/*
 * Copyright (C) 2014 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.phone;

import android.content.Context;
import android.content.res.Resources;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;

public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnGestureListener {

    private BaseStatusBar mBar;
    private boolean mIsVertical;
    private boolean mIsRTL;

    private final GestureDetector mTaskSwitcherDetector;
    private final int mScrollTouchSlop;
    private final int mMinFlingVelocity;
    private int mTouchDownX;
    private int mTouchDownY;

    public NavigationBarViewTaskSwitchHelper(Context context) {
        ViewConfiguration configuration = ViewConfiguration.get(context);
        Resources r = context.getResources();
        mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
        mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
        mTaskSwitcherDetector = new GestureDetector(context, this);
    }

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

    public void setBarState(boolean isVertical, boolean isRTL) {
        mIsVertical = isVertical;
        mIsRTL = isRTL;
    }

    public boolean onInterceptTouchEvent(MotionEvent event) {
        // If we move more than a fixed amount, then start capturing for the
        // task switcher detector
        mTaskSwitcherDetector.onTouchEvent(event);
        int action = event.getAction();
        boolean intercepted = false;
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                mTouchDownX = (int) event.getX();
                mTouchDownY = (int) event.getY();
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                int x = (int) event.getX();
                int y = (int) event.getY();
                int xDiff = Math.abs(x - mTouchDownX);
                int yDiff = Math.abs(y - mTouchDownY);
                boolean exceededTouchSlop = !mIsVertical
                        ? xDiff > mScrollTouchSlop && xDiff > yDiff
                        : yDiff > mScrollTouchSlop && yDiff > xDiff;
                if (exceededTouchSlop) {
                    return true;
                }
                break;
            }
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                break;
        }
        return intercepted;
    }

    public boolean onTouchEvent(MotionEvent event) {
        return mTaskSwitcherDetector.onTouchEvent(event);
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        float absVelX = Math.abs(velocityX);
        float absVelY = Math.abs(velocityY);
        boolean isValidFling = absVelX > mMinFlingVelocity &&
                mIsVertical ? (absVelY > absVelX) : (absVelX > absVelY);
        if (isValidFling) {
            boolean showNext;
            if (!mIsRTL) {
                showNext = mIsVertical ? (velocityY < 0) : (velocityX < 0);
            } else {
                // In RTL, vertical is still the same, but horizontal is flipped
                showNext = mIsVertical ? (velocityY < 0) : (velocityX > 0);
            }
            if (showNext) {
                mBar.showNextAffiliatedTask();
            } else {
                mBar.showPreviousAffiliatedTask();
            }
        }
        return true;
    }
}
