/*
 * Copyright (C) 2008 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.launcher2;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.InputType;
import android.text.Selection;
import android.text.Spannable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.launcher.R;
import com.android.launcher2.FolderInfo.FolderListener;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * Represents a set of icons chosen by the user or generated by the system.
 */
public class Folder extends LinearLayout implements DragSource, View.OnClickListener,
        View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener,
        View.OnFocusChangeListener {
    private static final String TAG = "Launcher.Folder";

    protected DragController mDragController;
    protected Launcher mLauncher;
    protected FolderInfo mInfo;

    static final int STATE_NONE = -1;
    static final int STATE_SMALL = 0;
    static final int STATE_ANIMATING = 1;
    static final int STATE_OPEN = 2;

    private int mExpandDuration;
    protected CellLayout mContent;
    private final LayoutInflater mInflater;
    private final IconCache mIconCache;
    private int mState = STATE_NONE;
    private static final int REORDER_ANIMATION_DURATION = 230;
    private static final int ON_EXIT_CLOSE_DELAY = 800;
    private boolean mRearrangeOnClose = false;
    private FolderIcon mFolderIcon;
    private int mMaxCountX;
    private int mMaxCountY;
    private int mMaxNumItems;
    private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
    private Drawable mIconDrawable;
    boolean mItemsInvalidated = false;
    private ShortcutInfo mCurrentDragInfo;
    private View mCurrentDragView;
    boolean mSuppressOnAdd = false;
    private int[] mTargetCell = new int[2];
    private int[] mPreviousTargetCell = new int[2];
    private int[] mEmptyCell = new int[2];
    private Alarm mReorderAlarm = new Alarm();
    private Alarm mOnExitAlarm = new Alarm();
    private int mFolderNameHeight;
    private Rect mTempRect = new Rect();
    private boolean mDragInProgress = false;
    private boolean mDeleteFolderOnDropCompleted = false;
    private boolean mSuppressFolderDeletion = false;
    private boolean mItemAddedBackToSelfViaIcon = false;
    FolderEditText mFolderName;
    private float mFolderIconPivotX;
    private float mFolderIconPivotY;

    private boolean mIsEditingName = false;
    private InputMethodManager mInputMethodManager;

    private static String sDefaultFolderName;
    private static String sHintText;
    private ObjectAnimator mOpenCloseAnimator;

    private boolean mDestroyed;

    /**
     * Used to inflate the Workspace from XML.
     *
     * @param context The application's context.
     * @param attrs The attribtues set containing the Workspace's customization values.
     */
    public Folder(Context context, AttributeSet attrs) {
        super(context, attrs);
        setAlwaysDrawnWithCacheEnabled(false);
        mInflater = LayoutInflater.from(context);
        mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache();

        Resources res = getResources();
        mMaxCountX = res.getInteger(R.integer.folder_max_count_x);
        mMaxCountY = res.getInteger(R.integer.folder_max_count_y);
        mMaxNumItems = res.getInteger(R.integer.folder_max_num_items);
        if (mMaxCountX < 0 || mMaxCountY < 0 || mMaxNumItems < 0) {
            mMaxCountX = LauncherModel.getCellCountX();
            mMaxCountY = LauncherModel.getCellCountY();
            mMaxNumItems = mMaxCountX * mMaxCountY;
        }

        mInputMethodManager = (InputMethodManager)
                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

        mExpandDuration = res.getInteger(R.integer.config_folderAnimDuration);

        if (sDefaultFolderName == null) {
            sDefaultFolderName = res.getString(R.string.folder_name);
        }
        if (sHintText == null) {
            sHintText = res.getString(R.string.folder_hint_text);
        }
        mLauncher = (Launcher) context;
        // We need this view to be focusable in touch mode so that when text editing of the folder
        // name is complete, we have something to focus on, thus hiding the cursor and giving
        // reliable behvior when clicking the text field (since it will always gain focus on click).
        setFocusableInTouchMode(true);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mContent = (CellLayout) findViewById(R.id.folder_content);
        mContent.setGridSize(0, 0);
        mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
        mFolderName = (FolderEditText) findViewById(R.id.folder_name);
        mFolderName.setFolder(this);
        mFolderName.setOnFocusChangeListener(this);

        // We find out how tall the text view wants to be (it is set to wrap_content), so that
        // we can allocate the appropriate amount of space for it.
        int measureSpec = MeasureSpec.UNSPECIFIED;
        mFolderName.measure(measureSpec, measureSpec);
        mFolderNameHeight = mFolderName.getMeasuredHeight();

        // We disable action mode for now since it messes up the view on phones
        mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
        mFolderName.setOnEditorActionListener(this);
        mFolderName.setSelectAllOnFocus(true);
        mFolderName.setInputType(mFolderName.getInputType() |
                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
    }

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }

        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }
    };

    public void onClick(View v) {
        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            // refactor this code from Folder
            ShortcutInfo item = (ShortcutInfo) tag;
            int[] pos = new int[2];
            v.getLocationOnScreen(pos);
            item.intent.setSourceBounds(new Rect(pos[0], pos[1],
                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));

            mLauncher.startActivitySafely(v, item.intent, item);
        }
    }

    public boolean onLongClick(View v) {
        // Return if global dragging is not enabled
        if (!mLauncher.isDraggingEnabled()) return true;

        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            ShortcutInfo item = (ShortcutInfo) tag;
            if (!v.isInTouchMode()) {
                return false;
            }

            mLauncher.dismissFolderCling(null);

            mLauncher.getWorkspace().onDragStartedWithItem(v);
            mLauncher.getWorkspace().beginDragShared(v, this);
            mIconDrawable = ((TextView) v).getCompoundDrawables()[1];

            mCurrentDragInfo = item;
            mEmptyCell[0] = item.cellX;
            mEmptyCell[1] = item.cellY;
            mCurrentDragView = v;

            mContent.removeView(mCurrentDragView);
            mInfo.remove(mCurrentDragInfo);
            mDragInProgress = true;
            mItemAddedBackToSelfViaIcon = false;
        }
        return true;
    }

    public boolean isEditingName() {
        return mIsEditingName;
    }

    public void startEditingFolderName() {
        mFolderName.setHint("");
        mIsEditingName = true;
    }

    public void dismissEditingName() {
        mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        doneEditingFolderName(true);
    }

    public void doneEditingFolderName(boolean commit) {
        mFolderName.setHint(sHintText);
        // Convert to a string here to ensure that no other state associated with the text field
        // gets saved.
        String newTitle = mFolderName.getText().toString();
        mInfo.setTitle(newTitle);
        LauncherModel.updateItemInDatabase(mLauncher, mInfo);

        if (commit) {
            sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                    String.format(getContext().getString(R.string.folder_renamed), newTitle));
        }
        // In order to clear the focus from the text field, we set the focus on ourself. This
        // ensures that every time the field is clicked, focus is gained, giving reliable behavior.
        requestFocus();

        Selection.setSelection((Spannable) mFolderName.getText(), 0, 0);
        mIsEditingName = false;
    }

    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            dismissEditingName();
            return true;
        }
        return false;
    }

    public View getEditTextRegion() {
        return mFolderName;
    }

    public Drawable getDragDrawable() {
        return mIconDrawable;
    }

    /**
     * We need to handle touch events to prevent them from falling through to the workspace below.
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    public void setDragController(DragController dragController) {
        mDragController = dragController;
    }

    void setFolderIcon(FolderIcon icon) {
        mFolderIcon = icon;
    }

    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        // When the folder gets focus, we don't want to announce the list of items.
        return true;
    }

    /**
     * @return the FolderInfo object associated with this folder
     */
    FolderInfo getInfo() {
        return mInfo;
    }

    private class GridComparator implements Comparator<ShortcutInfo> {
        int mNumCols;
        public GridComparator(int numCols) {
            mNumCols = numCols;
        }

        @Override
        public int compare(ShortcutInfo lhs, ShortcutInfo rhs) {
            int lhIndex = lhs.cellY * mNumCols + lhs.cellX;
            int rhIndex = rhs.cellY * mNumCols + rhs.cellX;
            return (lhIndex - rhIndex);
        }
    }

    private void placeInReadingOrder(ArrayList<ShortcutInfo> items) {
        int maxX = 0;
        int count = items.size();
        for (int i = 0; i < count; i++) {
            ShortcutInfo item = items.get(i);
            if (item.cellX > maxX) {
                maxX = item.cellX;
            }
        }

        GridComparator gridComparator = new GridComparator(maxX + 1);
        Collections.sort(items, gridComparator);
        final int countX = mContent.getCountX();
        for (int i = 0; i < count; i++) {
            int x = i % countX;
            int y = i / countX;
            ShortcutInfo item = items.get(i);
            item.cellX = x;
            item.cellY = y;
        }
    }

    void bind(FolderInfo info) {
        mInfo = info;
        ArrayList<ShortcutInfo> children = info.contents;
        ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
        setupContentForNumItems(children.size());
        placeInReadingOrder(children);
        int count = 0;
        for (int i = 0; i < children.size(); i++) {
            ShortcutInfo child = (ShortcutInfo) children.get(i);
            if (!createAndAddShortcut(child)) {
                overflow.add(child);
            } else {
                count++;
            }
        }

        // We rearrange the items in case there are any empty gaps
        setupContentForNumItems(count);

        // If our folder has too many items we prune them from the list. This is an issue 
        // when upgrading from the old Folders implementation which could contain an unlimited
        // number of items.
        for (ShortcutInfo item: overflow) {
            mInfo.remove(item);
            LauncherModel.deleteItemFromDatabase(mLauncher, item);
        }

        mItemsInvalidated = true;
        updateTextViewFocus();
        mInfo.addListener(this);

        if (!sDefaultFolderName.contentEquals(mInfo.title)) {
            mFolderName.setText(mInfo.title);
        } else {
            mFolderName.setText("");
        }
        updateItemLocationsInDatabase();
    }

    /**
     * Creates a new UserFolder, inflated from R.layout.user_folder.
     *
     * @param context The application's context.
     *
     * @return A new UserFolder.
     */
    static Folder fromXml(Context context) {
        return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
    }

    /**
     * This method is intended to make the UserFolder to be visually identical in size and position
     * to its associated FolderIcon. This allows for a seamless transition into the expanded state.
     */
    private void positionAndSizeAsIcon() {
        if (!(getParent() instanceof DragLayer)) return;
        setScaleX(0.8f);
        setScaleY(0.8f);
        setAlpha(0f);
        mState = STATE_SMALL;
    }

    public void animateOpen() {
        positionAndSizeAsIcon();

        if (!(getParent() instanceof DragLayer)) return;
        centerAboutIcon();
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
        final ObjectAnimator oa = mOpenCloseAnimator =
            LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);

        oa.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                        String.format(getContext().getString(R.string.folder_opened),
                        mContent.getCountX(), mContent.getCountY()));
                mState = STATE_ANIMATING;
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                mState = STATE_OPEN;
                setLayerType(LAYER_TYPE_NONE, null);
                Cling cling = mLauncher.showFirstRunFoldersCling();
                if (cling != null) {
                    cling.bringToFront();
                }
                setFocusOnFirstChild();
            }
        });
        oa.setDuration(mExpandDuration);
        setLayerType(LAYER_TYPE_HARDWARE, null);
        buildLayer();
        post(new Runnable() {
            public void run() {
                // Check if the animator changed in the meantime
                if (oa != mOpenCloseAnimator)
                    return;
                oa.start();
            }
        });
    }

    private void sendCustomAccessibilityEvent(int type, String text) {
        AccessibilityManager accessibilityManager = (AccessibilityManager)
                getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (accessibilityManager.isEnabled()) {
            AccessibilityEvent event = AccessibilityEvent.obtain(type);
            onInitializeAccessibilityEvent(event);
            event.getText().add(text);
            accessibilityManager.sendAccessibilityEvent(event);
        }
    }

    private void setFocusOnFirstChild() {
        View firstChild = mContent.getChildAt(0, 0);
        if (firstChild != null) {
            firstChild.requestFocus();
        }
    }

    public void animateClosed() {
        if (!(getParent() instanceof DragLayer)) return;
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f);
        final ObjectAnimator oa = mOpenCloseAnimator =
                LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);

        oa.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                onCloseComplete();
                setLayerType(LAYER_TYPE_NONE, null);
                mState = STATE_SMALL;
            }
            @Override
            public void onAnimationStart(Animator animation) {
                sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                        getContext().getString(R.string.folder_closed));
                mState = STATE_ANIMATING;
            }
        });
        oa.setDuration(mExpandDuration);
        setLayerType(LAYER_TYPE_HARDWARE, null);
        buildLayer();
        post(new Runnable() {
            public void run() {
                // Check if the animator changed in the meantime
                if (oa != mOpenCloseAnimator)
                    return;
                oa.start();
            }
        });
    }

    void notifyDataSetChanged() {
        // recreate all the children if the data set changes under us. We may want to do this more
        // intelligently (ie just removing the views that should no longer exist)
        mContent.removeAllViewsInLayout();
        bind(mInfo);
    }

    public boolean acceptDrop(DragObject d) {
        final ItemInfo item = (ItemInfo) d.dragInfo;
        final int itemType = item.itemType;
        return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
                    itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
                    !isFull());
    }

    protected boolean findAndSetEmptyCells(ShortcutInfo item) {
        int[] emptyCell = new int[2];
        if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
            item.cellX = emptyCell[0];
            item.cellY = emptyCell[1];
            return true;
        } else {
            return false;
        }
    }

    protected boolean createAndAddShortcut(ShortcutInfo item) {
        final TextView textView =
            (TextView) mInflater.inflate(R.layout.application, this, false);
        textView.setCompoundDrawablesWithIntrinsicBounds(null,
                new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
        textView.setText(item.title);
        textView.setTag(item);

        textView.setOnClickListener(this);
        textView.setOnLongClickListener(this);

        // We need to check here to verify that the given item's location isn't already occupied
        // by another item.
        if (mContent.getChildAt(item.cellX, item.cellY) != null || item.cellX < 0 || item.cellY < 0
                || item.cellX >= mContent.getCountX() || item.cellY >= mContent.getCountY()) {
            // This shouldn't happen, log it. 
            Log.e(TAG, "Folder order not properly persisted during bind");
            if (!findAndSetEmptyCells(item)) {
                return false;
            }
        }

        CellLayout.LayoutParams lp =
            new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
        boolean insert = false;
        textView.setOnKeyListener(new FolderKeyEventListener());
        mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
        return true;
    }

    public void onDragEnter(DragObject d) {
        mPreviousTargetCell[0] = -1;
        mPreviousTargetCell[1] = -1;
        mOnExitAlarm.cancelAlarm();
    }

    OnAlarmListener mReorderAlarmListener = new OnAlarmListener() {
        public void onAlarm(Alarm alarm) {
            realTimeReorder(mEmptyCell, mTargetCell);
        }
    };

    boolean readingOrderGreaterThan(int[] v1, int[] v2) {
        if (v1[1] > v2[1] || (v1[1] == v2[1] && v1[0] > v2[0])) {
            return true;
        } else {
            return false;
        }
    }

    private void realTimeReorder(int[] empty, int[] target) {
        boolean wrap;
        int startX;
        int endX;
        int startY;
        int delay = 0;
        float delayAmount = 30;
        if (readingOrderGreaterThan(target, empty)) {
            wrap = empty[0] >= mContent.getCountX() - 1;
            startY = wrap ? empty[1] + 1 : empty[1];
            for (int y = startY; y <= target[1]; y++) {
                startX = y == empty[1] ? empty[0] + 1 : 0;
                endX = y < target[1] ? mContent.getCountX() - 1 : target[0];
                for (int x = startX; x <= endX; x++) {
                    View v = mContent.getChildAt(x,y);
                    if (mContent.animateChildToPosition(v, empty[0], empty[1],
                            REORDER_ANIMATION_DURATION, delay, true, true)) {
                        empty[0] = x;
                        empty[1] = y;
                        delay += delayAmount;
                        delayAmount *= 0.9;
                    }
                }
            }
        } else {
            wrap = empty[0] == 0;
            startY = wrap ? empty[1] - 1 : empty[1];
            for (int y = startY; y >= target[1]; y--) {
                startX = y == empty[1] ? empty[0] - 1 : mContent.getCountX() - 1;
                endX = y > target[1] ? 0 : target[0];
                for (int x = startX; x >= endX; x--) {
                    View v = mContent.getChildAt(x,y);
                    if (mContent.animateChildToPosition(v, empty[0], empty[1],
                            REORDER_ANIMATION_DURATION, delay, true, true)) {
                        empty[0] = x;
                        empty[1] = y;
                        delay += delayAmount;
                        delayAmount *= 0.9;
                    }
                }
            }
        }
    }

    public void onDragOver(DragObject d) {
        float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView, null);
        mTargetCell = mContent.findNearestArea((int) r[0], (int) r[1], 1, 1, mTargetCell);

        if (mTargetCell[0] != mPreviousTargetCell[0] || mTargetCell[1] != mPreviousTargetCell[1]) {
            mReorderAlarm.cancelAlarm();
            mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
            mReorderAlarm.setAlarm(150);
            mPreviousTargetCell[0] = mTargetCell[0];
            mPreviousTargetCell[1] = mTargetCell[1];
        }
    }

    // This is used to compute the visual center of the dragView. The idea is that
    // the visual center represents the user's interpretation of where the item is, and hence
    // is the appropriate point to use when determining drop location.
    private float[] getDragViewVisualCenter(int x, int y, int xOffset, int yOffset,
            DragView dragView, float[] recycle) {
        float res[];
        if (recycle == null) {
            res = new float[2];
        } else {
            res = recycle;
        }

        // These represent the visual top and left of drag view if a dragRect was provided.
        // If a dragRect was not provided, then they correspond to the actual view left and
        // top, as the dragRect is in that case taken to be the entire dragView.
        // R.dimen.dragViewOffsetY.
        int left = x - xOffset;
        int top = y - yOffset;

        // In order to find the visual center, we shift by half the dragRect
        res[0] = left + dragView.getDragRegion().width() / 2;
        res[1] = top + dragView.getDragRegion().height() / 2;

        return res;
    }

    OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() {
        public void onAlarm(Alarm alarm) {
            completeDragExit();
        }
    };

    public void completeDragExit() {
        mLauncher.closeFolder();
        mCurrentDragInfo = null;
        mCurrentDragView = null;
        mSuppressOnAdd = false;
        mRearrangeOnClose = true;
    }

    public void onDragExit(DragObject d) {
        // We only close the folder if this is a true drag exit, ie. not because a drop
        // has occurred above the folder.
        if (!d.dragComplete) {
            mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener);
            mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY);
        }
        mReorderAlarm.cancelAlarm();
    }

    public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
            boolean success) {
        if (success) {
            if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon) {
                replaceFolderWithFinalItem();
            }
        } else {
            // The drag failed, we need to return the item to the folder
            mFolderIcon.onDrop(d);

            // We're going to trigger a "closeFolder" which may occur before this item has
            // been added back to the folder -- this could cause the folder to be deleted
            if (mOnExitAlarm.alarmPending()) {
                mSuppressFolderDeletion = true;
            }
        }

        if (target != this) {
            if (mOnExitAlarm.alarmPending()) {
                mOnExitAlarm.cancelAlarm();
                completeDragExit();
            }
        }
        mDeleteFolderOnDropCompleted = false;
        mDragInProgress = false;
        mItemAddedBackToSelfViaIcon = false;
        mCurrentDragInfo = null;
        mCurrentDragView = null;
        mSuppressOnAdd = false;

        // Reordering may have occured, and we need to save the new item locations. We do this once
        // at the end to prevent unnecessary database operations.
        updateItemLocationsInDatabase();
    }

    @Override
    public boolean supportsFlingToDelete() {
        return true;
    }

    public void onFlingToDelete(DragObject d, int x, int y, PointF vec) {
        // Do nothing
    }

    @Override
    public void onFlingToDeleteCompleted() {
        // Do nothing
    }

    private void updateItemLocationsInDatabase() {
        ArrayList<View> list = getItemsInReadingOrder();
        for (int i = 0; i < list.size(); i++) {
            View v = list.get(i);
            ItemInfo info = (ItemInfo) v.getTag();
            LauncherModel.moveItemInDatabase(mLauncher, info, mInfo.id, 0,
                        info.cellX, info.cellY);
        }
    }

    public void notifyDrop() {
        if (mDragInProgress) {
            mItemAddedBackToSelfViaIcon = true;
        }
    }

    public boolean isDropEnabled() {
        return true;
    }

    public DropTarget getDropTargetDelegate(DragObject d) {
        return null;
    }

    private void setupContentDimensions(int count) {
        ArrayList<View> list = getItemsInReadingOrder();

        int countX = mContent.getCountX();
        int countY = mContent.getCountY();
        boolean done = false;

        while (!done) {
            int oldCountX = countX;
            int oldCountY = countY;
            if (countX * countY < count) {
                // Current grid is too small, expand it
                if ((countX <= countY || countY == mMaxCountY) && countX < mMaxCountX) {
                    countX++;
                } else if (countY < mMaxCountY) {
                    countY++;
                }
                if (countY == 0) countY++;
            } else if ((countY - 1) * countX >= count && countY >= countX) {
                countY = Math.max(0, countY - 1);
            } else if ((countX - 1) * countY >= count) {
                countX = Math.max(0, countX - 1);
            }
            done = countX == oldCountX && countY == oldCountY;
        }
        mContent.setGridSize(countX, countY);
        arrangeChildren(list);
    }

    public boolean isFull() {
        return getItemCount() >= mMaxNumItems;
    }

    private void centerAboutIcon() {
        DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();

        int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
        int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight()
                + mFolderNameHeight;
        DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);

        float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect);

        int centerX = (int) (mTempRect.left + mTempRect.width() * scale / 2);
        int centerY = (int) (mTempRect.top + mTempRect.height() * scale / 2);
        int centeredLeft = centerX - width / 2;
        int centeredTop = centerY - height / 2;

        int currentPage = mLauncher.getWorkspace().getCurrentPage();
        // In case the workspace is scrolling, we need to use the final scroll to compute
        // the folders bounds.
        mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage);
        // We first fetch the currently visible CellLayoutChildren
        CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage);
        ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets();
        Rect bounds = new Rect();
        parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);
        // We reset the workspaces scroll
        mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage);

        // We need to bound the folder to the currently visible CellLayoutChildren
        int left = Math.min(Math.max(bounds.left, centeredLeft),
                bounds.left + bounds.width() - width);
        int top = Math.min(Math.max(bounds.top, centeredTop),
                bounds.top + bounds.height() - height);
        // If the folder doesn't fit within the bounds, center it about the desired bounds
        if (width >= bounds.width()) {
            left = bounds.left + (bounds.width() - width) / 2;
        }
        if (height >= bounds.height()) {
            top = bounds.top + (bounds.height() - height) / 2;
        }

        int folderPivotX = width / 2 + (centeredLeft - left);
        int folderPivotY = height / 2 + (centeredTop - top);
        setPivotX(folderPivotX);
        setPivotY(folderPivotY);
        mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
                (1.0f * folderPivotX / width));
        mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
                (1.0f * folderPivotY / height));

        lp.width = width;
        lp.height = height;
        lp.x = left;
        lp.y = top;
    }

    float getPivotXForIconAnimation() {
        return mFolderIconPivotX;
    }
    float getPivotYForIconAnimation() {
        return mFolderIconPivotY;
    }

    private void setupContentForNumItems(int count) {
        setupContentDimensions(count);

        DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
        if (lp == null) {
            lp = new DragLayer.LayoutParams(0, 0);
            lp.customPosition = true;
            setLayoutParams(lp);
        }
        centerAboutIcon();
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
        int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight()
                + mFolderNameHeight;

        int contentWidthSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(),
                MeasureSpec.EXACTLY);
        int contentHeightSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredHeight(),
                MeasureSpec.EXACTLY);
        mContent.measure(contentWidthSpec, contentHeightSpec);

        mFolderName.measure(contentWidthSpec,
                MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY));
        setMeasuredDimension(width, height);
    }

    private void arrangeChildren(ArrayList<View> list) {
        int[] vacant = new int[2];
        if (list == null) {
            list = getItemsInReadingOrder();
        }
        mContent.removeAllViews();

        for (int i = 0; i < list.size(); i++) {
            View v = list.get(i);
            mContent.getVacantCell(vacant, 1, 1);
            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
            lp.cellX = vacant[0];
            lp.cellY = vacant[1];
            ItemInfo info = (ItemInfo) v.getTag();
            if (info.cellX != vacant[0] || info.cellY != vacant[1]) {
                info.cellX = vacant[0];
                info.cellY = vacant[1];
                LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
                        info.cellX, info.cellY);
            }
            boolean insert = false;
            mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true);
        }
        mItemsInvalidated = true;
    }

    public int getItemCount() {
        return mContent.getShortcutsAndWidgets().getChildCount();
    }

    public View getItemAt(int index) {
        return mContent.getShortcutsAndWidgets().getChildAt(index);
    }

    private void onCloseComplete() {
        DragLayer parent = (DragLayer) getParent();
        if (parent != null) {
            parent.removeView(this);
        }
        mDragController.removeDropTarget((DropTarget) this);
        clearFocus();
        mFolderIcon.requestFocus();

        if (mRearrangeOnClose) {
            setupContentForNumItems(getItemCount());
            mRearrangeOnClose = false;
        }
        if (getItemCount() <= 1) {
            if (!mDragInProgress && !mSuppressFolderDeletion) {
                replaceFolderWithFinalItem();
            } else if (mDragInProgress) {
                mDeleteFolderOnDropCompleted = true;
            }
        }
        mSuppressFolderDeletion = false;
    }

    private void replaceFolderWithFinalItem() {
        // Add the last remaining child to the workspace in place of the folder
        Runnable onCompleteRunnable = new Runnable() {
            @Override
            public void run() {
                CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen);

               View child = null;
                // Move the item from the folder to the workspace, in the position of the folder
                if (getItemCount() == 1) {
                    ShortcutInfo finalItem = mInfo.contents.get(0);
                    child = mLauncher.createShortcut(R.layout.application, cellLayout,
                            finalItem);
                    LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container,
                            mInfo.screen, mInfo.cellX, mInfo.cellY);
                }
                if (getItemCount() <= 1) {
                    // Remove the folder
                    LauncherModel.deleteItemFromDatabase(mLauncher, mInfo);
                    cellLayout.removeView(mFolderIcon);
                    if (mFolderIcon instanceof DropTarget) {
                        mDragController.removeDropTarget((DropTarget) mFolderIcon);
                    }
                    mLauncher.removeFolder(mInfo);
                }
                // We add the child after removing the folder to prevent both from existing at
                // the same time in the CellLayout.
                if (child != null) {
                    mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen,
                            mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY);
                }
            }
        };
        View finalChild = getItemAt(0);
        if (finalChild != null) {
            mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable);
        }
        mDestroyed = true;
    }

    boolean isDestroyed() {
        return mDestroyed;
    }

    // This method keeps track of the last item in the folder for the purposes
    // of keyboard focus
    private void updateTextViewFocus() {
        View lastChild = getItemAt(getItemCount() - 1);
        getItemAt(getItemCount() - 1);
        if (lastChild != null) {
            mFolderName.setNextFocusDownId(lastChild.getId());
            mFolderName.setNextFocusRightId(lastChild.getId());
            mFolderName.setNextFocusLeftId(lastChild.getId());
            mFolderName.setNextFocusUpId(lastChild.getId());
        }
    }

    public void onDrop(DragObject d) {
        ShortcutInfo item;
        if (d.dragInfo instanceof ApplicationInfo) {
            // Came from all apps -- make a copy
            item = ((ApplicationInfo) d.dragInfo).makeShortcut();
            item.spanX = 1;
            item.spanY = 1;
        } else {
            item = (ShortcutInfo) d.dragInfo;
        }
        // Dragged from self onto self, currently this is the only path possible, however
        // we keep this as a distinct code path.
        if (item == mCurrentDragInfo) {
            ShortcutInfo si = (ShortcutInfo) mCurrentDragView.getTag();
            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mCurrentDragView.getLayoutParams();
            si.cellX = lp.cellX = mEmptyCell[0];
            si.cellX = lp.cellY = mEmptyCell[1];
            mContent.addViewToCellLayout(mCurrentDragView, -1, (int)item.id, lp, true);
            if (d.dragView.hasDrawn()) {
                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, mCurrentDragView);
            } else {
                d.deferDragViewCleanupPostAnimation = false;
                mCurrentDragView.setVisibility(VISIBLE);
            }
            mItemsInvalidated = true;
            setupContentDimensions(getItemCount());
            mSuppressOnAdd = true;
        }
        mInfo.add(item);
    }

    public void onAdd(ShortcutInfo item) {
        mItemsInvalidated = true;
        // If the item was dropped onto this open folder, we have done the work associated
        // with adding the item to the folder, as indicated by mSuppressOnAdd being set
        if (mSuppressOnAdd) return;
        if (!findAndSetEmptyCells(item)) {
            // The current layout is full, can we expand it?
            setupContentForNumItems(getItemCount() + 1);
            findAndSetEmptyCells(item);
        }
        createAndAddShortcut(item);
        LauncherModel.addOrMoveItemInDatabase(
                mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
    }

    public void onRemove(ShortcutInfo item) {
        mItemsInvalidated = true;
        // If this item is being dragged from this open folder, we have already handled
        // the work associated with removing the item, so we don't have to do anything here.
        if (item == mCurrentDragInfo) return;
        View v = getViewForInfo(item);
        mContent.removeView(v);
        if (mState == STATE_ANIMATING) {
            mRearrangeOnClose = true;
        } else {
            setupContentForNumItems(getItemCount());
        }
        if (getItemCount() <= 1) {
            replaceFolderWithFinalItem();
        }
    }

    private View getViewForInfo(ShortcutInfo item) {
        for (int j = 0; j < mContent.getCountY(); j++) {
            for (int i = 0; i < mContent.getCountX(); i++) {
                View v = mContent.getChildAt(i, j);
                if (v.getTag() == item) {
                    return v;
                }
            }
        }
        return null;
    }

    public void onItemsChanged() {
        updateTextViewFocus();
    }

    public void onTitleChanged(CharSequence title) {
    }

    public ArrayList<View> getItemsInReadingOrder() {
        return getItemsInReadingOrder(true);
    }

    public ArrayList<View> getItemsInReadingOrder(boolean includeCurrentDragItem) {
        if (mItemsInvalidated) {
            mItemsInReadingOrder.clear();
            for (int j = 0; j < mContent.getCountY(); j++) {
                for (int i = 0; i < mContent.getCountX(); i++) {
                    View v = mContent.getChildAt(i, j);
                    if (v != null) {
                        ShortcutInfo info = (ShortcutInfo) v.getTag();
                        if (info != mCurrentDragInfo || includeCurrentDragItem) {
                            mItemsInReadingOrder.add(v);
                        }
                    }
                }
            }
            mItemsInvalidated = false;
        }
        return mItemsInReadingOrder;
    }

    public void getLocationInDragLayer(int[] loc) {
        mLauncher.getDragLayer().getLocationInDragLayer(this, loc);
    }

    public void onFocusChange(View v, boolean hasFocus) {
        if (v == mFolderName && hasFocus) {
            startEditingFolderName();
        }
    }
}
