/*
 * Copyright (C) 2010 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.systemui.statusbar;

import android.app.StatusBarManager;
import android.content.res.Resources;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.PhoneStatusBar;

public class DelegateViewHelper {
    private View mDelegateView;
    private View mSourceView;
    private PhoneStatusBar mBar;
    private int[] mTempPoint = new int[2];
    private float[] mDownPoint = new float[2];
    private float mTriggerThreshhold;
    private boolean mPanelShowing;

    RectF mInitialTouch = new RectF();
    private boolean mStarted;
    private boolean mSwapXY = false;
    private boolean mDisabled;

    public DelegateViewHelper(View sourceView) {
        setSourceView(sourceView);
    }

    public void setDelegateView(View view) {
        mDelegateView = view;
    }

    public void setBar(PhoneStatusBar phoneStatusBar) {
        mBar = phoneStatusBar;
    }

    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (mSourceView == null || mDelegateView == null || mBar.shouldDisableNavbarGestures()) {
            return false;
        }

        mSourceView.getLocationOnScreen(mTempPoint);
        final float sourceX = mTempPoint[0];
        final float sourceY = mTempPoint[1];

        final int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE;
                mDownPoint[0] = event.getX();
                mDownPoint[1] = event.getY();
                mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY);
                break;
        }

        if (!mStarted) {
            return false;
        }

        if (!mDisabled && !mPanelShowing && action == MotionEvent.ACTION_MOVE) {
            final int historySize = event.getHistorySize();
            for (int k = 0; k < historySize + 1; k++) {
                float x = k < historySize ? event.getHistoricalX(k) : event.getX();
                float y = k < historySize ? event.getHistoricalY(k) : event.getY();
                final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
                if (distance > mTriggerThreshhold) {
                    mBar.invokeAssistGesture(false /* vibrate */);
                    mPanelShowing = true;
                    break;
                }
            }
        }

        if (action == MotionEvent.ACTION_DOWN) {
            mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, true);
        } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false);
        }

        mDelegateView.getLocationOnScreen(mTempPoint);
        final float delegateX = mTempPoint[0];
        final float delegateY = mTempPoint[1];

        float deltaX = sourceX - delegateX;
        float deltaY = sourceY - delegateY;
        event.offsetLocation(deltaX, deltaY);
        mDelegateView.dispatchTouchEvent(event);
        event.offsetLocation(-deltaX, -deltaY);
        return mPanelShowing;
    }

    public void abortCurrentGesture() {
        if (mStarted) {
            mStarted = false;
            mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false);
        }
    }

    public void setSourceView(View view) {
        mSourceView = view;
        if (mSourceView != null) {
            Resources r = mSourceView.getContext().getResources();
            mTriggerThreshhold = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
        }
    }

    /**
     * Selects the initial touch region based on a list of views.  This is meant to be called by
     * a container widget on children over which the initial touch should be detected.  Note this
     * will compute a minimum bound that contains all specified views.
     *
     * @param views
     */
    public void setInitialTouchRegion(View ... views) {
        RectF bounds = new RectF();
        int p[] = new int[2];
        for (int i = 0; i < views.length; i++) {
            View view = views[i];
            if (view == null) continue;
            view.getLocationOnScreen(p);
            if (i == 0) {
                bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
            } else {
                bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
            }
        }
        mInitialTouch.set(bounds);
    }

    /**
     * When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection
     * @param swap
     */
    public void setSwapXY(boolean swap) {
        mSwapXY = swap;
    }

    public void setDisabled(boolean disabled) {
        mDisabled = disabled;
    }
}