/*
 * 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.activities;

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SearchView.OnCloseListener;
import android.widget.TextView;

import com.android.contacts.ContactsDrawerActivity;
import com.android.contacts.R;
import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
import com.android.contacts.compat.CompatUtils;
import com.android.contacts.list.ContactsRequest;
import com.android.contacts.util.MaterialColorMapUtils;

import java.util.ArrayList;

/**
 * Adapter for the action bar at the top of the Contacts activity.
 */
public class ActionBarAdapter implements OnCloseListener {

    public interface Listener {
        public abstract class Action {
            public static final int CHANGE_SEARCH_QUERY = 0;
            public static final int START_SEARCH_MODE = 1;
            public static final int START_SELECTION_MODE = 2;
            public static final int STOP_SEARCH_AND_SELECTION_MODE = 3;
            public static final int BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE = 4;
        }

        void onAction(int action);

        void onUpButtonPressed();
    }

    private static final String EXTRA_KEY_SEARCH_MODE = "navBar.searchMode";
    private static final String EXTRA_KEY_QUERY = "navBar.query";
    private static final String EXTRA_KEY_SELECTED_MODE = "navBar.selectionMode";

    private boolean mSelectionMode;
    private boolean mSearchMode;
    private String mQueryString;

    private EditText mSearchView;
    private View mClearSearchView;
    private View mSearchContainer;
    private View mSelectionContainer;

    private int mMaxToolbarContentInsetStart;
    private int mActionBarAnimationDuration;

    private final Activity mActivity;

    private Listener mListener;

    private final ActionBar mActionBar;
    private final Toolbar mToolbar;
    /**
     *  Frame that contains the toolbar and draws the toolbar's background color. This is useful
     *  for placing things behind the toolbar.
     */
    private final FrameLayout mToolBarFrame;

    private boolean mShowHomeIcon;
    private boolean mShowHomeAsUp;

    private int mSearchHintResId;

    private ValueAnimator mStatusBarAnimator;

    public ActionBarAdapter(Activity activity, Listener listener, ActionBar actionBar,
            Toolbar toolbar) {
        this(activity, listener, actionBar, toolbar, R.string.hint_findContacts);
    }

    public ActionBarAdapter(Activity activity, Listener listener, ActionBar actionBar,
            Toolbar toolbar, int searchHintResId) {
        mActivity = activity;
        mListener = listener;
        mActionBar = actionBar;
        mToolbar = toolbar;
        mToolBarFrame = (FrameLayout) mToolbar.getParent();
        mMaxToolbarContentInsetStart = mToolbar.getContentInsetStart();
        mSearchHintResId = searchHintResId;
        mActionBarAnimationDuration =
                mActivity.getResources().getInteger(R.integer.action_bar_animation_duration);

        setupSearchAndSelectionViews();
    }

    public void setShowHomeIcon(boolean showHomeIcon) {
        mShowHomeIcon = showHomeIcon;
    }

    public void setShowHomeAsUp(boolean showHomeAsUp) {
        mShowHomeAsUp = showHomeAsUp;
    }

    public View getSelectionContainer() {
        return mSelectionContainer;
    }

    private void setupSearchAndSelectionViews() {
        final LayoutInflater inflater = (LayoutInflater) mToolbar.getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

        // Setup search bar
        mSearchContainer = inflater.inflate(R.layout.search_bar_expanded, mToolbar,
                /* attachToRoot = */ false);
        mSearchContainer.setVisibility(View.VISIBLE);
        mToolbar.addView(mSearchContainer);
        mSearchContainer.setBackgroundColor(mActivity.getResources().getColor(
                R.color.searchbox_background_color));
        mSearchView = (EditText) mSearchContainer.findViewById(R.id.search_view);
        mSearchView.setHint(mActivity.getString(mSearchHintResId));
        mSearchView.addTextChangedListener(new SearchTextWatcher());
        final ImageButton searchBackButton = (ImageButton) mSearchContainer
                .findViewById(R.id.search_back_button);
        searchBackButton.setOnClickListener(
                new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    mListener.onUpButtonPressed();
                }
            }
        });
        searchBackButton.getDrawable().setAutoMirrored(true);

        mClearSearchView = mSearchContainer.findViewById(R.id.search_close_button);
        mClearSearchView.setOnClickListener(
                new OnClickListener() {
            @Override
            public void onClick(View v) {
                setQueryString(null);
            }
        });

        // Setup selection bar
        mSelectionContainer = inflater.inflate(R.layout.selection_bar, mToolbar,
                /* attachToRoot = */ false);
        // Insert the selection container into mToolBarFrame behind the Toolbar, so that
        // the Toolbar's MenuItems can appear on top of the selection container.
        mToolBarFrame.addView(mSelectionContainer, 0);
        mSelectionContainer.findViewById(R.id.selection_close).setOnClickListener(
                new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (mListener != null) {
                            mListener.onUpButtonPressed();
                        }
                    }
                });
    }

    public void initialize(Bundle savedState, ContactsRequest request) {
        if (savedState == null) {
            mSearchMode = request.isSearchMode();
            mQueryString = request.getQueryString();
            mSelectionMode = false;
        } else {
            mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
            mSelectionMode = savedState.getBoolean(EXTRA_KEY_SELECTED_MODE);
            mQueryString = savedState.getString(EXTRA_KEY_QUERY);
        }
        // Show tabs or the expanded {@link SearchView}, depending on whether or not we are in
        // search mode.
        update(true /* skipAnimation */);
        // Expanding the {@link SearchView} clears the query, so set the query from the
        // {@link ContactsRequest} after it has been expanded, if applicable.
        if (mSearchMode && !TextUtils.isEmpty(mQueryString)) {
            setQueryString(mQueryString);
        }
    }

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

    private class SearchTextWatcher implements TextWatcher {

        @Override
        public void onTextChanged(CharSequence queryString, int start, int before, int count) {
            if (queryString.equals(mQueryString)) {
                return;
            }
            mQueryString = queryString.toString();
            if (!mSearchMode) {
                if (!TextUtils.isEmpty(queryString)) {
                    setSearchMode(true);
                }
            } else if (mListener != null) {
                mListener.onAction(Action.CHANGE_SEARCH_QUERY);
            }
            mClearSearchView.setVisibility(
                    TextUtils.isEmpty(queryString) ? View.GONE : View.VISIBLE);
        }

        @Override
        public void afterTextChanged(Editable s) {}

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
    }

    /**
     * @return Whether in search mode, i.e. if the search view is visible/expanded.
     *
     * Note even if the action bar is in search mode, if the query is empty, the search fragment
     * will not be in search mode.
     */
    public boolean isSearchMode() {
        return mSearchMode;
    }

    /**
     * @return Whether in selection mode, i.e. if the selection view is visible/expanded.
     */
    public boolean isSelectionMode() {
        return mSelectionMode;
    }

    public void setSearchMode(boolean flag) {
        if (mSearchMode != flag) {
            mSearchMode = flag;
            update(false /* skipAnimation */);
            if (mSearchView == null) {
                return;
            }
            if (mSearchMode) {
                mSearchView.setEnabled(true);
                setFocusOnSearchView();
            } else {
                // Disable search view, so that it doesn't keep the IME visible.
                mSearchView.setEnabled(false);
            }
            setQueryString(null);
        } else if (flag) {
            // Everything is already set up. Still make sure the keyboard is up
            if (mSearchView != null) setFocusOnSearchView();
        }
    }

    public void setSelectionMode(boolean flag) {
        if (mSelectionMode != flag) {
            mSelectionMode = flag;
            update(false /* skipAnimation */);
        }
    }

    public String getQueryString() {
        return mSearchMode ? mQueryString : null;
    }

    public void setQueryString(String query) {
        mQueryString = query;
        if (mSearchView != null) {
            mSearchView.setText(query);
            // When programmatically entering text into the search view, the most reasonable
            // place for the cursor is after all the text.
            mSearchView.setSelection(mSearchView.getText() == null ?
                    0 : mSearchView.getText().length());
        }
    }

    /** @return true if the "UP" icon is showing. */
    public boolean isUpShowing() {
        return mSearchMode; // Only shown on the search mode.
    }

    private void updateDisplayOptionsInner() {
        // All the flags we may change in this method.
        final int MASK = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME
                | ActionBar.DISPLAY_HOME_AS_UP;

        // The current flags set to the action bar.  (only the ones that we may change here)
        final int current = mActionBar.getDisplayOptions() & MASK;

        final boolean isSearchOrSelectionMode = mSearchMode || mSelectionMode;

        // Build the new flags...
        int newFlags = 0;
        if (mShowHomeIcon && !isSearchOrSelectionMode) {
            newFlags |= ActionBar.DISPLAY_SHOW_HOME;
            if (mShowHomeAsUp) {
                newFlags |= ActionBar.DISPLAY_HOME_AS_UP;
            }
        }
        if (mSearchMode && !mSelectionMode) {
            // The search container is placed inside the toolbar. So we need to disable the
            // Toolbar's content inset in order to allow the search container to be the width of
            // the window.
            mToolbar.setContentInsetsRelative(0, mToolbar.getContentInsetEnd());
        }
        if (!isSearchOrSelectionMode) {
            newFlags |= ActionBar.DISPLAY_SHOW_TITLE;
            mToolbar.setContentInsetsRelative(mMaxToolbarContentInsetStart,
                    mToolbar.getContentInsetEnd());
            mToolbar.setNavigationIcon(R.drawable.quantum_ic_menu_vd_theme_24);
        } else {
            mToolbar.setNavigationIcon(null);
        }

        if (mSelectionMode) {
            // Minimize the horizontal width of the Toolbar since the selection container is placed
            // behind the toolbar and its left hand side needs to be clickable.
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mToolbar.getLayoutParams();
            params.width = LayoutParams.WRAP_CONTENT;
            params.gravity = Gravity.END;
            mToolbar.setLayoutParams(params);
        } else {
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mToolbar.getLayoutParams();
            params.width = LayoutParams.MATCH_PARENT;
            params.gravity = Gravity.END;
            mToolbar.setLayoutParams(params);
        }

        if (current != newFlags) {
            // Pass the mask here to preserve other flags that we're not interested here.
            mActionBar.setDisplayOptions(newFlags, MASK);
        }
    }

    private void update(boolean skipAnimation) {
        updateOverflowButtonColor();

        final boolean isSelectionModeChanging
                = (mSelectionContainer.getParent() == null) == mSelectionMode;
        final boolean isSwitchingFromSearchToSelection =
                mSearchMode && isSelectionModeChanging || mSearchMode && mSelectionMode;
        final boolean isSearchModeChanging
                = (mSearchContainer.getParent() == null) == mSearchMode;
        final boolean isTabHeightChanging = isSearchModeChanging || isSelectionModeChanging;

        // Update toolbar and status bar color.
        mToolBarFrame.setBackgroundColor(MaterialColorMapUtils.getToolBarColor(mActivity));
        updateStatusBarColor(isSelectionModeChanging && !isSearchModeChanging);

        // When skipAnimation=true, it is possible that we will switch from search mode
        // to selection mode directly. So we need to remove the undesired container in addition
        // to adding the desired container.
        if (skipAnimation || isSwitchingFromSearchToSelection) {
            if (isTabHeightChanging || isSwitchingFromSearchToSelection) {
                mToolbar.removeView(mSearchContainer);
                mToolBarFrame.removeView(mSelectionContainer);
                if (mSelectionMode) {
                    addSelectionContainer();
                } else if (mSearchMode) {
                    addSearchContainer();
                }
                updateDisplayOptions(isSearchModeChanging);
            }
            return;
        }

        // Handle a switch to/from selection mode, due to UI interaction.
        if (isSelectionModeChanging) {
            if (mSelectionMode) {
                addSelectionContainer();
                mSelectionContainer.setAlpha(0);
                mSelectionContainer.animate().alpha(1).setDuration(mActionBarAnimationDuration);
                updateDisplayOptions(isSearchModeChanging);
            } else {
                if (mListener != null) {
                    mListener.onAction(Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE);
                }
                mSelectionContainer.setAlpha(1);
                mSelectionContainer.animate().alpha(0).setDuration(mActionBarAnimationDuration)
                        .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        updateDisplayOptions(isSearchModeChanging);
                        mToolBarFrame.removeView(mSelectionContainer);
                    }
                });
            }
        }

        // Handle a switch to/from search mode, due to UI interaction.
        if (isSearchModeChanging) {
            if (mSearchMode) {
                addSearchContainer();
                mSearchContainer.setAlpha(0);
                mSearchContainer.animate().alpha(1).setDuration(mActionBarAnimationDuration);
                updateDisplayOptions(isSearchModeChanging);
            } else {
                mSearchContainer.setAlpha(1);
                mSearchContainer.animate().alpha(0).setDuration(mActionBarAnimationDuration)
                        .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        updateDisplayOptions(isSearchModeChanging);
                        mToolbar.removeView(mSearchContainer);
                    }
                });
            }
        }
    }

    /**
     * Find overflow menu ImageView by its content description and update its color.
     */
    private void updateOverflowButtonColor() {
        final String overflowDescription = mActivity.getResources().getString(
                R.string.abc_action_menu_overflow_description);
        final ViewGroup decorView = (ViewGroup) mActivity.getWindow().getDecorView();
        final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        // Find the overflow ImageView.
                        final ArrayList<View> outViews = new ArrayList<>();
                        decorView.findViewsWithText(outViews, overflowDescription,
                                View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);

                        for (View view : outViews) {
                            if (!(view instanceof ImageView)) {
                                continue;
                            }
                            final ImageView overflow = (ImageView) view;

                            // Update the overflow image color.
                            final int iconColor;
                            if (mSelectionMode) {
                                iconColor = mActivity.getResources().getColor(
                                        R.color.actionbar_color_grey_solid);
                            } else {
                                iconColor = mActivity.getResources().getColor(
                                        R.color.actionbar_text_color);
                            }
                            overflow.setImageTintList(ColorStateList.valueOf(iconColor));
                        }

                        // We're done, remove the listener.
                        decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }
                });
    }

    public void setSelectionCount(int selectionCount) {
        TextView textView = (TextView) mSelectionContainer.findViewById(R.id.selection_count_text);
        if (selectionCount == 0) {
            textView.setVisibility(View.GONE);
        } else {
            textView.setVisibility(View.VISIBLE);
        }
        textView.setText(String.valueOf(selectionCount));
    }

    public void setActionBarTitle(String title) {
        final TextView textView =
                (TextView) mSelectionContainer.findViewById(R.id.selection_count_text);
        textView.setVisibility(View.VISIBLE);
        textView.setText(title);
    }

    private void updateStatusBarColor(boolean shouldAnimate) {
        if (!CompatUtils.isLollipopCompatible()) {
            return; // we can't change the status bar color prior to Lollipop
        }

        if (mSelectionMode) {
            final int cabStatusBarColor = ContextCompat.getColor(
                    mActivity, R.color.contextual_selection_bar_status_bar_color);
            runStatusBarAnimation(/* colorTo */ cabStatusBarColor);
        } else {
            if (shouldAnimate) {
                runStatusBarAnimation(/* colorTo */
                        MaterialColorMapUtils.getStatusBarColor(mActivity));
            } else if (mActivity instanceof ContactsDrawerActivity) {
                ((ContactsDrawerActivity) mActivity).updateStatusBarBackground();
            }
        }
    }

    private void runStatusBarAnimation(int colorTo) {
        final Window window = mActivity.getWindow();
        if (window.getStatusBarColor() != colorTo) {
            // Cancel running animation.
            if (mStatusBarAnimator != null && mStatusBarAnimator.isRunning()) {
                mStatusBarAnimator.cancel();
            }
            final int from = window.getStatusBarColor();
            // Set up mStatusBarAnimator and run animation.
            mStatusBarAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), from, colorTo);
            mStatusBarAnimator.addUpdateListener(
                    new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animator) {
                            window.setStatusBarColor((Integer) animator.getAnimatedValue());
                        }
                    });
            mStatusBarAnimator.setDuration(mActionBarAnimationDuration);
            mStatusBarAnimator.setStartDelay(0);
            mStatusBarAnimator.start();
        }
    }

    private void addSearchContainer() {
        mToolbar.removeView(mSearchContainer);
        mToolbar.addView(mSearchContainer);
        mSearchContainer.setAlpha(1);
    }

    private void addSelectionContainer() {
        mToolBarFrame.removeView(mSelectionContainer);
        mToolBarFrame.addView(mSelectionContainer, 0);
        mSelectionContainer.setAlpha(1);
    }

    private void updateDisplayOptions(boolean isSearchModeChanging) {
        if (mSearchMode && !mSelectionMode) {
            setFocusOnSearchView();
            // Since we have the {@link SearchView} in a custom action bar, we must manually handle
            // expanding the {@link SearchView} when a search is initiated. Note that a side effect
            // of this method is that the {@link SearchView} query text is set to empty string.
            if (isSearchModeChanging) {
                final CharSequence queryText = mSearchView.getText();
                if (!TextUtils.isEmpty(queryText)) {
                    mSearchView.setText(queryText);
                }
            }
        }
        if (mListener != null) {
            if (mSearchMode) {
                mListener.onAction(Action.START_SEARCH_MODE);
            }
            if (mSelectionMode) {
                mListener.onAction(Action.START_SELECTION_MODE);
            }
            if (!mSearchMode && !mSelectionMode) {
                mListener.onAction(Action.STOP_SEARCH_AND_SELECTION_MODE);
            }
        }
        updateDisplayOptionsInner();
    }

    @Override
    public boolean onClose() {
        setSearchMode(false);
        return false;
    }

    public void onSaveInstanceState(Bundle outState) {
        outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
        outState.putBoolean(EXTRA_KEY_SELECTED_MODE, mSelectionMode);
        outState.putString(EXTRA_KEY_QUERY, mQueryString);
    }

    public void setFocusOnSearchView() {
        mSearchView.requestFocus();
        showInputMethod(mSearchView); // Workaround for the "IME not popping up" issue.
    }

    private void showInputMethod(View view) {
        final InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
                Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.showSoftInput(view, 0);
        }
    }
}
