/*
 * Copyright (C) 2013 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.dialer.list;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.provider.CallLog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;

import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.ContactTileLoaderFactory;
import com.android.contacts.common.GeoUtil;
import com.android.contacts.common.list.ContactEntry;
import com.android.contacts.common.list.ContactListItemView;
import com.android.contacts.common.list.ContactTileView;
import com.android.dialer.DialtactsActivity;
import com.android.dialer.R;
import com.android.dialer.calllog.CallLogAdapter;
import com.android.dialer.calllog.CallLogQuery;
import com.android.dialer.calllog.CallLogQueryHandler;
import com.android.dialer.calllog.ContactInfoHelper;
import com.android.dialer.list.PhoneFavoritesTileAdapter.ContactTileRow;
import com.android.dialerbind.ObjectFactory;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * Fragment for Phone UI's favorite screen.
 *
 * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all"
 * contacts. To show them at once, this merges results from {@link com.android.contacts.common.list.ContactTileAdapter} and
 * {@link com.android.contacts.common.list.PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}.
 * A contact filter header is also inserted between those adapters' results.
 */
public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener,
        CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher,
        PhoneFavoritesTileAdapter.OnDataSetChangedForAnimationListener {

    /**
     * By default, the animation code assumes that all items in a list view are of the same height
     * when animating new list items into view (e.g. from the bottom of the screen into view).
     * This can cause incorrect translation offsets when a item that is larger or smaller than
     * other list item is removed from the list. This key is used to provide the actual height
     * of the removed object so that the actual translation appears correct to the user.
     */
    private static final long KEY_REMOVED_ITEM_HEIGHT = Long.MAX_VALUE;

    private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
    private static final boolean DEBUG = false;

    private int mAnimationDuration;

    /**
     * Used with LoaderManager.
     */
    private static int LOADER_ID_CONTACT_TILE = 1;
    private static int MISSED_CALL_LOADER = 2;

    private static final String KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE =
            "key_last_dismissed_call_shortcut_date";

    public interface OnShowAllContactsListener {
        public void onShowAllContacts();
    }

    public interface Listener {
        public void onContactSelected(Uri contactUri);
        public void onCallNumberDirectly(String phoneNumber);
    }

    public interface HostInterface {
        public void setDragDropController(DragDropController controller);
    }

    private class MissedCallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {

        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            final Uri uri = CallLog.Calls.CONTENT_URI;
            final String[] projection = new String[] {CallLog.Calls.TYPE};
            final String selection = CallLog.Calls.TYPE + " = " + CallLog.Calls.MISSED_TYPE +
                    " AND " + CallLog.Calls.IS_READ + " = 0";
            return new CursorLoader(getActivity(), uri, projection, selection, null, null);
        }

        @Override
        public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) {
            mCallLogAdapter.setMissedCalls(data);
        }

        @Override
        public void onLoaderReset(Loader<Cursor> cursorLoader) {
        }
    }

    private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
        @Override
        public CursorLoader onCreateLoader(int id, Bundle args) {
            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader.");
            return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity());
        }

        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished");
            mContactTileAdapter.setContactCursor(data);
            setEmptyViewVisibility(mContactTileAdapter.getCount() == 0);
        }

        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. ");
        }
    }

    private class ContactTileAdapterListener implements ContactTileView.Listener {
        @Override
        public void onContactSelected(Uri contactUri, Rect targetRect) {
            if (mListener != null) {
                mListener.onContactSelected(contactUri);
            }
        }

        @Override
        public void onCallNumberDirectly(String phoneNumber) {
            if (mListener != null) {
                mListener.onCallNumberDirectly(phoneNumber);
            }
        }

        @Override
        public int getApproximateTileWidth() {
            return getView().getWidth() / mContactTileAdapter.getColumnCount();
        }
    }

    private class ScrollListener implements ListView.OnScrollListener {
        @Override
        public void onScroll(AbsListView view,
                int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            mActivityScrollListener.onListFragmentScrollStateChange(scrollState);
        }
    }

    private Listener mListener;

    private OnListFragmentScrolledListener mActivityScrollListener;
    private OnShowAllContactsListener mShowAllContactsListener;
    private PhoneFavoriteMergedAdapter mAdapter;
    private PhoneFavoritesTileAdapter mContactTileAdapter;

    private CallLogAdapter mCallLogAdapter;
    private CallLogQueryHandler mCallLogQueryHandler;

    private View mParentView;

    private PhoneFavoriteListView mListView;

    private View mPhoneFavoritesMenu;
    private View mContactTileFrame;

    private TileInteractionTeaserView mTileInteractionTeaserView;

    private final HashMap<Long, Integer> mItemIdTopMap = new HashMap<Long, Integer>();
    private final HashMap<Long, Integer> mItemIdLeftMap = new HashMap<Long, Integer>();

    /**
     * Layout used when there are no favorites.
     */
    private View mEmptyView;

    /**
     * Call shortcuts older than this date (persisted in shared preferences) will not show up in
     * at the top of the screen
     */
    private long mLastCallShortcutDate = 0;

    /**
     * The date of the current call shortcut that is showing on screen.
     */
    private long mCurrentCallShortcutDate = 0;

    private final ContactTileView.Listener mContactTileAdapterListener =
            new ContactTileAdapterListener();
    private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener =
            new ContactTileLoaderListener();
    private final ScrollListener mScrollListener = new ScrollListener();

    @Override
    public void onAttach(Activity activity) {
        if (DEBUG) Log.d(TAG, "onAttach()");
        super.onAttach(activity);

        // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
        // We don't construct the resultant adapter at this moment since it requires LayoutInflater
        // that will be available on onCreateView().
        mContactTileAdapter = new PhoneFavoritesTileAdapter(activity, mContactTileAdapterListener,
                this,
                getResources().getInteger(R.integer.contact_tile_column_count_in_favorites),
                PhoneFavoritesTileAdapter.NO_ROW_LIMIT);
        mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
    }

    @Override
    public void onCreate(Bundle savedState) {
        if (DEBUG) Log.d(TAG, "onCreate()");
        super.onCreate(savedState);

        mAnimationDuration = getResources().getInteger(R.integer.fade_duration);
        mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(),
                this, 1);
        final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
        mCallLogAdapter = ObjectFactory.newCallLogAdapter(getActivity(), this,
                new ContactInfoHelper(getActivity(), currentCountryIso), false, false);
        setHasOptionsMenu(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        final SharedPreferences prefs = getActivity().getSharedPreferences(
                DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE);

        mLastCallShortcutDate = prefs.getLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, 0);

        fetchCalls();
        mCallLogAdapter.setLoading(true);
        getLoaderManager().getLoader(LOADER_ID_CONTACT_TILE).forceLoad();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mParentView = inflater.inflate(R.layout.phone_favorites_fragment, container, false);

        mListView = (PhoneFavoriteListView) mParentView.findViewById(R.id.contact_tile_list);
        mListView.setItemsCanFocus(true);
        mListView.setOnItemClickListener(this);
        mListView.setVerticalScrollBarEnabled(false);
        mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
        mListView.setOnItemSwipeListener(mContactTileAdapter);
        mListView.getDragDropController().addOnDragDropListener(mContactTileAdapter);

        final ImageView dragShadowOverlay =
                (ImageView) mParentView.findViewById(R.id.contact_tile_drag_shadow_overlay);
        mListView.setDragShadowOverlay(dragShadowOverlay);

        mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view);

        mPhoneFavoritesMenu = inflater.inflate(R.layout.phone_favorites_menu, mListView, false);
        prepareFavoritesMenu(mPhoneFavoritesMenu);

        mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame);

        mTileInteractionTeaserView = (TileInteractionTeaserView) inflater.inflate(
                R.layout.tile_interactions_teaser_view, mListView, false);

        mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter,
                mCallLogAdapter, mPhoneFavoritesMenu, mTileInteractionTeaserView);

        mTileInteractionTeaserView.setAdapter(mAdapter);

        mListView.setAdapter(mAdapter);

        mListView.setOnScrollListener(mScrollListener);
        mListView.setFastScrollEnabled(false);
        mListView.setFastScrollAlwaysVisible(false);

        return mParentView;
    }

    public boolean hasFrequents() {
        if (mContactTileAdapter == null) return false;
        return mContactTileAdapter.getNumFrequents() > 0;
    }

    /* package */ void setEmptyViewVisibility(final boolean visible) {
        final int previousVisibility = mEmptyView.getVisibility();
        final int newVisibility = visible ? View.VISIBLE : View.GONE;

        if (previousVisibility != newVisibility) {
            final RelativeLayout.LayoutParams params = (LayoutParams) mContactTileFrame
                    .getLayoutParams();
            params.height = visible ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT;
            mContactTileFrame.setLayoutParams(params);
            mEmptyView.setVisibility(newVisibility);
        }
    }

    @Override
    public void onStart() {
        super.onStart();

        final Activity activity = getActivity();

        try {
            mActivityScrollListener = (OnListFragmentScrolledListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnListFragmentScrolledListener");
        }

        try {
            mShowAllContactsListener = (OnShowAllContactsListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnShowAllContactsListener");
        }

        try {
            OnDragDropListener listener = (OnDragDropListener) activity;
            mListView.getDragDropController().addOnDragDropListener(listener);
            ((HostInterface) activity).setDragDropController(mListView.getDragDropController());
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnDragDropListener and HostInterface");
        }

        // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
        // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
        // be called, on which we'll check if "all" contacts should be reloaded again or not.
        getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
        getLoaderManager().initLoader(MISSED_CALL_LOADER, null, new MissedCallLogLoaderListener());
    }

    /**
     * {@inheritDoc}
     *
     * This is only effective for elements provided by {@link #mContactTileAdapter}.
     * {@link #mContactTileAdapter} has its own logic for click events.
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        final int contactTileAdapterCount = mContactTileAdapter.getCount();
        if (position <= contactTileAdapterCount) {
            Log.e(TAG, "onItemClick() event for unexpected position. "
                    + "The position " + position + " is before \"all\" section. Ignored.");
        }
    }

    /**
     * Gets called when user click on the show all contacts button.
     */
    private void showAllContacts() {
        mShowAllContactsListener.onShowAllContacts();
    }

    public void setListener(Listener listener) {
        mListener = listener;
    }

    @Override
    public void onVoicemailStatusFetched(Cursor statusCursor) {
        // no-op
    }

    @Override
    public void onCallsFetched(Cursor cursor) {
        animateListView();
        mCallLogAdapter.setLoading(false);

        // Save the date of the most recent call log item
        if (cursor != null && cursor.moveToFirst()) {
            mCurrentCallShortcutDate = cursor.getLong(CallLogQuery.DATE);
        }

        mCallLogAdapter.changeCursor(cursor);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void fetchCalls() {
        mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL, mLastCallShortcutDate);
    }

    @Override
    public void onPause() {
        // If there are any pending contact entries that are to be removed, remove them
        mContactTileAdapter.removePendingContactEntry();
        // Wipe the cache to refresh the call shortcut item. This is not that expensive because
        // it only contains one item.
        mCallLogAdapter.invalidateCache();
        super.onPause();
    }

    /**
     * Cache the current view offsets into memory. Once a relayout of views in the ListView
     * has happened due to a dataset change, the cached offsets are used to create animations
     * that slide views from their previous positions to their new ones, to give the appearance
     * that the views are sliding into their new positions.
     */
    @SuppressWarnings("unchecked")
    private void saveOffsets(int removedItemHeight) {
        final int firstVisiblePosition = mListView.getFirstVisiblePosition();
        if (DEBUG) {
            Log.d(TAG, "Child count : " + mListView.getChildCount());
        }
        for (int i = 0; i < mListView.getChildCount(); i++) {
            final View child = mListView.getChildAt(i);
            final int position = firstVisiblePosition + i;
            final long itemId = mAdapter.getItemId(position);
            final int itemViewType = mAdapter.getItemViewType(position);
            if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP) {
                // This is a tiled row, so save horizontal offsets instead
                saveHorizontalOffsets((ContactTileRow) child, (ArrayList<ContactEntry>)
                        mAdapter.getItem(position), position);
            }
            if (DEBUG) {
                Log.d(TAG, "Saving itemId: " + itemId + " for listview child " + i + " Top: "
                        + child.getTop());
            }
            mItemIdTopMap.put(itemId, child.getTop());
        }

        mItemIdTopMap.put(KEY_REMOVED_ITEM_HEIGHT, removedItemHeight);
    }

    /**
     * Saves the horizontal offsets for contacts that are displayed as tiles in a row. Saving
     * these offsets allow us to animate tiles sliding left and right within the same row.
     * See {@link #saveOffsets(int removedItemHeight)}
     */
    private void saveHorizontalOffsets(ContactTileRow row, ArrayList<ContactEntry> list,
            int currentRowIndex) {
        for (int i = 0; i < list.size() && i < row.getChildCount(); i++) {
            final View child = row.getChildAt(i);
            if (child == null) {
                continue;
            }
            final ContactEntry entry = list.get(i);
            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);
            if (DEBUG) {
                Log.d(TAG, "Saving itemId: " + itemId + " for tileview child " + i + " Left: "
                        + child.getTop());
            }
            mItemIdTopMap.put(itemId, currentRowIndex);
            mItemIdLeftMap.put(itemId, child.getLeft());
        }
    }

    /*
     * Performs a animations for a row of tiles
     */
    private void performHorizontalAnimations(ContactTileRow row, ArrayList<ContactEntry> list,
            long[] idsInPlace, int currentRow) {
        if (mItemIdLeftMap.isEmpty()) {
            return;
        }
        final AnimatorSet animSet = new AnimatorSet();
        final ArrayList<Animator> animators = new ArrayList<Animator>();
        for (int i = 0; i < list.size(); i++) {
            final View child = row.getChildAt(i);
            final ContactEntry entry = list.get(i);
            final long itemId = mContactTileAdapter.getAdjustedItemId(entry.id);

            if (containsId(idsInPlace, itemId)) {
                animators.add(ObjectAnimator.ofFloat(
                        child, "alpha", 0.0f, 1.0f));
                break;
            } else {
                Integer startLeft = mItemIdLeftMap.get(itemId);
                int left = child.getLeft();

                Integer startRow = mItemIdTopMap.get(itemId);

                if (startRow != null) {
                    if (startRow > currentRow) {
                        // Item has shifted upwards to the previous row.
                        // It should now animate in from right to left.
                        startLeft = left + child.getWidth();
                    } else if (startRow < currentRow) {
                        // Item has shifted downwards to the next row.
                        // It should now animate in from left to right.
                        startLeft = left - child.getWidth();
                    }

                    // If the item hasn't shifted rows (startRow == currentRow), it either remains
                    // in the same position or has shifted left or right within its current row.
                    // Either way, startLeft has already been correctly saved and retrieved from
                    // mItemIdTopMap.
                }

                if (startLeft != null) {
                    if (startLeft != left) {
                        int delta = startLeft - left;
                        if (DEBUG) {
                            Log.d(TAG, "Found itemId: " + itemId + " for tileview child " + i +
                                    " Left: " + left +
                                    " Delta: " + delta);
                        }
                        animators.add(ObjectAnimator.ofFloat(
                                child, "translationX", delta, 0.0f));
                    }
                } else {
                    // In case the last square row is pushed up from the non-square section.
                    animators.add(ObjectAnimator.ofFloat(
                            child, "translationX", left, 0.0f));
                }
            }
        }
        if (animators.size() > 0) {
            animSet.setDuration(mAnimationDuration).playTogether(animators);
            animSet.start();
        }
    }

    /*
     * Performs animations for the list view. If the list item is a row of tiles, horizontal
     * animations will be performed instead.
     */
    private void animateListView(final long... idsInPlace) {
        if (mItemIdTopMap.isEmpty()) {
            // Don't do animations if the database is being queried for the first time and
            // the previous item offsets have not been cached, or the user hasn't done anything
            // (dragging, swiping etc) that requires an animation.
            return;
        }

        final int removedItemHeight = mItemIdTopMap.get(KEY_REMOVED_ITEM_HEIGHT);

        final ViewTreeObserver observer = mListView.getViewTreeObserver();
        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @SuppressWarnings("unchecked")
            @Override
            public boolean onPreDraw() {
                observer.removeOnPreDrawListener(this);
                final int firstVisiblePosition = mListView.getFirstVisiblePosition();
                final AnimatorSet animSet = new AnimatorSet();
                final ArrayList<Animator> animators = new ArrayList<Animator>();
                for (int i = 0; i < mListView.getChildCount(); i++) {
                    final View child = mListView.getChildAt(i);
                    int position = firstVisiblePosition + i;
                    final int itemViewType = mAdapter.getItemViewType(position);
                    if (itemViewType == PhoneFavoritesTileAdapter.ViewTypes.TOP &&
                            child instanceof ContactTileRow) {
                        // This is a tiled row, so perform horizontal animations instead
                        performHorizontalAnimations((ContactTileRow) child, (
                                ArrayList<ContactEntry>) mAdapter.getItem(position), idsInPlace,
                                position);
                    }

                    final long itemId = mAdapter.getItemId(position);

                    if (containsId(idsInPlace, itemId)) {
                        animators.add(ObjectAnimator.ofFloat(
                                child, "alpha", 0.0f, 1.0f));
                        break;
                    } else {
                        Integer startTop = mItemIdTopMap.get(itemId);
                        final int top = child.getTop();
                        int delta = 0;
                        if (startTop != null) {
                            if (startTop != top) {
                                delta = startTop - top;
                            }
                        } else if (!mItemIdLeftMap.containsKey(itemId)) {
                            // Animate new views along with the others. The catch is that they did
                            // not exist in the start state, so we must calculate their starting
                            // position based on neighboring views.

                            final int itemHeight;
                            if (removedItemHeight == 0) {
                                itemHeight = child.getHeight() + mListView.getDividerHeight();
                            } else {
                                itemHeight = removedItemHeight;
                            }
                            startTop = top + (i > 0 ? itemHeight : -itemHeight);
                            delta = startTop - top;
                        } else {
                            // In case the first non-square row is pushed down
                            // from the square section.
                            animators.add(ObjectAnimator.ofFloat(
                                    child, "alpha", 0.0f, 1.0f));
                        }
                        if (DEBUG) {
                            Log.d(TAG, "Found itemId: " + itemId + " for listview child " + i +
                                    " Top: " + top +
                                    " Delta: " + delta);
                        }

                        if (delta != 0) {
                            animators.add(ObjectAnimator.ofFloat(
                                    child, "translationY", delta, 0.0f));
                        }
                    }
                }

                if (animators.size() > 0) {
                    animSet.setDuration(mAnimationDuration).playTogether(animators);
                    animSet.start();
                }

                mItemIdTopMap.clear();
                mItemIdLeftMap.clear();
                return true;
            }
        });
    }

    private boolean containsId(long[] ids, long target) {
        // Linear search on array is fine because this is typically only 0-1 elements long
        for (int i = 0; i < ids.length; i++) {
            if (ids[i] == target) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void onDataSetChangedForAnimation(long... idsInPlace) {
        animateListView(idsInPlace);
    }

    @Override
    public void cacheOffsetsForDatasetChange() {
        saveOffsets(0);
    }

    public void dismissShortcut(int height) {
        saveOffsets(height);
        mLastCallShortcutDate = mCurrentCallShortcutDate;
        final SharedPreferences prefs = getActivity().getSharedPreferences(
                DialtactsActivity.SHARED_PREFS_NAME, Context.MODE_PRIVATE);
        prefs.edit().putLong(KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE, mLastCallShortcutDate)
                .apply();
        fetchCalls();
    }

    /**
     * Prepares the favorites menu which contains the static label "Speed Dial" and the
     * "All Contacts" button.  Taps anywhere in the view take the user to "All Contacts".
     * This emulates how the headers in Play Store work.
     */
    private void prepareFavoritesMenu(View favoritesMenu) {
        // Set the onClick listener for the view to bring up the all contacts view.
        favoritesMenu.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                showAllContacts();
            }
        });
    }
}
