/*
 * Copyright (C) 2019 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 static android.app.StatusBarManager.WINDOW_STATE_SHOWING;

import android.app.StatusBarManager;
import android.graphics.RectF;
import android.hardware.display.AmbientDisplayConfiguration;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.view.GestureDetector;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.dock.DockManager;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;

import java.io.FileDescriptor;
import java.io.PrintWriter;

import javax.inject.Inject;

/**
 * Controller for {@link NotificationShadeWindowView}.
 */
public class NotificationShadeWindowViewController {
    private final InjectionInflationController mInjectionInflationController;
    private final NotificationWakeUpCoordinator mCoordinator;
    private final PulseExpansionHandler mPulseExpansionHandler;
    private final DynamicPrivacyController mDynamicPrivacyController;
    private final KeyguardBypassController mBypassController;
    private final PluginManager mPluginManager;
    private final FalsingManager mFalsingManager;
    private final TunerService mTunerService;
    private final NotificationLockscreenUserManager mNotificationLockscreenUserManager;
    private final NotificationEntryManager mNotificationEntryManager;
    private final KeyguardStateController mKeyguardStateController;
    private final SysuiStatusBarStateController mStatusBarStateController;
    private final DozeLog mDozeLog;
    private final DozeParameters mDozeParameters;
    private final CommandQueue mCommandQueue;
    private final NotificationShadeWindowView mView;
    private final ShadeController mShadeController;
    private final NotificationShadeDepthController mDepthController;

    private GestureDetector mGestureDetector;
    private View mBrightnessMirror;
    private boolean mTouchActive;
    private boolean mTouchCancelled;
    private boolean mExpandAnimationPending;
    private boolean mExpandAnimationRunning;
    private NotificationStackScrollLayout mStackScrollLayout;
    private PhoneStatusBarView mStatusBarView;
    private PhoneStatusBarTransitions mBarTransitions;
    private StatusBar mService;
    private NotificationShadeWindowController mNotificationShadeWindowController;
    private DragDownHelper mDragDownHelper;
    private boolean mDoubleTapEnabled;
    private boolean mSingleTapEnabled;
    private boolean mExpandingBelowNotch;
    private final DockManager mDockManager;
    private final NotificationPanelViewController mNotificationPanelViewController;
    private final SuperStatusBarViewFactory mStatusBarViewFactory;

    // Used for determining view / touch intersection
    private int[] mTempLocation = new int[2];
    private RectF mTempRect = new RectF();
    private boolean mIsTrackingBarGesture = false;

    @Inject
    public NotificationShadeWindowViewController(
            InjectionInflationController injectionInflationController,
            NotificationWakeUpCoordinator coordinator,
            PulseExpansionHandler pulseExpansionHandler,
            DynamicPrivacyController dynamicPrivacyController,
            KeyguardBypassController bypassController,
            FalsingManager falsingManager,
            PluginManager pluginManager,
            TunerService tunerService,
            NotificationLockscreenUserManager notificationLockscreenUserManager,
            NotificationEntryManager notificationEntryManager,
            KeyguardStateController keyguardStateController,
            SysuiStatusBarStateController statusBarStateController,
            DozeLog dozeLog,
            DozeParameters dozeParameters,
            CommandQueue commandQueue,
            ShadeController shadeController,
            DockManager dockManager,
            NotificationShadeDepthController depthController,
            NotificationShadeWindowView notificationShadeWindowView,
            NotificationPanelViewController notificationPanelViewController,
            SuperStatusBarViewFactory statusBarViewFactory) {
        mInjectionInflationController = injectionInflationController;
        mCoordinator = coordinator;
        mPulseExpansionHandler = pulseExpansionHandler;
        mDynamicPrivacyController = dynamicPrivacyController;
        mBypassController = bypassController;
        mFalsingManager = falsingManager;
        mPluginManager = pluginManager;
        mTunerService = tunerService;
        mNotificationLockscreenUserManager = notificationLockscreenUserManager;
        mNotificationEntryManager = notificationEntryManager;
        mKeyguardStateController = keyguardStateController;
        mStatusBarStateController = statusBarStateController;
        mDozeLog = dozeLog;
        mDozeParameters = dozeParameters;
        mCommandQueue = commandQueue;
        mView = notificationShadeWindowView;
        mShadeController = shadeController;
        mDockManager = dockManager;
        mNotificationPanelViewController = notificationPanelViewController;
        mDepthController = depthController;
        mStatusBarViewFactory = statusBarViewFactory;

        // This view is not part of the newly inflated expanded status bar.
        mBrightnessMirror = mView.findViewById(R.id.brightness_mirror);
    }

    /** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
    public void setupExpandedStatusBar() {
        mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);

        TunerService.Tunable tunable = (key, newValue) -> {
            AmbientDisplayConfiguration configuration =
                    new AmbientDisplayConfiguration(mView.getContext());
            switch (key) {
                case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
                    mDoubleTapEnabled = configuration.doubleTapGestureEnabled(
                            UserHandle.USER_CURRENT);
                    break;
                case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
                    mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
            }
        };
        mTunerService.addTunable(tunable,
                Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
                Settings.Secure.DOZE_TAP_SCREEN_GESTURE);

        GestureDetector.SimpleOnGestureListener gestureListener =
                new GestureDetector.SimpleOnGestureListener() {
                    @Override
                    public boolean onSingleTapConfirmed(MotionEvent e) {
                        if (mSingleTapEnabled && !mDockManager.isDocked()) {
                            mService.wakeUpIfDozing(
                                    SystemClock.uptimeMillis(), mView, "SINGLE_TAP");
                            return true;
                        }
                        return false;
                    }

                    @Override
                    public boolean onDoubleTap(MotionEvent e) {
                        if (mDoubleTapEnabled || mSingleTapEnabled) {
                            mService.wakeUpIfDozing(
                                    SystemClock.uptimeMillis(), mView, "DOUBLE_TAP");
                            return true;
                        }
                        return false;
                    }
                };
        mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);

        mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
            @Override
            public Boolean handleDispatchTouchEvent(MotionEvent ev) {
                boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
                boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
                boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;

                boolean expandingBelowNotch = mExpandingBelowNotch;
                if (isUp || isCancel) {
                    mExpandingBelowNotch = false;
                }

                // Reset manual touch dispatch state here but make sure the UP/CANCEL event still
                // gets
                // delivered.

                if (!isCancel && mService.shouldIgnoreTouch()) {
                    return false;
                }
                if (isDown && mNotificationPanelViewController.isFullyCollapsed()) {
                    mNotificationPanelViewController.startExpandLatencyTracking();
                }
                if (isDown) {
                    setTouchActive(true);
                    mTouchCancelled = false;
                } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
                        || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
                    setTouchActive(false);
                }
                if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
                    return false;
                }
                mFalsingManager.onTouchEvent(ev, mView.getWidth(), mView.getHeight());
                mGestureDetector.onTouchEvent(ev);
                if (mBrightnessMirror != null
                        && mBrightnessMirror.getVisibility() == View.VISIBLE) {
                    // Disallow new pointers while the brightness mirror is visible. This is so that
                    // you can't touch anything other than the brightness slider while the mirror is
                    // showing and the rest of the panel is transparent.
                    if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
                        return false;
                    }
                }
                if (isDown) {
                    mStackScrollLayout.closeControlsIfOutsideTouch(ev);
                }
                if (mStatusBarStateController.isDozing()) {
                    mService.mDozeScrimController.extendPulse();
                }
                // In case we start outside of the view bounds (below the status bar), we need to
                // dispatch
                // the touch manually as the view system can't accommodate for touches outside of
                // the
                // regular view bounds.
                if (isDown && ev.getY() >= mView.getBottom()) {
                    mExpandingBelowNotch = true;
                    expandingBelowNotch = true;
                }
                if (expandingBelowNotch) {
                    return mStatusBarView.dispatchTouchEvent(ev);
                }

                if (!mIsTrackingBarGesture && isDown
                        && mNotificationPanelViewController.isFullyCollapsed()) {
                    float x = ev.getRawX();
                    float y = ev.getRawY();
                    if (isIntersecting(mStatusBarView, x, y)) {
                        if (mService.isSameStatusBarState(WINDOW_STATE_SHOWING)) {
                            mIsTrackingBarGesture = true;
                            return mStatusBarView.dispatchTouchEvent(ev);
                        } else { // it's hidden or hiding, don't send to notification shade.
                            return true;
                        }
                    }
                } else if (mIsTrackingBarGesture) {
                    final boolean sendToNotification = mStatusBarView.dispatchTouchEvent(ev);
                    if (isUp || isCancel) {
                        mIsTrackingBarGesture = false;
                    }
                    return sendToNotification;
                }

                return null;
            }

            @Override
            public boolean shouldInterceptTouchEvent(MotionEvent ev) {
                if (mStatusBarStateController.isDozing() && !mService.isPulsing()
                        && !mDockManager.isDocked()) {
                    // Capture all touch events in always-on.
                    return true;
                }
                boolean intercept = false;
                if (mNotificationPanelViewController.isFullyExpanded()
                        && mDragDownHelper.isDragDownEnabled()
                        && !mService.isBouncerShowing()
                        && !mStatusBarStateController.isDozing()) {
                    intercept = mDragDownHelper.onInterceptTouchEvent(ev);
                }

                return intercept;

            }

            @Override
            public void didIntercept(MotionEvent ev) {
                MotionEvent cancellation = MotionEvent.obtain(ev);
                cancellation.setAction(MotionEvent.ACTION_CANCEL);
                mStackScrollLayout.onInterceptTouchEvent(cancellation);
                mNotificationPanelViewController.getView().onInterceptTouchEvent(cancellation);
                cancellation.recycle();
            }

            @Override
            public boolean handleTouchEvent(MotionEvent ev) {
                boolean handled = false;
                if (mStatusBarStateController.isDozing()) {
                    handled = !mService.isPulsing();
                }
                if ((mDragDownHelper.isDragDownEnabled() && !handled)
                        || mDragDownHelper.isDraggingDown()) {
                    // we still want to finish our drag down gesture when locking the screen
                    handled = mDragDownHelper.onTouchEvent(ev);
                }

                return handled;
            }

            @Override
            public void didNotHandleTouchEvent(MotionEvent ev) {
                final int action = ev.getActionMasked();
                if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                    mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
                }
            }

            @Override
            public boolean interceptMediaKey(KeyEvent event) {
                return mService.interceptMediaKey(event);
            }

            @Override
            public boolean dispatchKeyEvent(KeyEvent event) {
                boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
                switch (event.getKeyCode()) {
                    case KeyEvent.KEYCODE_BACK:
                        if (!down) {
                            mService.onBackPressed();
                        }
                        return true;
                    case KeyEvent.KEYCODE_MENU:
                        if (!down) {
                            return mService.onMenuPressed();
                        }
                        break;
                    case KeyEvent.KEYCODE_SPACE:
                        if (!down) {
                            return mService.onSpacePressed();
                        }
                        break;
                    case KeyEvent.KEYCODE_VOLUME_DOWN:
                    case KeyEvent.KEYCODE_VOLUME_UP:
                        if (mStatusBarStateController.isDozing()) {
                            MediaSessionLegacyHelper.getHelper(mView.getContext())
                                    .sendVolumeKeyEvent(
                                            event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
                            return true;
                        }
                        break;
                }
                return false;
            }
        });

        mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
            @Override
            public void onChildViewAdded(View parent, View child) {
                if (child.getId() == R.id.brightness_mirror) {
                    mBrightnessMirror = child;
                }
            }

            @Override
            public void onChildViewRemoved(View parent, View child) {
            }
        });

        ExpandHelper.Callback expandHelperCallback = mStackScrollLayout.getExpandHelperCallback();
        DragDownHelper.DragDownCallback dragDownCallback = mStackScrollLayout.getDragDownCallback();
        setDragDownHelper(
                new DragDownHelper(
                        mView.getContext(), mView, expandHelperCallback,
                        dragDownCallback, mFalsingManager));

        mDepthController.setRoot(mView);
        mNotificationPanelViewController.addExpansionListener(mDepthController);
    }

    public NotificationShadeWindowView getView() {
        return mView;
    }

    public void setTouchActive(boolean touchActive) {
        mTouchActive = touchActive;
    }

    public void cancelCurrentTouch() {
        if (mTouchActive) {
            final long now = SystemClock.uptimeMillis();
            MotionEvent event = MotionEvent.obtain(now, now,
                    MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
            event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
            mView.dispatchTouchEvent(event);
            event.recycle();
            mTouchCancelled = true;
        }
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.print("  mExpandAnimationPending=");
        pw.println(mExpandAnimationPending);
        pw.print("  mExpandAnimationRunning=");
        pw.println(mExpandAnimationRunning);
        pw.print("  mTouchCancelled=");
        pw.println(mTouchCancelled);
        pw.print("  mTouchActive=");
        pw.println(mTouchActive);
    }

    public void setExpandAnimationPending(boolean pending) {
        mExpandAnimationPending = pending;
        mNotificationShadeWindowController
                .setLaunchingActivity(mExpandAnimationPending | mExpandAnimationRunning);
    }

    public void setExpandAnimationRunning(boolean running) {
        mExpandAnimationRunning = running;
        mNotificationShadeWindowController
                .setLaunchingActivity(mExpandAnimationPending | mExpandAnimationRunning);
    }

    public void cancelExpandHelper() {
        if (mStackScrollLayout != null) {
            mStackScrollLayout.cancelExpandHelper();
        }
    }

    public PhoneStatusBarTransitions getBarTransitions() {
        return mBarTransitions;
    }

    public void setStatusBarView(PhoneStatusBarView statusBarView) {
        mStatusBarView = statusBarView;
        if (statusBarView != null && mStatusBarViewFactory != null) {
            mBarTransitions = new PhoneStatusBarTransitions(
                    statusBarView,
                    mStatusBarViewFactory.getStatusBarWindowView()
                            .findViewById(R.id.status_bar_container));
        }
    }

    public void setService(StatusBar statusBar, NotificationShadeWindowController controller) {
        mService = statusBar;
        mNotificationShadeWindowController = controller;
    }

    @VisibleForTesting
    void setDragDownHelper(DragDownHelper dragDownHelper) {
        mDragDownHelper = dragDownHelper;
    }

    private boolean isIntersecting(View view, float x, float y) {
        mTempLocation = view.getLocationOnScreen();
        mTempRect.set(mTempLocation[0], mTempLocation[1], mTempLocation[0] + view.getWidth(),
                mTempLocation[1] + view.getHeight());
        return mTempRect.contains(x, y);
    }
}
