package com.android.launcher3.shortcuts;

import android.animation.Animator;
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;

import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LogDecelerateInterpolator;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.UiThreadCircularReveal;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * A container for shortcuts to deep links within apps.
 */
@TargetApi(Build.VERSION_CODES.N)
public class DeepShortcutsContainer extends LinearLayout implements View.OnLongClickListener,
        View.OnTouchListener, DragSource, DragController.DragListener,
        UserEventDispatcher.LaunchSourceProvider {
    private static final String TAG = "ShortcutsContainer";

    private Launcher mLauncher;
    private DeepShortcutManager mDeepShortcutsManager;
    private final int mDragDeadzone;
    private final int mStartDragThreshold;
    private BubbleTextView mDeferredDragIcon;
    private int mActivePointerId;
    private Point mTouchDown = null;
    private DragView mDragView;
    private float mLastX, mLastY;
    private float mDistanceDragged = 0;
    private final Rect mTempRect = new Rect();
    private final int[] mTempXY = new int[2];
    private Point mIconLastTouchPos = new Point();
    private boolean mIsLeftAligned;
    private boolean mIsAboveIcon;

    /**
     * Sorts shortcuts in rank order, with manifest shortcuts coming before dynamic shortcuts.
     */
    private static final Comparator<ShortcutInfoCompat> sShortcutsComparator
            = new Comparator<ShortcutInfoCompat>() {
        @Override
        public int compare(ShortcutInfoCompat a, ShortcutInfoCompat b) {
            if (a.isDeclaredInManifest() && !b.isDeclaredInManifest()) {
                return -1;
            }
            if (!a.isDeclaredInManifest() && b.isDeclaredInManifest()) {
                return 1;
            }
            return Integer.compare(a.getRank(), b.getRank());
        }
    };

    private static final Comparator<ShortcutInfoCompat> sShortcutsComparatorReversed
            = Collections.reverseOrder(sShortcutsComparator);

    public DeepShortcutsContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mLauncher = (Launcher) context;
        mDeepShortcutsManager = LauncherAppState.getInstance().getShortcutManager();

        mDragDeadzone = ViewConfiguration.get(context).getScaledTouchSlop();
        mStartDragThreshold = getResources().getDimensionPixelSize(
                R.dimen.deep_shortcuts_start_drag_threshold);
    }

    public DeepShortcutsContainer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DeepShortcutsContainer(Context context) {
        this(context, null, 0);
    }

    public void populateAndShow(final BubbleTextView originalIcon, final List<String> ids) {
        // Add dummy views first, and populate with real shortcut info when ready.
        for (int i = 0; i < ids.size(); i++) {
            final DeepShortcutView shortcut = (DeepShortcutView)
                    mLauncher.getLayoutInflater().inflate(R.layout.deep_shortcut, this, false);
            if (i < ids.size() - 1) {
                ((LayoutParams) shortcut.getLayoutParams()).bottomMargin = shortcut.getSpacing();
            }
            addView(shortcut);
        }

        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        animateOpen(originalIcon);

        deferDrag(originalIcon);

        // Load the shortcuts on a background thread and update the container as it animates.
        final Looper workerLooper = LauncherModel.getWorkerLooper();
        final Handler uiHandler = new Handler(Looper.getMainLooper());
        final ItemInfo originalInfo = (ItemInfo) originalIcon.getTag();
        final UserHandleCompat user = originalInfo.user;
        final ComponentName activity = originalInfo.getTargetComponent();
        new Handler(workerLooper).postAtFrontOfQueue(new Runnable() {
            @Override
            public void run() {
                final List<ShortcutInfoCompat> shortcuts = mDeepShortcutsManager
                        .queryForShortcutsContainer(activity, ids, user);
                // We want the lowest rank to be closest to the user's finger.
                final Comparator<ShortcutInfoCompat> shortcutsComparator = mIsAboveIcon ?
                        sShortcutsComparatorReversed : sShortcutsComparator;
                Collections.sort(shortcuts, shortcutsComparator);
                for (int i = 0; i < shortcuts.size(); i++) {
                    final ShortcutInfoCompat shortcut = shortcuts.get(i);
                    final ShortcutInfo launcherShortcutInfo = ShortcutInfo
                            .fromDeepShortcutInfo(shortcut, mLauncher);
                    CharSequence label = shortcut.getLongLabel();
                    if (TextUtils.isEmpty(label)) {
                        label = shortcut.getShortLabel();
                    }
                    uiHandler.post(new UpdateShortcutChild(i, launcherShortcutInfo, label));
                }
            }
        });
    }

    /** Updates the child of this container at the given index based on the given shortcut info. */
    private class UpdateShortcutChild implements Runnable {
        private int mShortcutChildIndex;
        private ShortcutInfo mShortcutChildInfo;
        private CharSequence mLabel;

        public UpdateShortcutChild(int shortcutChildIndex, ShortcutInfo shortcutChildInfo,
                CharSequence label) {
            mShortcutChildIndex = shortcutChildIndex;
            mShortcutChildInfo = shortcutChildInfo;
            mLabel = label;
        }

        @Override
        public void run() {
            DeepShortcutView shortcutView = (DeepShortcutView) getChildAt(mShortcutChildIndex);
            shortcutView.applyFromShortcutInfo(mShortcutChildInfo,
                    LauncherAppState.getInstance().getIconCache());
            shortcutView.setText(mLabel);
            shortcutView.setOnClickListener(mLauncher);
            shortcutView.setOnLongClickListener(DeepShortcutsContainer.this);
            shortcutView.setOnTouchListener(DeepShortcutsContainer.this);
        }
    }

    // TODO: update this animation
    private void animateOpen(BubbleTextView originalIcon) {
        orientAboutIcon(originalIcon);

        setVisibility(View.VISIBLE);
        int rx = (int) Math.max(Math.max(getMeasuredWidth() - getPivotX(), 0), getPivotX());
        int ry = (int) Math.max(Math.max(getMeasuredHeight() - getPivotY(), 0), getPivotY());
        float radius = (float) Math.hypot(rx, ry);
        Animator reveal = UiThreadCircularReveal.createCircularReveal(this, (int) getPivotX(),
                (int) getPivotY(), 0, radius);
        reveal.setDuration(getResources().getInteger(R.integer.config_materialFolderExpandDuration));
        reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));
        reveal.start();
    }

    /**
     * Orients this container above or below the given icon, aligning with the left or right.
     *
     * These are the preferred orientations, in order:
     * - Above and left-aligned
     * - Above and right-aligned
     * - Below and left-aligned
     * - Below and right-aligned
     *
     * So we always align left if there is enough horizontal space
     * and align above if there is enough vertical space.
     *
     * TODO: draw pointer based on orientation.
     */
    private void orientAboutIcon(BubbleTextView icon) {
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        DragLayer dragLayer = mLauncher.getDragLayer();
        dragLayer.getDescendantRectRelativeToSelf(icon, mTempRect);
        // Align left and above by default.
        int x = mTempRect.left + icon.getPaddingLeft();
        int y = mTempRect.top - height;
        Rect insets = dragLayer.getInsets();

        mIsLeftAligned = x + width < dragLayer.getRight() - insets.right;
        if (!mIsLeftAligned) {
            x = mTempRect.right - width - icon.getPaddingRight();
        }

        mIsAboveIcon = mTempRect.top - height > dragLayer.getTop() + insets.top;
        if (!mIsAboveIcon) {
            y = mTempRect.bottom;
        }

        setPivotX(width / 2);
        setPivotY(height / 2);

        // Insets are added later, so subtract them now.
        y -= insets.top;

        setX(x);
        setY(y);
    }

    private void deferDrag(BubbleTextView originalIcon) {
        mDeferredDragIcon = originalIcon;
        showDragView(originalIcon);
        mLauncher.getDragController().addDragListener(this);
    }

    public BubbleTextView getDeferredDragIcon() {
        return mDeferredDragIcon;
    }

    private void showDragView(BubbleTextView originalIcon) {
        // TODO: implement support for Drawable DragViews so we don't have to create a bitmap here.
        Bitmap b = Utilities.createIconBitmap(originalIcon.getIcon(), mLauncher);
        float scale = mLauncher.getDragLayer().getLocationInDragLayer(originalIcon, mTempXY);
        int dragLayerX = Math.round(mTempXY[0] - (b.getWidth() - scale * originalIcon.getWidth()) / 2);
        int dragLayerY = Math.round(mTempXY[1] - (b.getHeight() - scale * b.getHeight()) / 2
                - Workspace.DRAG_BITMAP_PADDING / 2) + originalIcon.getPaddingTop();
        int motionDownX = mLauncher.getDragController().getMotionDown().x;
        int motionDownY = mLauncher.getDragController().getMotionDown().y;
        final int registrationX = motionDownX - dragLayerX;
        final int registrationY = motionDownY - dragLayerY;

        float scaleDps = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_drag_view_scale);
        mDragView = new DragView(mLauncher, b, registrationX, registrationY,
                0, 0, b.getWidth(), b.getHeight(), 1f, scaleDps);
        mLastX = mLastY = mDistanceDragged = 0;
        mDragView.show(motionDownX, motionDownY);
    }

    public boolean onForwardedEvent(MotionEvent ev, int activePointerId, Point touchDown) {
        mActivePointerId = activePointerId;
        mTouchDown = touchDown;
        return dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mDeferredDragIcon == null) {
            return false;
        }

        final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
        if (activePointerIndex < 0) {
            return false;
        }
        final float x = ev.getX(activePointerIndex);
        final float y = ev.getY(activePointerIndex);


        int action = ev.getAction();
        // The event was in this container's coordinate system before this,
        // but will be in DragLayer's coordinate system from now on.
        Utilities.translateEventCoordinates(this, mLauncher.getDragLayer(), ev);
        final int dragLayerX = (int) ev.getX();
        final int dragLayerY = (int) ev.getY();
        int childCount = getChildCount();
        if (action == MotionEvent.ACTION_MOVE) {
            if (mLastX != 0 || mLastY != 0) {
                mDistanceDragged += Math.hypot(mLastX - x, mLastY - y);
            }
            mLastX = x;
            mLastY = y;

            boolean containerContainsTouch = x >= 0 && y >= 0 && x < getWidth() && y < getHeight();
            if (shouldStartDeferredDrag((int) x, (int) y, containerContainsTouch)) {
                cleanupDeferredDrag();
                mDeferredDragIcon.getParent().requestDisallowInterceptTouchEvent(false);
                mDeferredDragIcon.getOnLongClickListener().onLongClick(mDeferredDragIcon);
                mLauncher.getDragController().onTouchEvent(ev);
                return true;
            } else {
                // Determine whether touch is over a shortcut.
                boolean hoveringOverShortcut = false;
                for (int i = 0; i < childCount; i++) {
                    DeepShortcutView shortcut = (DeepShortcutView) getChildAt(i);
                    if (shortcut.updateHoverState(containerContainsTouch, hoveringOverShortcut, y)) {
                        hoveringOverShortcut = true;
                    }
                }

                if (!hoveringOverShortcut && mDistanceDragged > mDragDeadzone) {
                    // After dragging further than a small deadzone,
                    // have the drag view follow the user's finger.
                    mDragView.setVisibility(VISIBLE);
                    mDragView.move(dragLayerX, dragLayerY);
                    mDeferredDragIcon.setVisibility(INVISIBLE);
                } else if (hoveringOverShortcut) {
                    // Jump drag view back to original place on grid,
                    // so user doesn't think they are still dragging.
                    // TODO: can we improve this interaction? maybe with a ghost icon or similar?
                    mDragView.setVisibility(INVISIBLE);
                    mDeferredDragIcon.setVisibility(VISIBLE);
                }
            }
        } else if (action == MotionEvent.ACTION_UP) {
            cleanupDeferredDrag();
            // Launch a shortcut if user was hovering over it.
            for (int i = 0; i < childCount; i++) {
                DeepShortcutView shortcut = (DeepShortcutView) getChildAt(i);
                if (shortcut.isHoveringOver()) {
                    shortcut.performClick();
                    break;
                }
            }
        }
        return true;
    }

    /**
     * Determines whether the deferred drag should be started based on touch coordinates
     * relative to the original icon and the shortcuts container.
     *
     * Current behavior:
     * - Compute distance from original touch down to closest container edge.
     * - Compute distance from latest touch (given x and y) and compare to original distance;
     *   if the new distance is larger than a threshold, the deferred drag should start.
     * - Never defer the drag if this container contains the touch.
     *
     * @param x the x touch coordinate relative to this container
     * @param y the y touch coordinate relative to this container
     */
    private boolean shouldStartDeferredDrag(int x, int y, boolean containerContainsTouch) {
        int closestEdgeY = mIsAboveIcon ? getMeasuredHeight() : 0;
        double distToEdge = Math.abs(mTouchDown.y - closestEdgeY);
        double newDistToEdge = Math.hypot(x - mTouchDown.x, y - closestEdgeY);
        return  !containerContainsTouch && (newDistToEdge - distToEdge > mStartDragThreshold);
    }

    public void cleanupDeferredDrag() {
        if (mDragView != null) {
            mDragView.remove();
        }
        mDeferredDragIcon.setVisibility(VISIBLE);
    }

    @Override
    public boolean onTouch(View v, MotionEvent ev) {
        // Touched a shortcut, update where it was touched so we can drag from there on long click.
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
                break;
        }
        return false;
    }

    public boolean onLongClick(View v) {
        // Return early if this is not initiated from a touch
        if (!v.isInTouchMode()) return false;
        // Return if global dragging is not enabled
        if (!mLauncher.isDraggingEnabled()) return false;

        // Long clicked on a shortcut.
        mLauncher.getWorkspace().beginDragShared(v, mIconLastTouchPos, this, false);
        // TODO: support dragging from within folder without having to close it
        mLauncher.closeFolder();
        return false;
    }

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

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

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

    @Override
    public float getIntrinsicIconScaleFactor() {
        return (float) getResources().getDimensionPixelSize(R.dimen.deep_shortcut_icon_size)
                / mLauncher.getDeviceProfile().iconSizePx;
    }

    @Override
    public void onFlingToDeleteCompleted() {
        // Don't care; ignore.
    }

    @Override
    public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete,
            boolean success) {
        if (!success) {
            d.dragView.remove();
            mLauncher.showWorkspace(true);
            mLauncher.getDropTargetBar().onDragEnd();
        }
    }

    @Override
    public void onDragStart(DragSource source, ItemInfo info, int dragAction) {
        // Either the original icon or one of the shortcuts was dragged.
        // Hide the container, but don't remove it yet because that interferes with touch events.
        setVisibility(INVISIBLE);
    }

    @Override
    public void onDragEnd() {
        // Now remove the container.
        mLauncher.closeShortcutsContainer();
    }

    @Override
    public void fillInLaunchSourceData(View v, ItemInfo info, Target target, Target targetParent) {
        target.itemType = LauncherLogProto.SHORTCUT; // TODO: change to DYNAMIC_SHORTCUT
        target.gridX = info.cellX;
        target.gridY = info.cellY;
        target.pageIndex = 0;
        targetParent.containerType = LauncherLogProto.FOLDER; // TODO: change to DYNAMIC_SHORTCUTS
    }
}
