/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.contacts.list;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.SearchSnippets;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.widget.AppCompatCheckBox;
import android.support.v7.widget.AppCompatImageButton;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.SelectionBoundsAdjuster;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.QuickContactBadge;
import android.widget.TextView;

import com.android.contacts.ContactPresenceIconUtil;
import com.android.contacts.ContactStatusUtil;
import com.android.contacts.R;
import com.android.contacts.compat.CompatUtils;
import com.android.contacts.compat.PhoneNumberUtilsCompat;
import com.android.contacts.format.TextHighlighter;
import com.android.contacts.util.ContactDisplayUtils;
import com.android.contacts.util.SearchUtil;
import com.android.contacts.util.ViewUtil;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * A custom view for an item in the contact list.
 * The view contains the contact's photo, a set of text views (for name, status, etc...) and
 * icons for presence and call.
 * The view uses no XML file for layout and all the measurements and layouts are done
 * in the onMeasure and onLayout methods.
 *
 * The layout puts the contact's photo on the right side of the view, the call icon (if present)
 * to the left of the photo, the text lines are aligned to the left and the presence icon (if
 * present) is set to the left of the status line.
 *
 * The layout also supports a header (used as a header of a group of contacts) that is above the
 * contact's data and a divider between contact view.
 */

public class ContactListItemView extends ViewGroup
        implements SelectionBoundsAdjuster {

    private static final String TAG = "ContactListItemView";

    // Style values for layout and appearance
    // The initialized values are defaults if none is provided through xml.
    private int mPreferredHeight = 0;
    private int mGapBetweenImageAndText = 0;
    private int mGapBetweenIndexerAndImage = 0;
    private int mGapBetweenLabelAndData = 0;
    private int mPresenceIconMargin = 4;
    private int mPresenceIconSize = 16;
    private int mTextIndent = 0;
    private int mTextOffsetTop;
    private int mAvatarOffsetTop;
    private int mNameTextViewTextSize;
    private int mHeaderWidth;
    private Drawable mActivatedBackgroundDrawable;
    private int mVideoCallIconSize = 32;
    private int mVideoCallIconMargin = 16;
    private int mGapFromScrollBar = 20;

    // Set in onLayout. Represent left and right position of the View on the screen.
    private int mLeftOffset;
    private int mRightOffset;

    /**
     * Used with {@link #mLabelView}, specifying the width ratio between label and data.
     */
    private int mLabelViewWidthWeight = 3;
    /**
     * Used with {@link #mDataView}, specifying the width ratio between label and data.
     */
    private int mDataViewWidthWeight = 5;

    protected static class HighlightSequence {
        private final int start;
        private final int end;

        HighlightSequence(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }

    private ArrayList<HighlightSequence> mNameHighlightSequence;
    private ArrayList<HighlightSequence> mNumberHighlightSequence;

    // Highlighting prefix for names.
    private String mHighlightedPrefix;

    /**
     * Used to notify listeners when a video call icon is clicked.
     */
    private PhoneNumberListAdapter.Listener mPhoneNumberListAdapterListener;

    /**
     * Indicates whether to show the "video call" icon, used to initiate a video call.
     */
    private boolean mShowVideoCallIcon = false;

    /**
     * Indicates whether the view should leave room for the "video call" icon.
     */
    private boolean mSupportVideoCallIcon = false;

    /**
     * Where to put contact photo. This affects the other Views' layout or look-and-feel.
     *
     * TODO: replace enum with int constants
     */
    public enum PhotoPosition {
        LEFT,
        RIGHT
    }

    static public final PhotoPosition getDefaultPhotoPosition(boolean opposite) {
        final Locale locale = Locale.getDefault();
        final int layoutDirection = TextUtils.getLayoutDirectionFromLocale(locale);
        switch (layoutDirection) {
            case View.LAYOUT_DIRECTION_RTL:
                return (opposite ? PhotoPosition.LEFT : PhotoPosition.RIGHT);
            case View.LAYOUT_DIRECTION_LTR:
            default:
                return (opposite ? PhotoPosition.RIGHT : PhotoPosition.LEFT);
        }
    }

    private PhotoPosition mPhotoPosition = getDefaultPhotoPosition(false /* normal/non opposite */);

    // Header layout data
    private View mHeaderView;
    private boolean mIsSectionHeaderEnabled;

    // The views inside the contact view
    private boolean mQuickContactEnabled = true;
    private QuickContactBadge mQuickContact;
    private ImageView mPhotoView;
    private TextView mNameTextView;
    private TextView mPhoneticNameTextView;
    private TextView mLabelView;
    private TextView mDataView;
    private TextView mSnippetView;
    private TextView mStatusView;
    private ImageView mPresenceIcon;
    private AppCompatCheckBox mCheckBox;
    private AppCompatImageButton mDeleteImageButton;
    private ImageView mVideoCallIcon;
    private ImageView mWorkProfileIcon;

    private ColorStateList mSecondaryTextColor;

    private int mDefaultPhotoViewSize = 0;
    /**
     * Can be effective even when {@link #mPhotoView} is null, as we want to have horizontal padding
     * to align other data in this View.
     */
    private int mPhotoViewWidth;
    /**
     * Can be effective even when {@link #mPhotoView} is null, as we want to have vertical padding.
     */
    private int mPhotoViewHeight;

    /**
     * Only effective when {@link #mPhotoView} is null.
     * When true all the Views on the right side of the photo should have horizontal padding on
     * those left assuming there is a photo.
     */
    private boolean mKeepHorizontalPaddingForPhotoView;
    /**
     * Only effective when {@link #mPhotoView} is null.
     */
    private boolean mKeepVerticalPaddingForPhotoView;

    /**
     * True when {@link #mPhotoViewWidth} and {@link #mPhotoViewHeight} are ready for being used.
     * False indicates those values should be updated before being used in position calculation.
     */
    private boolean mPhotoViewWidthAndHeightAreReady = false;

    private int mNameTextViewHeight;
    private int mNameTextViewTextColor = Color.BLACK;
    private int mPhoneticNameTextViewHeight;
    private int mLabelViewHeight;
    private int mDataViewHeight;
    private int mSnippetTextViewHeight;
    private int mStatusTextViewHeight;
    private int mCheckBoxHeight;
    private int mCheckBoxWidth;
    private int mDeleteImageButtonHeight;
    private int mDeleteImageButtonWidth;

    // Holds Math.max(mLabelTextViewHeight, mDataViewHeight), assuming Label and Data share the
    // same row.
    private int mLabelAndDataViewMaxHeight;

    // TODO: some TextView fields are using CharArrayBuffer while some are not. Determine which is
    // more efficient for each case or in general, and simplify the whole implementation.
    // Note: if we're sure MARQUEE will be used every time, there's no reason to use
    // CharArrayBuffer, since MARQUEE requires Span and thus we need to copy characters inside the
    // buffer to Spannable once, while CharArrayBuffer is for directly applying char array to
    // TextView without any modification.
    private final CharArrayBuffer mDataBuffer = new CharArrayBuffer(128);
    private final CharArrayBuffer mPhoneticNameBuffer = new CharArrayBuffer(128);

    private boolean mActivatedStateSupported;
    private boolean mAdjustSelectionBoundsEnabled = true;

    private Rect mBoundsWithoutHeader = new Rect();

    /** A helper used to highlight a prefix in a text field. */
    private final TextHighlighter mTextHighlighter;
    private CharSequence mUnknownNameText;
    private int mPosition;

    public ContactListItemView(Context context) {
        super(context);

        mTextHighlighter = new TextHighlighter(Typeface.BOLD);
        mNameHighlightSequence = new ArrayList<HighlightSequence>();
        mNumberHighlightSequence = new ArrayList<HighlightSequence>();
    }

    public ContactListItemView(Context context, AttributeSet attrs, boolean supportVideoCallIcon) {
        this(context, attrs);

        mSupportVideoCallIcon = supportVideoCallIcon;
    }

    public ContactListItemView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a;

        if (R.styleable.ContactListItemView != null) {
            // Read all style values
            a = getContext().obtainStyledAttributes(attrs, R.styleable.ContactListItemView);
            mPreferredHeight = a.getDimensionPixelSize(
                    R.styleable.ContactListItemView_list_item_height, mPreferredHeight);
            mActivatedBackgroundDrawable = a.getDrawable(
                    R.styleable.ContactListItemView_activated_background);

            mGapBetweenImageAndText = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_gap_between_image_and_text,
                    mGapBetweenImageAndText);
            mGapBetweenIndexerAndImage = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_gap_between_indexer_and_image,
                    mGapBetweenIndexerAndImage);
            mGapBetweenLabelAndData = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_gap_between_label_and_data,
                    mGapBetweenLabelAndData);
            mPresenceIconMargin = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_presence_icon_margin,
                    mPresenceIconMargin);
            mPresenceIconSize = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_presence_icon_size,
                    mPresenceIconSize);
            mDefaultPhotoViewSize = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_photo_size, mDefaultPhotoViewSize);
            mTextIndent = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_text_indent, mTextIndent);
            mTextOffsetTop = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_text_offset_top, mTextOffsetTop);
            mAvatarOffsetTop = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_avatar_offset_top, mAvatarOffsetTop);
            mDataViewWidthWeight = a.getInteger(
                    R.styleable.ContactListItemView_list_item_data_width_weight,
                    mDataViewWidthWeight);
            mLabelViewWidthWeight = a.getInteger(
                    R.styleable.ContactListItemView_list_item_label_width_weight,
                    mLabelViewWidthWeight);
            mNameTextViewTextColor = a.getColor(
                    R.styleable.ContactListItemView_list_item_name_text_color,
                    mNameTextViewTextColor);
            mNameTextViewTextSize = (int) a.getDimension(
                    R.styleable.ContactListItemView_list_item_name_text_size,
                    (int) getResources().getDimension(R.dimen.contact_browser_list_item_text_size));
            mVideoCallIconSize = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_video_call_icon_size,
                    mVideoCallIconSize);
            mVideoCallIconMargin = a.getDimensionPixelOffset(
                    R.styleable.ContactListItemView_list_item_video_call_icon_margin,
                    mVideoCallIconMargin);


            setPaddingRelative(
                    a.getDimensionPixelOffset(
                            R.styleable.ContactListItemView_list_item_padding_left, 0),
                    a.getDimensionPixelOffset(
                            R.styleable.ContactListItemView_list_item_padding_top, 0),
                    a.getDimensionPixelOffset(
                            R.styleable.ContactListItemView_list_item_padding_right, 0),
                    a.getDimensionPixelOffset(
                            R.styleable.ContactListItemView_list_item_padding_bottom, 0));

            a.recycle();
        }

        mTextHighlighter = new TextHighlighter(Typeface.BOLD);

        if (R.styleable.Theme != null) {
            a = getContext().obtainStyledAttributes(R.styleable.Theme);
            mSecondaryTextColor = a.getColorStateList(R.styleable.Theme_android_textColorSecondary);
            a.recycle();
        }

        mHeaderWidth =
                getResources().getDimensionPixelSize(R.dimen.contact_list_section_header_width);

        if (mActivatedBackgroundDrawable != null) {
            mActivatedBackgroundDrawable.setCallback(this);
        }

        mNameHighlightSequence = new ArrayList<HighlightSequence>();
        mNumberHighlightSequence = new ArrayList<HighlightSequence>();

        setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
    }

    public void setUnknownNameText(CharSequence unknownNameText) {
        mUnknownNameText = unknownNameText;
    }

    public void setQuickContactEnabled(boolean flag) {
        mQuickContactEnabled = flag;
    }

    /**
     * Sets whether the video calling icon is shown.  For the video calling icon to be shown,
     * {@link #mSupportVideoCallIcon} must be {@code true}.
     *
     * @param showVideoCallIcon {@code true} if the video calling icon is shown, {@code false}
     *      otherwise.
     * @param listener Listener to notify when the video calling icon is clicked.
     * @param position The position in the adapater of the video calling icon.
     */
    public void setShowVideoCallIcon(boolean showVideoCallIcon,
            PhoneNumberListAdapter.Listener listener, int position) {
        mShowVideoCallIcon = showVideoCallIcon;
        mPhoneNumberListAdapterListener = listener;
        mPosition = position;

        if (mShowVideoCallIcon) {
            if (mVideoCallIcon == null) {
                mVideoCallIcon = new ImageView(getContext());
                addView(mVideoCallIcon);
            }
            mVideoCallIcon.setContentDescription(getContext().getString(
                    R.string.description_search_video_call));
            mVideoCallIcon.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
            mVideoCallIcon.setScaleType(ScaleType.CENTER);
            mVideoCallIcon.setVisibility(View.VISIBLE);
            mVideoCallIcon.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // Inform the adapter that the video calling icon was clicked.
                    if (mPhoneNumberListAdapterListener != null) {
                        mPhoneNumberListAdapterListener.onVideoCallIconClicked(mPosition);
                    }
                }
            });
        } else {
            if (mVideoCallIcon != null) {
                mVideoCallIcon.setVisibility(View.GONE);
            }
        }
    }

    /**
     * Sets whether the view supports a video calling icon.  This is independent of whether the view
     * is actually showing an icon.  Support for the video calling icon ensures that the layout
     * leaves space for the video icon, should it be shown.
     *
     * @param supportVideoCallIcon {@code true} if the video call icon is supported, {@code false}
     *      otherwise.
     */
    public void setSupportVideoCallIcon(boolean supportVideoCallIcon) {
        mSupportVideoCallIcon = supportVideoCallIcon;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // We will match parent's width and wrap content vertically, but make sure
        // height is no less than listPreferredItemHeight.
        final int specWidth = resolveSize(0, widthMeasureSpec);
        final int preferredHeight = mPreferredHeight;

        mNameTextViewHeight = 0;
        mPhoneticNameTextViewHeight = 0;
        mLabelViewHeight = 0;
        mDataViewHeight = 0;
        mLabelAndDataViewMaxHeight = 0;
        mSnippetTextViewHeight = 0;
        mStatusTextViewHeight = 0;
        mCheckBoxWidth = 0;
        mCheckBoxHeight = 0;
        mDeleteImageButtonWidth = 0;
        mDeleteImageButtonHeight = 0;

        ensurePhotoViewSize();

        // Width each TextView is able to use.
        int effectiveWidth;
        // All the other Views will honor the photo, so available width for them may be shrunk.
        if (mPhotoViewWidth > 0 || mKeepHorizontalPaddingForPhotoView) {
            effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight()
                    - (mPhotoViewWidth + mGapBetweenImageAndText + mGapBetweenIndexerAndImage);
        } else {
            effectiveWidth = specWidth - getPaddingLeft() - getPaddingRight();
        }

        if (mIsSectionHeaderEnabled) {
            effectiveWidth -= mHeaderWidth;
        }

        if (mSupportVideoCallIcon) {
            effectiveWidth -= (mVideoCallIconSize + mVideoCallIconMargin);
        }

        // Go over all visible text views and measure actual width of each of them.
        // Also calculate their heights to get the total height for this entire view.

        if (isVisible(mCheckBox)) {
            mCheckBox.measure(
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mCheckBoxWidth = mCheckBox.getMeasuredWidth();
            mCheckBoxHeight = mCheckBox.getMeasuredHeight();
            effectiveWidth -= mCheckBoxWidth + mGapBetweenImageAndText;
        }

        if (isVisible(mDeleteImageButton)) {
            mDeleteImageButton.measure(
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mDeleteImageButtonWidth = mDeleteImageButton.getMeasuredWidth();
            mDeleteImageButtonHeight = mDeleteImageButton.getMeasuredHeight();
            effectiveWidth -= mDeleteImageButtonWidth + mGapBetweenImageAndText;
        }

        if (isVisible(mNameTextView)) {
            // Calculate width for name text - this parallels similar measurement in onLayout.
            int nameTextWidth = effectiveWidth;
            if (mPhotoPosition != PhotoPosition.LEFT) {
                nameTextWidth -= mTextIndent;
            }
            mNameTextView.measure(
                    MeasureSpec.makeMeasureSpec(nameTextWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mNameTextViewHeight = mNameTextView.getMeasuredHeight();
        }

        if (isVisible(mPhoneticNameTextView)) {
            mPhoneticNameTextView.measure(
                    MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mPhoneticNameTextViewHeight = mPhoneticNameTextView.getMeasuredHeight();
        }

        // If both data (phone number/email address) and label (type like "MOBILE") are quite long,
        // we should ellipsize both using appropriate ratio.
        final int dataWidth;
        final int labelWidth;
        if (isVisible(mDataView)) {
            if (isVisible(mLabelView)) {
                final int totalWidth = effectiveWidth - mGapBetweenLabelAndData;
                dataWidth = ((totalWidth * mDataViewWidthWeight)
                        / (mDataViewWidthWeight + mLabelViewWidthWeight));
                labelWidth = ((totalWidth * mLabelViewWidthWeight) /
                        (mDataViewWidthWeight + mLabelViewWidthWeight));
            } else {
                dataWidth = effectiveWidth;
                labelWidth = 0;
            }
        } else {
            dataWidth = 0;
            if (isVisible(mLabelView)) {
                labelWidth = effectiveWidth;
            } else {
                labelWidth = 0;
            }
        }

        if (isVisible(mDataView)) {
            mDataView.measure(MeasureSpec.makeMeasureSpec(dataWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mDataViewHeight = mDataView.getMeasuredHeight();
        }

        if (isVisible(mLabelView)) {
            mLabelView.measure(MeasureSpec.makeMeasureSpec(labelWidth, MeasureSpec.AT_MOST),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mLabelViewHeight = mLabelView.getMeasuredHeight();
        }
        mLabelAndDataViewMaxHeight = Math.max(mLabelViewHeight, mDataViewHeight);

        if (isVisible(mSnippetView)) {
            mSnippetView.measure(
                    MeasureSpec.makeMeasureSpec(effectiveWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mSnippetTextViewHeight = mSnippetView.getMeasuredHeight();
        }

        // Status view height is the biggest of the text view and the presence icon
        if (isVisible(mPresenceIcon)) {
            mPresenceIcon.measure(
                    MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(mPresenceIconSize, MeasureSpec.EXACTLY));
            mStatusTextViewHeight = mPresenceIcon.getMeasuredHeight();
        }

        if (mSupportVideoCallIcon && isVisible(mVideoCallIcon)) {
            mVideoCallIcon.measure(
                    MeasureSpec.makeMeasureSpec(mVideoCallIconSize, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(mVideoCallIconSize, MeasureSpec.EXACTLY));
        }

        if (isVisible(mWorkProfileIcon)) {
            mWorkProfileIcon.measure(
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mNameTextViewHeight =
                    Math.max(mNameTextViewHeight, mWorkProfileIcon.getMeasuredHeight());
        }

        if (isVisible(mStatusView)) {
            // Presence and status are in a same row, so status will be affected by icon size.
            final int statusWidth;
            if (isVisible(mPresenceIcon)) {
                statusWidth = (effectiveWidth - mPresenceIcon.getMeasuredWidth()
                        - mPresenceIconMargin);
            } else {
                statusWidth = effectiveWidth;
            }
            mStatusView.measure(MeasureSpec.makeMeasureSpec(statusWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            mStatusTextViewHeight =
                    Math.max(mStatusTextViewHeight, mStatusView.getMeasuredHeight());
        }

        // Calculate height including padding.
        int height = (mNameTextViewHeight + mPhoneticNameTextViewHeight +
                mLabelAndDataViewMaxHeight +
                mSnippetTextViewHeight + mStatusTextViewHeight);

        // Make sure the height is at least as high as the photo
        height = Math.max(height, mPhotoViewHeight + getPaddingBottom() + getPaddingTop());

        // Make sure height is at least the preferred height
        height = Math.max(height, preferredHeight);

        // Measure the header if it is visible.
        if (mHeaderView != null && mHeaderView.getVisibility() == VISIBLE) {
            mHeaderView.measure(
                    MeasureSpec.makeMeasureSpec(mHeaderWidth, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        }

        setMeasuredDimension(specWidth, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        final int height = bottom - top;
        final int width = right - left;

        // Determine the vertical bounds by laying out the header first.
        int topBound = 0;
        int bottomBound = height;
        int leftBound = getPaddingLeft();
        int rightBound = width - getPaddingRight();

        final boolean isLayoutRtl = ViewUtil.isViewLayoutRtl(this);

        // Put the section header on the left side of the contact view.
        if (mIsSectionHeaderEnabled) {
            if (mHeaderView != null) {
                int headerHeight = mHeaderView.getMeasuredHeight();
                int headerTopBound = (bottomBound + topBound - headerHeight) / 2 + mTextOffsetTop;

                mHeaderView.layout(
                        isLayoutRtl ? rightBound - mHeaderWidth : leftBound,
                        headerTopBound,
                        isLayoutRtl ? rightBound : leftBound + mHeaderWidth,
                        headerTopBound + headerHeight);
            }
            if (isLayoutRtl) {
                rightBound -= mHeaderWidth;
            } else {
                leftBound += mHeaderWidth;
            }
        }

        mBoundsWithoutHeader.set(left + leftBound, topBound, left + rightBound, bottomBound);
        mLeftOffset = left + leftBound;
        mRightOffset = left + rightBound;
        if (isLayoutRtl) {
            rightBound -= mGapBetweenIndexerAndImage;
        } else {
            leftBound += mGapBetweenIndexerAndImage;
        }

        if (mActivatedStateSupported && isActivated()) {
            mActivatedBackgroundDrawable.setBounds(mBoundsWithoutHeader);
        }

        if (isVisible(mCheckBox)) {
            final int photoTop = topBound + (bottomBound - topBound - mCheckBoxHeight) / 2;
            if (mPhotoPosition == PhotoPosition.LEFT) {
                mCheckBox.layout(rightBound - mGapFromScrollBar - mCheckBoxWidth,
                        photoTop,
                        rightBound - mGapFromScrollBar,
                        photoTop + mCheckBoxHeight);
            } else {
                mCheckBox.layout(leftBound + mGapFromScrollBar,
                        photoTop,
                        leftBound + mGapFromScrollBar + mCheckBoxWidth,
                        photoTop + mCheckBoxHeight);
            }
        }

        if (isVisible(mDeleteImageButton)) {
            final int photoTop = topBound + (bottomBound - topBound - mDeleteImageButtonHeight) / 2;
            final int mDeleteImageButtonSize = mDeleteImageButtonHeight > mDeleteImageButtonWidth
                    ? mDeleteImageButtonHeight : mDeleteImageButtonWidth;
            if (mPhotoPosition == PhotoPosition.LEFT) {
                mDeleteImageButton.layout(rightBound - mDeleteImageButtonSize,
                        photoTop,
                        rightBound,
                        photoTop + mDeleteImageButtonSize);
                rightBound -= mDeleteImageButtonSize;
            } else {
                mDeleteImageButton.layout(leftBound,
                        photoTop,
                        leftBound + mDeleteImageButtonSize,
                        photoTop + mDeleteImageButtonSize);
                leftBound += mDeleteImageButtonSize;
            }
        }

        final View photoView = mQuickContact != null ? mQuickContact : mPhotoView;
        if (mPhotoPosition == PhotoPosition.LEFT) {
            // Photo is the left most view. All the other Views should on the right of the photo.
            if (photoView != null) {
                // Center the photo vertically
                final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2
                        + mAvatarOffsetTop;
                photoView.layout(
                        leftBound,
                        photoTop,
                        leftBound + mPhotoViewWidth,
                        photoTop + mPhotoViewHeight);
                leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
            } else if (mKeepHorizontalPaddingForPhotoView) {
                // Draw nothing but keep the padding.
                leftBound += mPhotoViewWidth + mGapBetweenImageAndText;
            }
        } else {
            // Photo is the right most view. Right bound should be adjusted that way.
            if (photoView != null) {
                // Center the photo vertically
                final int photoTop = topBound + (bottomBound - topBound - mPhotoViewHeight) / 2
                        + mAvatarOffsetTop;
                photoView.layout(
                        rightBound - mPhotoViewWidth,
                        photoTop,
                        rightBound,
                        photoTop + mPhotoViewHeight);
                rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText);
            } else if (mKeepHorizontalPaddingForPhotoView) {
                // Draw nothing but keep the padding.
                rightBound -= (mPhotoViewWidth + mGapBetweenImageAndText);
            }

            // Add indent between left-most padding and texts.
            leftBound += mTextIndent;
        }

        if (mSupportVideoCallIcon) {
            // Place the video call button at the end of the list (e.g. take into account RTL mode).
            if (isVisible(mVideoCallIcon)) {
                // Center the video icon vertically
                final int videoIconTop = topBound +
                        (bottomBound - topBound - mVideoCallIconSize) / 2;

                if (!isLayoutRtl) {
                    // When photo is on left, video icon is placed on the right edge.
                    mVideoCallIcon.layout(rightBound - mVideoCallIconSize,
                            videoIconTop,
                            rightBound,
                            videoIconTop + mVideoCallIconSize);
                } else {
                    // When photo is on right, video icon is placed on the left edge.
                    mVideoCallIcon.layout(leftBound,
                            videoIconTop,
                            leftBound + mVideoCallIconSize,
                            videoIconTop + mVideoCallIconSize);
                }
            }

            if (mPhotoPosition == PhotoPosition.LEFT) {
                rightBound -= (mVideoCallIconSize + mVideoCallIconMargin);
            } else {
                leftBound += mVideoCallIconSize + mVideoCallIconMargin;
            }
        }


        // Center text vertically, then apply the top offset.
        final int totalTextHeight = mNameTextViewHeight + mPhoneticNameTextViewHeight +
                mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight;
        int textTopBound = (bottomBound + topBound - totalTextHeight) / 2 + mTextOffsetTop;

        // Work Profile icon align top
        int workProfileIconWidth = 0;
        if (isVisible(mWorkProfileIcon)) {
            workProfileIconWidth = mWorkProfileIcon.getMeasuredWidth();
            final int distanceFromEnd = mCheckBoxWidth > 0
                    ? mCheckBoxWidth + mGapBetweenImageAndText : 0;
            if (mPhotoPosition == PhotoPosition.LEFT) {
                // When photo is on left, label is placed on the right edge of the list item.
                mWorkProfileIcon.layout(rightBound - workProfileIconWidth - distanceFromEnd,
                        textTopBound,
                        rightBound - distanceFromEnd,
                        textTopBound + mNameTextViewHeight);
            } else {
                // When photo is on right, label is placed on the left of data view.
                mWorkProfileIcon.layout(leftBound + distanceFromEnd,
                        textTopBound,
                        leftBound + workProfileIconWidth + distanceFromEnd,
                        textTopBound + mNameTextViewHeight);
            }
        }

        // Layout all text view and presence icon
        // Put name TextView first
        if (isVisible(mNameTextView)) {
            final int distanceFromEnd = workProfileIconWidth
                    + (mCheckBoxWidth > 0 ? mCheckBoxWidth + mGapBetweenImageAndText : 0);
            if (mPhotoPosition == PhotoPosition.LEFT) {
                mNameTextView.layout(leftBound,
                        textTopBound,
                        rightBound - distanceFromEnd,
                        textTopBound + mNameTextViewHeight);
            } else {
                mNameTextView.layout(leftBound + distanceFromEnd,
                        textTopBound,
                        rightBound,
                        textTopBound + mNameTextViewHeight);
            }
        }

        if (isVisible(mNameTextView) || isVisible(mWorkProfileIcon)) {
            textTopBound += mNameTextViewHeight;
        }

        // Presence and status
        if (isLayoutRtl) {
            int statusRightBound = rightBound;
            if (isVisible(mPresenceIcon)) {
                int iconWidth = mPresenceIcon.getMeasuredWidth();
                mPresenceIcon.layout(
                        rightBound - iconWidth,
                        textTopBound,
                        rightBound,
                        textTopBound + mStatusTextViewHeight);
                statusRightBound -= (iconWidth + mPresenceIconMargin);
            }

            if (isVisible(mStatusView)) {
                mStatusView.layout(leftBound,
                        textTopBound,
                        statusRightBound,
                        textTopBound + mStatusTextViewHeight);
            }
        } else {
            int statusLeftBound = leftBound;
            if (isVisible(mPresenceIcon)) {
                int iconWidth = mPresenceIcon.getMeasuredWidth();
                mPresenceIcon.layout(
                        leftBound,
                        textTopBound,
                        leftBound + iconWidth,
                        textTopBound + mStatusTextViewHeight);
                statusLeftBound += (iconWidth + mPresenceIconMargin);
            }

            if (isVisible(mStatusView)) {
                mStatusView.layout(statusLeftBound,
                        textTopBound,
                        rightBound,
                        textTopBound + mStatusTextViewHeight);
            }
        }

        if (isVisible(mStatusView) || isVisible(mPresenceIcon)) {
            textTopBound += mStatusTextViewHeight;
        }

        // Rest of text views
        int dataLeftBound = leftBound;
        if (isVisible(mPhoneticNameTextView)) {
            mPhoneticNameTextView.layout(leftBound,
                    textTopBound,
                    rightBound,
                    textTopBound + mPhoneticNameTextViewHeight);
            textTopBound += mPhoneticNameTextViewHeight;
        }

        // Label and Data align bottom.
        if (isVisible(mLabelView)) {
            if (!isLayoutRtl) {
                mLabelView.layout(dataLeftBound,
                        textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight,
                        rightBound,
                        textTopBound + mLabelAndDataViewMaxHeight);
                dataLeftBound += mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData;
            } else {
                dataLeftBound = leftBound + mLabelView.getMeasuredWidth();
                mLabelView.layout(rightBound - mLabelView.getMeasuredWidth(),
                        textTopBound + mLabelAndDataViewMaxHeight - mLabelViewHeight,
                        rightBound,
                        textTopBound + mLabelAndDataViewMaxHeight);
                rightBound -= (mLabelView.getMeasuredWidth() + mGapBetweenLabelAndData);
            }
        }

        if (isVisible(mDataView)) {
            if (!isLayoutRtl) {
                mDataView.layout(dataLeftBound,
                        textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight,
                        rightBound,
                        textTopBound + mLabelAndDataViewMaxHeight);
            } else {
                mDataView.layout(rightBound - mDataView.getMeasuredWidth(),
                        textTopBound + mLabelAndDataViewMaxHeight - mDataViewHeight,
                        rightBound,
                        textTopBound + mLabelAndDataViewMaxHeight);
            }
        }
        if (isVisible(mLabelView) || isVisible(mDataView)) {
            textTopBound += mLabelAndDataViewMaxHeight;
        }

        if (isVisible(mSnippetView)) {
            mSnippetView.layout(leftBound,
                    textTopBound,
                    rightBound,
                    textTopBound + mSnippetTextViewHeight);
        }
    }

    @Override
    public void adjustListItemSelectionBounds(Rect bounds) {
        if (mAdjustSelectionBoundsEnabled) {
            bounds.top += mBoundsWithoutHeader.top;
            bounds.bottom = bounds.top + mBoundsWithoutHeader.height();
            bounds.left = mBoundsWithoutHeader.left;
            bounds.right = mBoundsWithoutHeader.right;
        }
    }

    protected boolean isVisible(View view) {
        return view != null && view.getVisibility() == View.VISIBLE;
    }

    /**
     * Extracts width and height from the style
     */
    private void ensurePhotoViewSize() {
        if (!mPhotoViewWidthAndHeightAreReady) {
            mPhotoViewWidth = mPhotoViewHeight = getDefaultPhotoViewSize();
            if (!mQuickContactEnabled && mPhotoView == null) {
                if (!mKeepHorizontalPaddingForPhotoView) {
                    mPhotoViewWidth = 0;
                }
                if (!mKeepVerticalPaddingForPhotoView) {
                    mPhotoViewHeight = 0;
                }
            }

            mPhotoViewWidthAndHeightAreReady = true;
        }
    }

    protected int getDefaultPhotoViewSize() {
        return mDefaultPhotoViewSize;
    }

    /**
     * Gets a LayoutParam that corresponds to the default photo size.
     *
     * @return A new LayoutParam.
     */
    private LayoutParams getDefaultPhotoLayoutParams() {
        LayoutParams params = generateDefaultLayoutParams();
        params.width = getDefaultPhotoViewSize();
        params.height = params.width;
        return params;
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (mActivatedStateSupported) {
            mActivatedBackgroundDrawable.setState(getDrawableState());
        }
    }

    @Override
    protected boolean verifyDrawable(Drawable who) {
        return who == mActivatedBackgroundDrawable || super.verifyDrawable(who);
    }

    @Override
    public void jumpDrawablesToCurrentState() {
        super.jumpDrawablesToCurrentState();
        if (mActivatedStateSupported) {
            mActivatedBackgroundDrawable.jumpToCurrentState();
        }
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        if (mActivatedStateSupported && isActivated()) {
            mActivatedBackgroundDrawable.draw(canvas);
        }

        super.dispatchDraw(canvas);
    }

    /**
     * Sets section header or makes it invisible if the title is null.
     */
    public void setSectionHeader(String title) {
        if (title != null) {
            // Empty section title is the favorites so show the star here.
            if (title.isEmpty()) {
                if (mHeaderView == null) {
                    addStarImageHeader();
                } else if (mHeaderView instanceof TextView) {
                    removeView(mHeaderView);
                    addStarImageHeader();
                } else {
                    mHeaderView.setVisibility(View.VISIBLE);
                }
            } else {
                if (mHeaderView == null) {
                    addTextHeader(title);
                } else if (mHeaderView instanceof ImageView) {
                    removeView(mHeaderView);
                    addTextHeader(title);
                } else {
                    updateHeaderText((TextView) mHeaderView, title);
                }
            }
        } else if (mHeaderView != null) {
            mHeaderView.setVisibility(View.GONE);
        }
    }

    private void addTextHeader(String title) {
        mHeaderView = new TextView(getContext());
        final TextView headerTextView = (TextView) mHeaderView;
        headerTextView.setTextAppearance(getContext(), R.style.SectionHeaderStyle);
        headerTextView.setGravity(Gravity.CENTER_HORIZONTAL);
        updateHeaderText(headerTextView, title);
        addView(headerTextView);
    }

    private void updateHeaderText(TextView headerTextView, String title) {
        setMarqueeText(headerTextView, title);
        headerTextView.setAllCaps(true);
        if (ContactsSectionIndexer.BLANK_HEADER_STRING.equals(title)) {
            headerTextView.setContentDescription(
                    getContext().getString(R.string.description_no_name_header));
        } else {
            headerTextView.setContentDescription(title);
        }
        headerTextView.setVisibility(View.VISIBLE);
    }

    private void addStarImageHeader() {
        mHeaderView = new ImageView(getContext());
        final ImageView headerImageView = (ImageView) mHeaderView;
        headerImageView.setImageDrawable(
                getResources().getDrawable(R.drawable.quantum_ic_star_vd_theme_24,
                        getContext().getTheme()));
        headerImageView.setImageTintList(ColorStateList.valueOf(getResources()
                .getColor(R.color.material_star_pink)));
        headerImageView.setContentDescription(
                getContext().getString(R.string.contactsFavoritesLabel));
        headerImageView.setVisibility(View.VISIBLE);
        addView(headerImageView);
    }

    public void setIsSectionHeaderEnabled(boolean isSectionHeaderEnabled) {
        mIsSectionHeaderEnabled = isSectionHeaderEnabled;
    }

    /**
     * Returns the quick contact badge, creating it if necessary.
     */
    public QuickContactBadge getQuickContact() {
        if (!mQuickContactEnabled) {
            throw new IllegalStateException("QuickContact is disabled for this view");
        }
        if (mQuickContact == null) {
            mQuickContact = new QuickContactBadge(getContext());
            if (CompatUtils.isLollipopCompatible()) {
                mQuickContact.setOverlay(null);
            }
            mQuickContact.setLayoutParams(getDefaultPhotoLayoutParams());
            if (mNameTextView != null) {
                mQuickContact.setContentDescription(getContext().getString(
                        R.string.description_quick_contact_for, mNameTextView.getText()));
            }

            addView(mQuickContact);
            mPhotoViewWidthAndHeightAreReady = false;
        }
        return mQuickContact;
    }

    /**
     * Returns the photo view, creating it if necessary.
     */
    public ImageView getPhotoView() {
        if (mPhotoView == null) {
            mPhotoView = new ImageView(getContext());
            mPhotoView.setLayoutParams(getDefaultPhotoLayoutParams());
            // Quick contact style used above will set a background - remove it
            mPhotoView.setBackground(null);
            addView(mPhotoView);
            mPhotoViewWidthAndHeightAreReady = false;
        }
        return mPhotoView;
    }

    /**
     * Removes the photo view.
     */
    public void removePhotoView() {
        removePhotoView(false, true);
    }

    /**
     * Removes the photo view.
     *
     * @param keepHorizontalPadding True means data on the right side will have
     *            padding on left, pretending there is still a photo view.
     * @param keepVerticalPadding True means the View will have some height
     *            enough for accommodating a photo view.
     */
    public void removePhotoView(boolean keepHorizontalPadding, boolean keepVerticalPadding) {
        mPhotoViewWidthAndHeightAreReady = false;
        mKeepHorizontalPaddingForPhotoView = keepHorizontalPadding;
        mKeepVerticalPaddingForPhotoView = keepVerticalPadding;
        if (mPhotoView != null) {
            removeView(mPhotoView);
            mPhotoView = null;
        }
        if (mQuickContact != null) {
            removeView(mQuickContact);
            mQuickContact = null;
        }
    }

    /**
     * Sets a word prefix that will be highlighted if encountered in fields like
     * name and search snippet. This will disable the mask highlighting for names.
     * <p>
     * NOTE: must be all upper-case
     */
    public void setHighlightedPrefix(String upperCasePrefix) {
        mHighlightedPrefix = upperCasePrefix;
    }

    /**
     * Clears previously set highlight sequences for the view.
     */
    public void clearHighlightSequences() {
        mNameHighlightSequence.clear();
        mNumberHighlightSequence.clear();
        mHighlightedPrefix = null;
    }

    /**
     * Adds a highlight sequence to the name highlighter.
     * @param start The start position of the highlight sequence.
     * @param end The end position of the highlight sequence.
     */
    public void addNameHighlightSequence(int start, int end) {
        mNameHighlightSequence.add(new HighlightSequence(start, end));
    }

    /**
     * Adds a highlight sequence to the number highlighter.
     * @param start The start position of the highlight sequence.
     * @param end The end position of the highlight sequence.
     */
    public void addNumberHighlightSequence(int start, int end) {
        mNumberHighlightSequence.add(new HighlightSequence(start, end));
    }

    /**
     * Returns the text view for the contact name, creating it if necessary.
     */
    public TextView getNameTextView() {
        if (mNameTextView == null) {
            mNameTextView = new TextView(getContext());
            mNameTextView.setSingleLine(true);
            mNameTextView.setEllipsize(getTextEllipsis());
            mNameTextView.setTextColor(ResourcesCompat.getColorStateList(getResources(),
                    R.color.contact_list_name_text_color, getContext().getTheme()));
            mNameTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mNameTextViewTextSize);
            // Manually call setActivated() since this view may be added after the first
            // setActivated() call toward this whole item view.
            mNameTextView.setActivated(isActivated());
            mNameTextView.setGravity(Gravity.CENTER_VERTICAL);
            mNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
            mNameTextView.setId(R.id.cliv_name_textview);
            if (CompatUtils.isLollipopCompatible()) {
                mNameTextView.setElegantTextHeight(false);
            }
            addView(mNameTextView);
        }
        return mNameTextView;
    }

    /**
     * Adds or updates a text view for the phonetic name.
     */
    public void setPhoneticName(char[] text, int size) {
        if (text == null || size == 0) {
            if (mPhoneticNameTextView != null) {
                mPhoneticNameTextView.setVisibility(View.GONE);
            }
        } else {
            getPhoneticNameTextView();
            setMarqueeText(mPhoneticNameTextView, text, size);
            mPhoneticNameTextView.setVisibility(VISIBLE);
        }
    }

    /**
     * Returns the text view for the phonetic name, creating it if necessary.
     */
    public TextView getPhoneticNameTextView() {
        if (mPhoneticNameTextView == null) {
            mPhoneticNameTextView = new TextView(getContext());
            mPhoneticNameTextView.setSingleLine(true);
            mPhoneticNameTextView.setEllipsize(getTextEllipsis());
            mPhoneticNameTextView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small);
            mPhoneticNameTextView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
            mPhoneticNameTextView.setTypeface(mPhoneticNameTextView.getTypeface(), Typeface.BOLD);
            mPhoneticNameTextView.setActivated(isActivated());
            mPhoneticNameTextView.setId(R.id.cliv_phoneticname_textview);
            addView(mPhoneticNameTextView);
        }
        return mPhoneticNameTextView;
    }

    /**
     * Adds or updates a text view for the data label.
     */
    public void setLabel(CharSequence text) {
        if (TextUtils.isEmpty(text)) {
            if (mLabelView != null) {
                mLabelView.setVisibility(View.GONE);
            }
        } else {
            getLabelView();
            setMarqueeText(mLabelView, text);
            mLabelView.setVisibility(VISIBLE);
        }
    }

    /**
     * Returns the text view for the data label, creating it if necessary.
     */
    public TextView getLabelView() {
        if (mLabelView == null) {
            mLabelView = new TextView(getContext());
            mLabelView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                    LayoutParams.WRAP_CONTENT));

            mLabelView.setSingleLine(true);
            mLabelView.setEllipsize(getTextEllipsis());
            mLabelView.setTextAppearance(getContext(), R.style.TextAppearanceSmall);
            if (mPhotoPosition == PhotoPosition.LEFT) {
                mLabelView.setAllCaps(true);
            } else {
                mLabelView.setTypeface(mLabelView.getTypeface(), Typeface.BOLD);
            }
            mLabelView.setActivated(isActivated());
            mLabelView.setId(R.id.cliv_label_textview);
            addView(mLabelView);
        }
        return mLabelView;
    }

    /**
     * Adds or updates a text view for the data element.
     */
    public void setData(char[] text, int size) {
        if (text == null || size == 0) {
            if (mDataView != null) {
                mDataView.setVisibility(View.GONE);
            }
        } else {
            getDataView();
            setMarqueeText(mDataView, text, size);
            mDataView.setVisibility(VISIBLE);
        }
    }

    /**
     * Sets phone number for a list item. This takes care of number highlighting if the highlight
     * mask exists.
     */
    public void setPhoneNumber(String text, String countryIso) {
        if (text == null) {
            if (mDataView != null) {
                mDataView.setVisibility(View.GONE);
            }
        } else {
            getDataView();

            // TODO: Format number using PhoneNumberUtils.formatNumber before assigning it to
            // mDataView. Make sure that determination of the highlight sequences are done only
            // after number formatting.

            // Sets phone number texts for display after highlighting it, if applicable.
            // CharSequence textToSet = text;
            final SpannableString textToSet = new SpannableString(text);

            if (mNumberHighlightSequence.size() != 0) {
                final HighlightSequence highlightSequence = mNumberHighlightSequence.get(0);
                mTextHighlighter.applyMaskingHighlight(textToSet, highlightSequence.start,
                        highlightSequence.end);
            }

            setMarqueeText(mDataView, textToSet);
            mDataView.setVisibility(VISIBLE);

            // We have a phone number as "mDataView" so make it always LTR and VIEW_START
            mDataView.setTextDirection(View.TEXT_DIRECTION_LTR);
            mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
        }
    }

    private void setMarqueeText(TextView textView, char[] text, int size) {
        if (getTextEllipsis() == TruncateAt.MARQUEE) {
            setMarqueeText(textView, new String(text, 0, size));
        } else {
            textView.setText(text, 0, size);
        }
    }

    private void setMarqueeText(TextView textView, CharSequence text) {
        if (getTextEllipsis() == TruncateAt.MARQUEE) {
            // To show MARQUEE correctly (with END effect during non-active state), we need
            // to build Spanned with MARQUEE in addition to TextView's ellipsize setting.
            final SpannableString spannable = new SpannableString(text);
            spannable.setSpan(TruncateAt.MARQUEE, 0, spannable.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(spannable);
        } else {
            textView.setText(text);
        }
    }

    /**
     * Returns the {@link AppCompatCheckBox} view, creating it if necessary.
     */
    public AppCompatCheckBox getCheckBox() {
        if (mCheckBox == null) {
            mCheckBox = new AppCompatCheckBox(getContext());
            // Make non-focusable, so the rest of the ContactListItemView can be clicked.
            mCheckBox.setFocusable(false);
            addView(mCheckBox);
        }
        return mCheckBox;
    }

    /**
     * Returns the {@link AppCompatImageButton} delete button, creating it if necessary.
     */
    public AppCompatImageButton getDeleteImageButton(
            final MultiSelectEntryContactListAdapter.DeleteContactListener listener,
            final int position) {
        if (mDeleteImageButton == null) {
            mDeleteImageButton = new AppCompatImageButton(getContext());
            mDeleteImageButton.setImageResource(R.drawable.quantum_ic_cancel_vd_theme_24);
            mDeleteImageButton.setScaleType(ScaleType.CENTER);
            mDeleteImageButton.setBackgroundColor(Color.TRANSPARENT);
            mDeleteImageButton.setContentDescription(
                    getResources().getString(R.string.description_delete_contact));
            if (CompatUtils. isLollipopCompatible()) {
                final TypedValue typedValue = new TypedValue();
                getContext().getTheme().resolveAttribute(
                        android.R.attr.selectableItemBackgroundBorderless, typedValue, true);
                mDeleteImageButton.setBackgroundResource(typedValue.resourceId);
            }
            addView(mDeleteImageButton);
        }
        // Reset onClickListener because after reloading the view, position might be changed.
        mDeleteImageButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Inform the adapter that delete icon was clicked.
                if (listener != null) {
                    listener.onContactDeleteClicked(position);
                }
            }
        });
        return mDeleteImageButton;
    }

    /**
     * Returns the text view for the data text, creating it if necessary.
     */
    public TextView getDataView() {
        if (mDataView == null) {
            mDataView = new TextView(getContext());
            mDataView.setSingleLine(true);
            mDataView.setEllipsize(getTextEllipsis());
            mDataView.setTextAppearance(getContext(), R.style.TextAppearanceSmall);
            mDataView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
            mDataView.setActivated(isActivated());
            mDataView.setId(R.id.cliv_data_view);
            if (CompatUtils.isLollipopCompatible()) {
                mDataView.setElegantTextHeight(false);
            }
            addView(mDataView);
        }
        return mDataView;
    }

    /**
     * Adds or updates a text view for the search snippet.
     */
    public void setSnippet(String text) {
        if (TextUtils.isEmpty(text)) {
            if (mSnippetView != null) {
                mSnippetView.setVisibility(View.GONE);
            }
        } else {
            mTextHighlighter.setPrefixText(getSnippetView(), text, mHighlightedPrefix);
            mSnippetView.setVisibility(VISIBLE);
            if (ContactDisplayUtils.isPossiblePhoneNumber(text)) {
                // Give the text-to-speech engine a hint that it's a phone number
                mSnippetView.setContentDescription(
                        PhoneNumberUtilsCompat.createTtsSpannable(text));
            } else {
                mSnippetView.setContentDescription(null);
            }
        }
    }

    /**
     * Returns the text view for the search snippet, creating it if necessary.
     */
    public TextView getSnippetView() {
        if (mSnippetView == null) {
            mSnippetView = new TextView(getContext());
            mSnippetView.setSingleLine(true);
            mSnippetView.setEllipsize(getTextEllipsis());
            mSnippetView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small);
            mSnippetView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
            mSnippetView.setActivated(isActivated());
            addView(mSnippetView);
        }
        return mSnippetView;
    }

    /**
     * Returns the text view for the status, creating it if necessary.
     */
    public TextView getStatusView() {
        if (mStatusView == null) {
            mStatusView = new TextView(getContext());
            mStatusView.setSingleLine(true);
            mStatusView.setEllipsize(getTextEllipsis());
            mStatusView.setTextAppearance(getContext(), android.R.style.TextAppearance_Small);
            mStatusView.setTextColor(mSecondaryTextColor);
            mStatusView.setActivated(isActivated());
            mStatusView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
            addView(mStatusView);
        }
        return mStatusView;
    }

    /**
     * Adds or updates a text view for the status.
     */
    public void setStatus(CharSequence text) {
        if (TextUtils.isEmpty(text)) {
            if (mStatusView != null) {
                mStatusView.setVisibility(View.GONE);
            }
        } else {
            getStatusView();
            setMarqueeText(mStatusView, text);
            mStatusView.setVisibility(VISIBLE);
        }
    }

    /**
     * Adds or updates the presence icon view.
     */
    public void setPresence(Drawable icon) {
        if (icon != null) {
            if (mPresenceIcon == null) {
                mPresenceIcon = new ImageView(getContext());
                addView(mPresenceIcon);
            }
            mPresenceIcon.setImageDrawable(icon);
            mPresenceIcon.setScaleType(ScaleType.CENTER);
            mPresenceIcon.setVisibility(View.VISIBLE);
        } else {
            if (mPresenceIcon != null) {
                mPresenceIcon.setVisibility(View.GONE);
            }
        }
    }

    /**
     * Set to display work profile icon or not
     *
     * @param enabled set to display work profile icon or not
     */
    public void setWorkProfileIconEnabled(boolean enabled) {
        if (mWorkProfileIcon != null) {
            mWorkProfileIcon.setVisibility(enabled ? View.VISIBLE : View.GONE);
        } else if (enabled) {
            mWorkProfileIcon = new ImageView(getContext());
            addView(mWorkProfileIcon);
            mWorkProfileIcon.setImageResource(R.drawable.ic_work_profile);
            mWorkProfileIcon.setScaleType(ScaleType.CENTER_INSIDE);
            mWorkProfileIcon.setVisibility(View.VISIBLE);
        }
    }

    private TruncateAt getTextEllipsis() {
        return TruncateAt.MARQUEE;
    }

    public void showDisplayName(Cursor cursor, int nameColumnIndex, int displayOrder) {
        CharSequence name = cursor.getString(nameColumnIndex);
        setDisplayName(name);

        // Since the quick contact content description is derived from the display name and there is
        // no guarantee that when the quick contact is initialized the display name is already set,
        // do it here too.
        if (mQuickContact != null) {
            mQuickContact.setContentDescription(getContext().getString(
                    R.string.description_quick_contact_for, mNameTextView.getText()));
        }
    }

    public void setDisplayName(CharSequence name, boolean highlight) {
        if (!TextUtils.isEmpty(name) && highlight) {
            clearHighlightSequences();
            addNameHighlightSequence(0, name.length());
        }
        setDisplayName(name);
    }

    public void setDisplayName(CharSequence name) {
        if (!TextUtils.isEmpty(name)) {
            // Chooses the available highlighting method for highlighting.
            if (mHighlightedPrefix != null) {
                name = mTextHighlighter.applyPrefixHighlight(name, mHighlightedPrefix);
            } else if (mNameHighlightSequence.size() != 0) {
                final SpannableString spannableName = new SpannableString(name);
                for (HighlightSequence highlightSequence : mNameHighlightSequence) {
                    mTextHighlighter.applyMaskingHighlight(spannableName, highlightSequence.start,
                            highlightSequence.end);
                }
                name = spannableName;
            }
        } else {
            name = mUnknownNameText;
        }
        setMarqueeText(getNameTextView(), name);

        if (ContactDisplayUtils.isPossiblePhoneNumber(name)) {
            // Give the text-to-speech engine a hint that it's a phone number
            mNameTextView.setTextDirection(View.TEXT_DIRECTION_LTR);
            mNameTextView.setContentDescription(
                    PhoneNumberUtilsCompat.createTtsSpannable(name.toString()));
        } else {
            // Remove span tags of highlighting for talkback to avoid reading highlighting and rest
            // of the name into two separate parts.
            mNameTextView.setContentDescription(name.toString());
        }
    }

    public void hideCheckBox() {
        if (mCheckBox != null) {
            removeView(mCheckBox);
            mCheckBox = null;
        }
    }

    public void hideDeleteImageButton() {
        if (mDeleteImageButton != null) {
            removeView(mDeleteImageButton);
            mDeleteImageButton = null;
        }
    }

    public void hideDisplayName() {
        if (mNameTextView != null) {
            removeView(mNameTextView);
            mNameTextView = null;
        }
    }

    public void showPhoneticName(Cursor cursor, int phoneticNameColumnIndex) {
        cursor.copyStringToBuffer(phoneticNameColumnIndex, mPhoneticNameBuffer);
        int phoneticNameSize = mPhoneticNameBuffer.sizeCopied;
        if (phoneticNameSize != 0) {
            setPhoneticName(mPhoneticNameBuffer.data, phoneticNameSize);
        } else {
            setPhoneticName(null, 0);
        }
    }

    public void hidePhoneticName() {
        if (mPhoneticNameTextView != null) {
            removeView(mPhoneticNameTextView);
            mPhoneticNameTextView = null;
        }
    }

    /**
     * Sets the proper icon (star or presence or nothing) and/or status message.
     */
    public void showPresenceAndStatusMessage(Cursor cursor, int presenceColumnIndex,
            int contactStatusColumnIndex) {
        Drawable icon = null;
        int presence = 0;
        if (!cursor.isNull(presenceColumnIndex)) {
            presence = cursor.getInt(presenceColumnIndex);
            icon = ContactPresenceIconUtil.getPresenceIcon(getContext(), presence);
        }
        setPresence(icon);

        String statusMessage = null;
        if (contactStatusColumnIndex != 0 && !cursor.isNull(contactStatusColumnIndex)) {
            statusMessage = cursor.getString(contactStatusColumnIndex);
        }
        // If there is no status message from the contact, but there was a presence value, then use
        // the default status message string
        if (statusMessage == null && presence != 0) {
            statusMessage = ContactStatusUtil.getStatusString(getContext(), presence);
        }
        setStatus(statusMessage);
    }

    /**
     * Shows search snippet for email and phone number matches.
     */
    public void showSnippet(Cursor cursor, String query, int snippetColumn) {
        // TODO: this does not properly handle phone numbers with control characters
        // For example if the phone number is 444-5555, the search query 4445 will match the
        // number since we normalize it before querying CP2 but the snippet will fail since
        // the portion to be highlighted is 444-5 not 4445.
        final String snippet = cursor.getString(snippetColumn);
        if (snippet == null) {
            setSnippet(null);
            return;
        }
        final String displayName = cursor.getColumnIndex(Contacts.DISPLAY_NAME) >= 0
                ? cursor.getString(cursor.getColumnIndex(Contacts.DISPLAY_NAME)) : null;
        if (snippet.equals(displayName)) {
            // If the snippet exactly matches the display name (i.e. the phone number or email
            // address is being used as the display name) then no snippet is necessary
            setSnippet(null);
            return;
        }
        // Show the snippet with the part of the query that matched it
        setSnippet(updateSnippet(snippet, query, displayName));
    }

    /**
     * Shows search snippet.
     */
    public void showSnippet(Cursor cursor, int summarySnippetColumnIndex) {
        if (cursor.getColumnCount() <= summarySnippetColumnIndex
            || !SearchSnippets.SNIPPET.equals(cursor.getColumnName(summarySnippetColumnIndex))) {
            setSnippet(null);
            return;
        }

        String snippet = cursor.getString(summarySnippetColumnIndex);

        // Do client side snippeting if provider didn't do it
        final Bundle extras = cursor.getExtras();
        if (extras.getBoolean(ContactsContract.DEFERRED_SNIPPETING)) {

            final String query = extras.getString(ContactsContract.DEFERRED_SNIPPETING_QUERY);

            String displayName = null;
            int displayNameIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            if (displayNameIndex >= 0) {
                displayName = cursor.getString(displayNameIndex);
            }

            snippet = updateSnippet(snippet, query, displayName);

        } else {
            if (snippet != null) {
                int from = 0;
                int to = snippet.length();
                int start = snippet.indexOf(DefaultContactListAdapter.SNIPPET_START_MATCH);
                if (start == -1) {
                    snippet = null;
                } else {
                    int firstNl = snippet.lastIndexOf('\n', start);
                    if (firstNl != -1) {
                        from = firstNl + 1;
                    }
                    int end = snippet.lastIndexOf(DefaultContactListAdapter.SNIPPET_END_MATCH);
                    if (end != -1) {
                        int lastNl = snippet.indexOf('\n', end);
                        if (lastNl != -1) {
                            to = lastNl;
                        }
                    }

                    StringBuilder sb = new StringBuilder();
                    for (int i = from; i < to; i++) {
                        char c = snippet.charAt(i);
                        if (c != DefaultContactListAdapter.SNIPPET_START_MATCH &&
                                c != DefaultContactListAdapter.SNIPPET_END_MATCH) {
                            sb.append(c);
                        }
                    }
                    snippet = sb.toString();
                }
            }
        }

        setSnippet(snippet);
    }

    /**
     * Used for deferred snippets from the database. The contents come back as large strings which
     * need to be extracted for display.
     *
     * @param snippet The snippet from the database.
     * @param query The search query substring.
     * @param displayName The contact display name.
     * @return The proper snippet to display.
     */
    private String updateSnippet(String snippet, String query, String displayName) {

        if (TextUtils.isEmpty(snippet) || TextUtils.isEmpty(query)) {
            return null;
        }
        query = SearchUtil.cleanStartAndEndOfSearchQuery(query.toLowerCase());

        // If the display name already contains the query term, return empty - snippets should
        // not be needed in that case.
        if (!TextUtils.isEmpty(displayName)) {
            final String lowerDisplayName = displayName.toLowerCase();
            final List<String> nameTokens = split(lowerDisplayName);
            for (String nameToken : nameTokens) {
                if (nameToken.startsWith(query)) {
                    return null;
                }
            }
        }

        // The snippet may contain multiple data lines.
        // Show the first line that matches the query.
        final SearchUtil.MatchedLine matched = SearchUtil.findMatchingLine(snippet, query);

        if (matched != null && matched.line != null) {
            // Tokenize for long strings since the match may be at the end of it.
            // Skip this part for short strings since the whole string will be displayed.
            // Most contact strings are short so the snippetize method will be called infrequently.
            final int lengthThreshold = getResources().getInteger(
                    R.integer.snippet_length_before_tokenize);
            if (matched.line.length() > lengthThreshold) {
                return snippetize(matched.line, matched.startIndex, lengthThreshold);
            } else {
                return matched.line;
            }
        }

        // No match found.
        return null;
    }

    private String snippetize(String line, int matchIndex, int maxLength) {
        // Show up to maxLength characters. But we only show full tokens so show the last full token
        // up to maxLength characters. So as many starting tokens as possible before trying ending
        // tokens.
        int remainingLength = maxLength;
        int tempRemainingLength = remainingLength;

        // Start the end token after the matched query.
        int index = matchIndex;
        int endTokenIndex = index;

        // Find the match token first.
        while (index < line.length()) {
            if (!Character.isLetterOrDigit(line.charAt(index))) {
                endTokenIndex = index;
                remainingLength = tempRemainingLength;
                break;
            }
            tempRemainingLength--;
            index++;
        }

        // Find as much content before the match.
        index = matchIndex - 1;
        tempRemainingLength = remainingLength;
        int startTokenIndex = matchIndex;
        while (index > -1 && tempRemainingLength > 0) {
            if (!Character.isLetterOrDigit(line.charAt(index))) {
                startTokenIndex = index;
                remainingLength = tempRemainingLength;
            }
            tempRemainingLength--;
            index--;
        }

        index = endTokenIndex;
        tempRemainingLength = remainingLength;
        // Find remaining content at after match.
        while (index < line.length() && tempRemainingLength > 0) {
            if (!Character.isLetterOrDigit(line.charAt(index))) {
                endTokenIndex = index;
            }
            tempRemainingLength--;
            index++;
        }
        // Append ellipse if there is content before or after.
        final StringBuilder sb = new StringBuilder();
        if (startTokenIndex > 0) {
            sb.append("...");
        }
        sb.append(line.substring(startTokenIndex, endTokenIndex));
        if (endTokenIndex < line.length()) {
            sb.append("...");
        }
        return sb.toString();
    }

    private static final Pattern SPLIT_PATTERN = Pattern.compile(
            "([\\w-\\.]+)@((?:[\\w]+\\.)+)([a-zA-Z]{2,4})|[\\w]+");

    /**
     * Helper method for splitting a string into tokens.  The lists passed in are populated with
     * the
     * tokens and offsets into the content of each token.  The tokenization function parses e-mail
     * addresses as a single token; otherwise it splits on any non-alphanumeric character.
     *
     * @param content Content to split.
     * @return List of token strings.
     */
    private static List<String> split(String content) {
        final Matcher matcher = SPLIT_PATTERN.matcher(content);
        final ArrayList<String> tokens = Lists.newArrayList();
        while (matcher.find()) {
            tokens.add(matcher.group());
        }
        return tokens;
    }

    /**
     * Shows data element.
     */
    public void showData(Cursor cursor, int dataColumnIndex) {
        cursor.copyStringToBuffer(dataColumnIndex, mDataBuffer);
        setData(mDataBuffer.data, mDataBuffer.sizeCopied);
    }

    public void setActivatedStateSupported(boolean flag) {
        this.mActivatedStateSupported = flag;
    }

    public void setAdjustSelectionBoundsEnabled(boolean enabled) {
        mAdjustSelectionBoundsEnabled = enabled;
    }

    @Override
    public void requestLayout() {
        // We will assume that once measured this will not need to resize
        // itself, so there is no need to pass the layout request to the parent
        // view (ListView).
        forceLayout();
    }

    public void setPhotoPosition(PhotoPosition photoPosition) {
        mPhotoPosition = photoPosition;
    }

    public PhotoPosition getPhotoPosition() {
        return mPhotoPosition;
    }

    /**
     * Set drawable resources directly for the drawable resource of the photo view.
     *
     * @param drawableId Id of drawable resource.
     */
    public void setDrawableResource(int drawableId) {
        ImageView photo = getPhotoView();
        photo.setScaleType(ImageView.ScaleType.CENTER);
        final Drawable drawable = ContextCompat.getDrawable(getContext(), drawableId);
        final int iconColor =
                ContextCompat.getColor(getContext(), R.color.search_shortcut_icon_color);
        if (CompatUtils.isLollipopCompatible()) {
            photo.setImageDrawable(drawable);
            photo.setImageTintList(ColorStateList.valueOf(iconColor));
        } else {
            final Drawable drawableWrapper = DrawableCompat.wrap(drawable).mutate();
            DrawableCompat.setTint(drawableWrapper, iconColor);
            photo.setImageDrawable(drawableWrapper);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        // If the touch event's coordinates are not within the view's header, then delegate
        // to super.onTouchEvent so that regular view behavior is preserved. Otherwise, consume
        // and ignore the touch event.
        if (mBoundsWithoutHeader.contains((int) x, (int) y) || !pointIsInView(x, y)) {
            return super.onTouchEvent(event);
        } else {
            return true;
        }
    }

    private final boolean pointIsInView(float localX, float localY) {
        return localX >= mLeftOffset && localX < mRightOffset
                && localY >= 0 && localY < (getBottom() - getTop());
    }
}
