/*
 * 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
                + getPaddingBottom() + getPaddingTop());

        // 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());
    }
}
