/*
 * 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.example.android.common.actionbarcompat;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.util.Pair;
import android.util.SparseBooleanArray;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ListView;

import java.util.HashSet;

/**
 * Utilities for handling multiple selection in list views. Contains functionality similar to {@link
 * AbsListView#CHOICE_MODE_MULTIPLE_MODAL} which works with {@link ActionBarActivity} and
 * backward-compatible action bars.
 */
public class MultiSelectionUtil {

    /**
     * Attach a Controller to the given <code>listView</code>, <code>activity</code>
     * and <code>listener</code>.
     *
     * @param listView ListView which displays {@link android.widget.Checkable} items.
     * @param activity Activity which contains the ListView.
     * @param listener Listener that will manage the selection mode.
     * @return the attached Controller instance.
     */
    public static Controller attachMultiSelectionController(final ListView listView,
            final ActionBarActivity activity, final MultiChoiceModeListener listener) {
        return new Controller(listView, activity, listener);
    }

    /**
     * Class which provides functionality similar to {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL}
     * for the {@link ListView} provided to it. A
     * {@link android.widget.AdapterView.OnItemLongClickListener} is set on the ListView so that
     * when an item is long-clicked an ActionBarCompat Action Mode is started. Once started, a
     * {@link android.widget.AdapterView.OnItemClickListener} is set so that an item click toggles
     * that item's checked state.
     */
    public static class Controller {

        private final ListView mListView;
        private final ActionBarActivity mActivity;
        private final MultiChoiceModeListener mListener;
        private final Callbacks mCallbacks;

        // Current Action Mode (if there is one)
        private ActionMode mActionMode;

        // Keeps record of any items that should be checked on the next action mode creation
        private HashSet<Pair<Integer, Long>> mItemsToCheck;

        // Reference to the replace OnItemClickListener (so it can be restored later)
        private AdapterView.OnItemClickListener mOldItemClickListener;

        private final Runnable mSetChoiceModeNoneRunnable = new Runnable() {
            @Override
            public void run() {
                mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);
            }
        };

        private Controller(ListView listView, ActionBarActivity activity,
                MultiChoiceModeListener listener) {
            mListView = listView;
            mActivity = activity;
            mListener = listener;
            mCallbacks = new Callbacks();

            // We set ourselves as the OnItemLongClickListener so we know when to start
            // an Action Mode
            listView.setOnItemLongClickListener(mCallbacks);
        }

        /**
         * Finish the current Action Mode (if there is one).
         */
        public void finish() {
            if (mActionMode != null) {
                mActionMode.finish();
            }
        }

        /**
         * This method should be called from your {@link ActionBarActivity} or
         * {@link android.support.v4.app.Fragment Fragment} to allow the controller to restore any
         * instance state.
         *
         * @param savedInstanceState - The state passed to your Activity or Fragment.
         */
        public void restoreInstanceState(Bundle savedInstanceState) {
            if (savedInstanceState != null) {
                long[] checkedIds = savedInstanceState.getLongArray(getStateKey());
                if (checkedIds != null && checkedIds.length > 0) {
                    HashSet<Long> idsToCheckOnRestore = new HashSet<Long>();
                    for (long id : checkedIds) {
                        idsToCheckOnRestore.add(id);
                    }
                    tryRestoreInstanceState(idsToCheckOnRestore);
                }
            }
        }

        /**
         * This method should be called from
         * {@link ActionBarActivity#onSaveInstanceState(android.os.Bundle)} or
         * {@link android.support.v4.app.Fragment#onSaveInstanceState(android.os.Bundle)
         * Fragment.onSaveInstanceState(Bundle)} to allow the controller to save its instance
         * state.
         *
         * @param outState - The state passed to your Activity or Fragment.
         */
        public void saveInstanceState(Bundle outState) {
            if (mActionMode != null && mListView.getAdapter().hasStableIds()) {
                outState.putLongArray(getStateKey(), mListView.getCheckedItemIds());
            }
        }

        // Internal utility methods

        private String getStateKey() {
            return MultiSelectionUtil.class.getSimpleName() + "_" + mListView.getId();
        }

        private void tryRestoreInstanceState(HashSet<Long> idsToCheckOnRestore) {
            if (idsToCheckOnRestore == null || mListView.getAdapter() == null) {
                return;
            }

            boolean idsFound = false;
            Adapter adapter = mListView.getAdapter();
            for (int pos = adapter.getCount() - 1; pos >= 0; pos--) {
                if (idsToCheckOnRestore.contains(adapter.getItemId(pos))) {
                    idsFound = true;
                    if (mItemsToCheck == null) {
                        mItemsToCheck = new HashSet<Pair<Integer, Long>>();
                    }
                    mItemsToCheck.add(new Pair<Integer, Long>(pos, adapter.getItemId(pos)));
                }
            }

            if (idsFound) {
                // We found some IDs that were checked. Let's now restore the multi-selection
                // state.
                mActionMode = mActivity.startSupportActionMode(mCallbacks);
            }
        }

        /**
         * This class encapsulates all of the callbacks necessary for the controller class.
         */
        final class Callbacks implements ActionMode.Callback, AdapterView.OnItemClickListener,
                AdapterView.OnItemLongClickListener {

            @Override
            public final boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
                if (mListener.onCreateActionMode(actionMode, menu)) {
                    mActionMode = actionMode;
                    // Keep a reference to the existing OnItemClickListener so we can restore it
                    mOldItemClickListener = mListView.getOnItemClickListener();

                    // Set-up the ListView to emulate CHOICE_MODE_MULTIPLE_MODAL
                    mListView.setOnItemClickListener(this);
                    mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
                    mListView.removeCallbacks(mSetChoiceModeNoneRunnable);

                    // If there are some items to check, do it now
                    if (mItemsToCheck != null) {
                        for (Pair<Integer, Long> posAndId : mItemsToCheck) {
                            mListView.setItemChecked(posAndId.first, true);
                            // Notify the listener that the item has been checked
                            mListener.onItemCheckedStateChanged(mActionMode, posAndId.first,
                                    posAndId.second, true);
                        }
                    }
                    return true;
                }
                return false;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
                // Proxy listener
                return mListener.onPrepareActionMode(actionMode, menu);
            }

            @Override
            public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
                // Proxy listener
                return mListener.onActionItemClicked(actionMode, menuItem);
            }

            @Override
            public void onDestroyActionMode(ActionMode actionMode) {
                mListener.onDestroyActionMode(actionMode);

                // Clear all the checked items
                SparseBooleanArray checkedPositions = mListView.getCheckedItemPositions();
                if (checkedPositions != null) {
                    for (int i = 0; i < checkedPositions.size(); i++) {
                        mListView.setItemChecked(checkedPositions.keyAt(i), false);
                    }
                }

                // Restore the original onItemClickListener
                mListView.setOnItemClickListener(mOldItemClickListener);

                // Clear the Action Mode
                mActionMode = null;

                // Reset the ListView's Choice Mode
                mListView.post(mSetChoiceModeNoneRunnable);
            }

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                // Check to see what the new checked state is, and then notify the listener
                final boolean checked = mListView.isItemChecked(position);
                mListener.onItemCheckedStateChanged(mActionMode, position, id, checked);

                boolean hasCheckedItem = checked;

                // Check to see if we have any checked items
                if (!hasCheckedItem) {
                    SparseBooleanArray checkedItemPositions = mListView.getCheckedItemPositions();
                    if (checkedItemPositions != null) {
                        // Iterate through the SparseBooleanArray to see if there is a checked item
                        int i = 0;
                        while (!hasCheckedItem && i < checkedItemPositions.size()) {
                            hasCheckedItem = checkedItemPositions.valueAt(i++);
                        }
                    }
                }

                // If we don't have any checked items, finish the action mode
                if (!hasCheckedItem) {
                    mActionMode.finish();
                }
            }

            @Override
            public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position,
                    long id) {
                // If we already have an action mode started return false
                // (onItemClick will be called anyway)
                if (mActionMode != null) {
                    return false;
                }

                mItemsToCheck = new HashSet<Pair<Integer, Long>>();
                mItemsToCheck.add(new Pair<Integer, Long>(position, id));
                mActionMode = mActivity.startSupportActionMode(this);
                return true;
            }
        }
    }

    /**
     * @see android.widget.AbsListView.MultiChoiceModeListener
     */
    public static interface MultiChoiceModeListener extends ActionMode.Callback {

        /**
         * @see android.widget.AbsListView.MultiChoiceModeListener#onItemCheckedStateChanged(
         *android.view.ActionMode, int, long, boolean)
         */
        public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
                boolean checked);
    }
}
