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

import android.graphics.Rect;
import android.graphics.Region;
import android.view.DisplayInfo;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.WindowManagerPolicy.PointerEventListener;

import com.android.server.wm.WindowManagerService.H;

import static android.view.PointerIcon.STYLE_NOT_SPECIFIED;
import static android.view.PointerIcon.STYLE_DEFAULT;
import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW;
import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW;
import static android.view.PointerIcon.STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW;
import static android.view.PointerIcon.STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW;

public class TaskTapPointerEventListener implements PointerEventListener {
    private static final int TAP_TIMEOUT_MSEC = 300;
    private static final float TAP_MOTION_SLOP_INCHES = 0.125f;

    private final int mMotionSlop;
    private float mDownX;
    private float mDownY;
    private int mPointerId;
    final private Region mTouchExcludeRegion = new Region();
    private final WindowManagerService mService;
    private final DisplayContent mDisplayContent;
    private final Rect mTmpRect = new Rect();
    private final Region mNonResizeableRegion = new Region();
    private boolean mTwoFingerScrolling;
    private boolean mInGestureDetection;
    private GestureDetector mGestureDetector;
    private int mPointerIconShape = STYLE_NOT_SPECIFIED;

    public TaskTapPointerEventListener(WindowManagerService service,
            DisplayContent displayContent) {
        mService = service;
        mDisplayContent = displayContent;
        DisplayInfo info = displayContent.getDisplayInfo();
        mMotionSlop = (int)(info.logicalDensityDpi * TAP_MOTION_SLOP_INCHES);
    }

    // initialize the object, note this must be done outside WindowManagerService
    // ctor, otherwise it may cause recursion as some code in GestureDetector ctor
    // depends on WMS being already created.
    void init() {
        mGestureDetector = new GestureDetector(
                mService.mContext, new TwoFingerScrollListener(), mService.mH);
    }

    @Override
    public void onPointerEvent(MotionEvent motionEvent) {
        doGestureDetection(motionEvent);

        final int action = motionEvent.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                mPointerId = motionEvent.getPointerId(0);
                mDownX = motionEvent.getX();
                mDownY = motionEvent.getY();

                final int x = (int) mDownX;
                final int y = (int) mDownY;
                synchronized (this) {
                    if (!mTouchExcludeRegion.contains(x, y)) {
                        mService.mH.obtainMessage(H.TAP_DOWN_OUTSIDE_TASK, x, y,
                                mDisplayContent).sendToTarget();
                    }
                }
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                if (mPointerId >= 0) {
                    int index = motionEvent.findPointerIndex(mPointerId);
                    if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC
                            || index < 0
                            || Math.abs(motionEvent.getX(index) - mDownX) > mMotionSlop
                            || Math.abs(motionEvent.getY(index) - mDownY) > mMotionSlop) {
                        mPointerId = -1;
                    }
                }
                if (motionEvent.getPointerCount() != 2) {
                    stopTwoFingerScroll();
                }
                break;
            }

            case MotionEvent.ACTION_HOVER_MOVE: {
                final int x = (int) motionEvent.getX();
                final int y = (int) motionEvent.getY();
                final Task task = mDisplayContent.findTaskForControlPoint(x, y);
                if (task == null) {
                    mPointerIconShape = STYLE_NOT_SPECIFIED;
                    break;
                }
                task.getDimBounds(mTmpRect);
                if (!mTmpRect.isEmpty() && !mTmpRect.contains(x, y)) {
                    int iconShape = STYLE_DEFAULT;
                    if (x < mTmpRect.left) {
                        iconShape =
                            (y < mTmpRect.top) ? STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
                            (y > mTmpRect.bottom) ? STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
                            STYLE_HORIZONTAL_DOUBLE_ARROW;
                    } else if (x > mTmpRect.right) {
                        iconShape =
                            (y < mTmpRect.top) ? STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW :
                            (y > mTmpRect.bottom) ? STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW :
                            STYLE_HORIZONTAL_DOUBLE_ARROW;
                    } else if (y < mTmpRect.top || y > mTmpRect.bottom) {
                        iconShape = STYLE_VERTICAL_DOUBLE_ARROW;
                    }
                    if (mPointerIconShape != iconShape) {
                        mPointerIconShape = iconShape;
                        motionEvent.getDevice().setPointerShape(iconShape);
                    }
                } else {
                    mPointerIconShape = STYLE_NOT_SPECIFIED;
                }
            } break;

            case MotionEvent.ACTION_HOVER_EXIT:
                mPointerIconShape = STYLE_NOT_SPECIFIED;
                motionEvent.getDevice().setPointerShape(STYLE_DEFAULT);
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP: {
                int index = (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
                // Extract the index of the pointer that left the touch sensor
                if (mPointerId == motionEvent.getPointerId(index)) {
                    final int x = (int)motionEvent.getX(index);
                    final int y = (int)motionEvent.getY(index);
                    synchronized(this) {
                        if ((motionEvent.getEventTime() - motionEvent.getDownTime())
                                < TAP_TIMEOUT_MSEC
                                && Math.abs(x - mDownX) < mMotionSlop
                                && Math.abs(y - mDownY) < mMotionSlop
                                && !mTouchExcludeRegion.contains(x, y)) {
                            mService.mH.obtainMessage(H.TAP_OUTSIDE_TASK, x, y,
                                    mDisplayContent).sendToTarget();
                        }
                    }
                    mPointerId = -1;
                }
                stopTwoFingerScroll();
                break;
            }
        }
    }

    private void doGestureDetection(MotionEvent motionEvent) {
        if (mGestureDetector == null || mNonResizeableRegion.isEmpty()) {
            return;
        }
        final int action = motionEvent.getAction() & MotionEvent.ACTION_MASK;
        final int x = (int) motionEvent.getX();
        final int y = (int) motionEvent.getY();
        final boolean isTouchInside = mNonResizeableRegion.contains(x, y);
        if (mInGestureDetection || action == MotionEvent.ACTION_DOWN && isTouchInside) {
            // If we receive the following actions, or the pointer goes out of the area
            // we're interested in, stop detecting and cancel the current detection.
            mInGestureDetection = isTouchInside
                    && action != MotionEvent.ACTION_UP
                    && action != MotionEvent.ACTION_POINTER_UP
                    && action != MotionEvent.ACTION_CANCEL;
            if (mInGestureDetection) {
                mGestureDetector.onTouchEvent(motionEvent);
            } else {
                MotionEvent cancelEvent = motionEvent.copy();
                cancelEvent.cancel();
                mGestureDetector.onTouchEvent(cancelEvent);
                stopTwoFingerScroll();
            }
        }
    }

    private void onTwoFingerScroll(MotionEvent e) {
        final int x = (int)e.getX(0);
        final int y = (int)e.getY(0);
        if (!mTwoFingerScrolling) {
            mTwoFingerScrolling = true;
            mService.mH.obtainMessage(
                    H.TWO_FINGER_SCROLL_START, x, y, mDisplayContent).sendToTarget();
        }
    }

    private void stopTwoFingerScroll() {
        if (mTwoFingerScrolling) {
            mTwoFingerScrolling = false;
            mService.mH.obtainMessage(H.FINISH_TASK_POSITIONING).sendToTarget();
        }
    }

    private final class TwoFingerScrollListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            if (e2.getPointerCount() == 2) {
                onTwoFingerScroll(e2);
                return true;
            }
            stopTwoFingerScroll();
            return false;
        }
    }

    void setTouchExcludeRegion(Region newRegion, Region nonResizeableRegion) {
        synchronized (this) {
           mTouchExcludeRegion.set(newRegion);
           mNonResizeableRegion.set(nonResizeableRegion);
        }
    }
}
