/*
 * 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 android.view;

import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.ArrayMap;
import android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo;

/**
 * Helper class to handle situations where you want a view to have a larger touch area than its
 * actual view bounds. The view whose touch area is changed is called the delegate view. This
 * class should be used by an ancestor of the delegate. To use a TouchDelegate, first create an
 * instance that specifies the bounds that should be mapped to the delegate and the delegate
 * view itself.
 * <p>
 * The ancestor should then forward all of its touch events received in its
 * {@link android.view.View#onTouchEvent(MotionEvent)} to {@link #onTouchEvent(MotionEvent)}.
 * </p>
 */
public class TouchDelegate {

    /**
     * View that should receive forwarded touch events
     */
    private View mDelegateView;

    /**
     * Bounds in local coordinates of the containing view that should be mapped to the delegate
     * view. This rect is used for initial hit testing.
     */
    private Rect mBounds;

    /**
     * mBounds inflated to include some slop. This rect is to track whether the motion events
     * should be considered to be within the delegate view.
     */
    private Rect mSlopBounds;

    /**
     * True if the delegate had been targeted on a down event (intersected mBounds).
     */
    @UnsupportedAppUsage
    private boolean mDelegateTargeted;

    /**
     * The touchable region of the View extends above its actual extent.
     */
    public static final int ABOVE = 1;

    /**
     * The touchable region of the View extends below its actual extent.
     */
    public static final int BELOW = 2;

    /**
     * The touchable region of the View extends to the left of its actual extent.
     */
    public static final int TO_LEFT = 4;

    /**
     * The touchable region of the View extends to the right of its actual extent.
     */
    public static final int TO_RIGHT = 8;

    private int mSlop;

    /**
     * Touch delegate information for accessibility
     */
    private TouchDelegateInfo mTouchDelegateInfo;

    /**
     * Constructor
     *
     * @param bounds Bounds in local coordinates of the containing view that should be mapped to
     *        the delegate view
     * @param delegateView The view that should receive motion events
     */
    public TouchDelegate(Rect bounds, View delegateView) {
        mBounds = bounds;

        mSlop = ViewConfiguration.get(delegateView.getContext()).getScaledTouchSlop();
        mSlopBounds = new Rect(bounds);
        mSlopBounds.inset(-mSlop, -mSlop);
        mDelegateView = delegateView;
    }

    /**
     * Forward touch events to the delegate view if the event is within the bounds
     * specified in the constructor.
     *
     * @param event The touch event to forward
     * @return True if the event was consumed by the delegate, false otherwise.
     */
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        int x = (int)event.getX();
        int y = (int)event.getY();
        boolean sendToDelegate = false;
        boolean hit = true;
        boolean handled = false;

        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mDelegateTargeted = mBounds.contains(x, y);
                sendToDelegate = mDelegateTargeted;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_MOVE:
                sendToDelegate = mDelegateTargeted;
                if (sendToDelegate) {
                    Rect slopBounds = mSlopBounds;
                    if (!slopBounds.contains(x, y)) {
                        hit = false;
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                sendToDelegate = mDelegateTargeted;
                mDelegateTargeted = false;
                break;
        }
        if (sendToDelegate) {
            if (hit) {
                // Offset event coordinates to be inside the target view
                event.setLocation(mDelegateView.getWidth() / 2, mDelegateView.getHeight() / 2);
            } else {
                // Offset event coordinates to be outside the target view (in case it does
                // something like tracking pressed state)
                int slop = mSlop;
                event.setLocation(-(slop * 2), -(slop * 2));
            }
            handled = mDelegateView.dispatchTouchEvent(event);
        }
        return handled;
    }

    /**
     * Forward hover events to the delegate view if the event is within the bounds
     * specified in the constructor and touch exploration is enabled.
     *
     * <p>This method is provided for accessibility purposes so touch exploration, which is
     * commonly used by screen readers, can properly place accessibility focus on views that
     * use touch delegates. Therefore, touch exploration must be enabled for hover events
     * to be dispatched through the delegate.</p>
     *
     * @param event The hover event to forward
     * @return True if the event was consumed by the delegate, false otherwise.
     *
     * @see android.view.accessibility.AccessibilityManager#isTouchExplorationEnabled
     */
    public boolean onTouchExplorationHoverEvent(@NonNull MotionEvent event) {
        if (mBounds == null) {
            return false;
        }

        final int x = (int) event.getX();
        final int y = (int) event.getY();
        boolean hit = true;
        boolean handled = false;

        final boolean isInbound = mBounds.contains(x, y);
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_HOVER_ENTER:
                mDelegateTargeted = isInbound;
                break;
            case MotionEvent.ACTION_HOVER_MOVE:
                if (isInbound) {
                    mDelegateTargeted = true;
                } else {
                    // delegated previously
                    if (mDelegateTargeted && !mSlopBounds.contains(x, y)) {
                        hit = false;
                    }
                }
                break;
            case MotionEvent.ACTION_HOVER_EXIT:
                mDelegateTargeted = true;
                break;
        }
        if (mDelegateTargeted) {
            if (hit) {
                event.setLocation(mDelegateView.getWidth() / 2, mDelegateView.getHeight() / 2);
            } else {
                mDelegateTargeted = false;
            }
            handled = mDelegateView.dispatchHoverEvent(event);
        }
        return handled;
    }

    /**
     * Return a {@link TouchDelegateInfo} mapping from regions (in view coordinates) to
     * delegated views for accessibility usage.
     *
     * @return A TouchDelegateInfo.
     */
    @NonNull
    public TouchDelegateInfo getTouchDelegateInfo() {
        if (mTouchDelegateInfo == null) {
            final ArrayMap<Region, View> targetMap = new ArrayMap<>(1);
            Rect bounds = mBounds;
            if (bounds == null) {
                bounds = new Rect();
            }
            targetMap.put(new Region(bounds), mDelegateView);
            mTouchDelegateInfo = new TouchDelegateInfo(targetMap);
        }
        return mTouchDelegateInfo;
    }
}
