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

import static com.android.documentsui.base.Shared.DEBUG;

import android.annotation.Nullable;
import android.os.Bundle;
import android.provider.DocumentsContract.Root;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnActionExpandListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;

import com.android.documentsui.DocumentsToolbar;
import com.android.documentsui.R;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;

/**
 * Manages searching UI behavior.
 */
public class SearchViewManager implements
        SearchView.OnCloseListener, OnQueryTextListener, OnClickListener, OnFocusChangeListener,
        OnActionExpandListener {

    static final String TAG = "SearchManager";
    private final SearchManagerListener mListener;
    private final DebugCommandProcessor mCommandProcessor;

    private boolean mSearchExpanded;
    private String mCurrentSearch;
    private boolean mIgnoreNextClose;
    private boolean mFullBar;

    private DocumentsToolbar mActionBar;
    private MenuItem mMenuItem;
    private SearchView mSearchView;

    public SearchViewManager(
            SearchManagerListener listener,
            @Nullable Bundle savedState) {
        assert (listener != null);
        mListener = listener;
        mCurrentSearch = savedState != null ? savedState.getString(Shared.EXTRA_QUERY) : null;

        // "Commands" are meta input for controlling system behavior.
        // We piggy back on search input as it is the only text input
        // area in the app. But the functionality is independent
        // of "regular" search query processing.
        mCommandProcessor = new DebugCommandProcessor();
    }

    public void install(DocumentsToolbar actionBar, boolean isFullBarSearch) {
        mActionBar = actionBar;
        mMenuItem = actionBar.getSearchMenu();
        mSearchView = (SearchView) mMenuItem.getActionView();

        mSearchView.setOnQueryTextListener(this);
        mSearchView.setOnCloseListener(this);
        mSearchView.setOnSearchClickListener(this);
        mSearchView.setOnQueryTextFocusChangeListener(this);

        mFullBar = isFullBarSearch;
        if (mFullBar) {
            mMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
                    | MenuItem.SHOW_AS_ACTION_ALWAYS);
            mMenuItem.setOnActionExpandListener(this);
        }

        restoreSearch();
    }

    /**
     * Used to hide menu icons, when the search is being restored. Needed because search restoration
     * is done before onPrepareOptionsMenu(Menu menu) that is overriding the icons visibility.
     */
    public void updateMenu() {
        if (isSearching() && mFullBar) {
            Menu menu = mActionBar.getMenu();
            menu.setGroupVisible(R.id.group_hide_when_searching, false);
        }
    }

    /**
     * @param root Info about the current directory.
     */
    public void update(RootInfo root) {
        if (mMenuItem == null) {
            if (DEBUG) Log.d(TAG, "update called before Search MenuItem installed.");
            return;
        }

        if (mCurrentSearch != null) {
            mMenuItem.expandActionView();

            mSearchView.setIconified(false);
            mSearchView.clearFocus();
            mSearchView.setQuery(mCurrentSearch, false);
        } else {
            mSearchView.clearFocus();
            if (!mSearchView.isIconified()) {
                mIgnoreNextClose = true;
                mSearchView.setIconified(true);
            }

            if (mMenuItem.isActionViewExpanded()) {
                mMenuItem.collapseActionView();
            }
        }

        showMenu(root != null
                && ((root.flags & Root.FLAG_SUPPORTS_SEARCH) != 0));
    }

    public void showMenu(boolean visible) {
        if (mMenuItem == null) {
            if (DEBUG) Log.d(TAG, "showMenu called before Search MenuItem installed.");
            return;
        }

        if (!visible) {
            mCurrentSearch = null;
        }

        mMenuItem.setVisible(visible);
    }

    /**
     * Cancels current search operation. Triggers clearing and collapsing the SearchView.
     *
     * @return True if it cancels search. False if it does not operate search currently.
     */
    public boolean cancelSearch() {
        if (isExpanded() || isSearching()) {
            // If the query string is not empty search view won't get iconified
            mSearchView.setQuery("", false);

            if (mFullBar) {
               onClose();
            } else {
                // Causes calling onClose(). onClose() is triggering directory content update.
                mSearchView.setIconified(true);
            }
            return true;
        }
        return false;
    }

    /**
     * Sets search view into the searching state. Used to restore state after device orientation
     * change.
     */
    private void restoreSearch() {
        if (isSearching()) {
            if(mFullBar) {
                mMenuItem.expandActionView();
            } else {
                mSearchView.setIconified(false);
            }
            onSearchExpanded();
            mSearchView.setQuery(mCurrentSearch, false);
            mSearchView.clearFocus();
        }
    }

    private void onSearchExpanded() {
        mSearchExpanded = true;
        if(mFullBar) {
            Menu menu = mActionBar.getMenu();
            menu.setGroupVisible(R.id.group_hide_when_searching, false);
        }

        mListener.onSearchViewChanged(true);
    }

    /**
     * Clears the search. Triggers refreshing of the directory content.
     * @return True if the default behavior of clearing/dismissing SearchView should be overridden.
     *         False otherwise.
     */
    @Override
    public boolean onClose() {
        mSearchExpanded = false;
        if (mIgnoreNextClose) {
            mIgnoreNextClose = false;
            return false;
        }

        // Refresh the directory if a search was done
        if (mCurrentSearch != null) {
            mCurrentSearch = null;
            mListener.onSearchChanged(mCurrentSearch);
        }

        if(mFullBar) {
            mMenuItem.collapseActionView();
        }
        mListener.onSearchFinished();

        mListener.onSearchViewChanged(false);

        return false;
    }

    /**
     * Called when owning activity is saving state to be used to restore state during creation.
     * @param state Bundle to save state too
     */
    public void onSaveInstanceState(Bundle state) {
        state.putString(Shared.EXTRA_QUERY, mCurrentSearch);
    }

    /**
     * Sets mSearchExpanded. Called when search icon is clicked to start search for both search view
     * modes.
     */
    @Override
    public void onClick(View v) {
        onSearchExpanded();
    }

    @Override
    public boolean onQueryTextSubmit(String query) {

        if (mCommandProcessor.accept(query)) {
            mSearchView.setQuery("", false);
        } else {
            mCurrentSearch = query;
            mSearchView.clearFocus();
            mListener.onSearchChanged(mCurrentSearch);
        }

        return true;
    }

    /**
     * Used to detect and handle back button pressed event when search is expanded.
     */
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            if (mCurrentSearch == null) {
                mSearchView.setIconified(true);
            } else if (TextUtils.isEmpty(mSearchView.getQuery())) {
                cancelSearch();
            }
        }
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        return false;
    }

    @Override
    public boolean onMenuItemActionCollapse(MenuItem item) {
        Menu menu = mActionBar.getMenu();
        menu.setGroupVisible(R.id.group_hide_when_searching, true);

        // Handles case when search view is collapsed by using the arrow on the left of the bar
        if (isExpanded() || isSearching()) {
            cancelSearch();
            return false;
        }
        return true;
    }

    @Override
    public boolean onMenuItemActionExpand(MenuItem item) {
        return true;
    }

    String getCurrentSearch() {
        return mCurrentSearch;
    }

    public boolean isSearching() {
        return mCurrentSearch != null;
    }

    public boolean isExpanded() {
        return mSearchExpanded;
    }

    public interface SearchManagerListener {
        void onSearchChanged(@Nullable String query);
        void onSearchFinished();
        void onSearchViewChanged(boolean opened);
    }
}
