/*
 * 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;

public class DelegateViewHelper {
    private View mDelegateView;
    private View mSourceView;
    private BaseStatusBar 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(BaseStatusBar 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.showSearchPanel();
                    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 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;
    }
}