/*
 * Copyright (C) 2018 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.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import android.view.WindowInsets;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;

import java.util.function.BiConsumer;
import java.util.function.Consumer;

/**
 * Controls the appearance of heads up notifications in the icon area and the header itself.
 */
public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
        DarkIconDispatcher.DarkReceiver {
    public static final int CONTENT_FADE_DURATION = 110;
    public static final int CONTENT_FADE_DELAY = 100;
    private final NotificationIconAreaController mNotificationIconAreaController;
    private final HeadsUpManagerPhone mHeadsUpManager;
    private final NotificationStackScrollLayout mStackScroller;
    private final HeadsUpStatusBarView mHeadsUpStatusBarView;
    private final View mClockView;
    private final DarkIconDispatcher mDarkIconDispatcher;
    private final NotificationPanelView mPanelView;
    private final Consumer<ExpandableNotificationRow>
            mSetTrackingHeadsUp = this::setTrackingHeadsUp;
    private final Runnable mUpdatePanelTranslation = this::updatePanelTranslation;
    private final BiConsumer<Float, Float> mSetExpandedHeight = this::setExpandedHeight;
    private float mExpandedHeight;
    private boolean mIsExpanded;
    private float mExpandFraction;
    private ExpandableNotificationRow mTrackedChild;
    private boolean mShown;
    private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
            (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
                    -> updatePanelTranslation();
    Point mPoint;

    public HeadsUpAppearanceController(
            NotificationIconAreaController notificationIconAreaController,
            HeadsUpManagerPhone headsUpManager,
            View statusbarView) {
        this(notificationIconAreaController, headsUpManager,
                statusbarView.findViewById(R.id.heads_up_status_bar_view),
                statusbarView.findViewById(R.id.notification_stack_scroller),
                statusbarView.findViewById(R.id.notification_panel),
                statusbarView.findViewById(R.id.clock));
    }

    @VisibleForTesting
    public HeadsUpAppearanceController(
            NotificationIconAreaController notificationIconAreaController,
            HeadsUpManagerPhone headsUpManager,
            HeadsUpStatusBarView headsUpStatusBarView,
            NotificationStackScrollLayout stackScroller,
            NotificationPanelView panelView,
            View clockView) {
        mNotificationIconAreaController = notificationIconAreaController;
        mHeadsUpManager = headsUpManager;
        mHeadsUpManager.addListener(this);
        mHeadsUpStatusBarView = headsUpStatusBarView;
        headsUpStatusBarView.setOnDrawingRectChangedListener(
                () -> updateIsolatedIconLocation(true /* requireUpdate */));
        mStackScroller = stackScroller;
        mPanelView = panelView;
        panelView.addTrackingHeadsUpListener(mSetTrackingHeadsUp);
        panelView.addVerticalTranslationListener(mUpdatePanelTranslation);
        panelView.setHeadsUpAppearanceController(this);
        mStackScroller.addOnExpandedHeightListener(mSetExpandedHeight);
        mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
        mStackScroller.setHeadsUpAppearanceController(this);
        mClockView = clockView;
        mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
        mDarkIconDispatcher.addDarkReceiver(this);
    }


    public void destroy() {
        mHeadsUpManager.removeListener(this);
        mHeadsUpStatusBarView.setOnDrawingRectChangedListener(null);
        mPanelView.removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
        mPanelView.removeVerticalTranslationListener(mUpdatePanelTranslation);
        mPanelView.setHeadsUpAppearanceController(null);
        mStackScroller.removeOnExpandedHeightListener(mSetExpandedHeight);
        mStackScroller.removeOnLayoutChangeListener(mStackScrollLayoutChangeListener);
        mDarkIconDispatcher.removeDarkReceiver(this);
    }

    private void updateIsolatedIconLocation(boolean requireStateUpdate) {
        mNotificationIconAreaController.setIsolatedIconLocation(
                mHeadsUpStatusBarView.getIconDrawingRect(), requireStateUpdate);
    }

    @Override
    public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
        updateTopEntry();
        updateHeader(headsUp.getEntry());
    }

    /** To count the distance from the window right boundary to scroller right boundary. The
     * distance formula is the following:
     *     Y = screenSize - (SystemWindow's width + Scroller.getRight())
     * There are four modes MUST to be considered in Cut Out of RTL.
     * No Cut Out:
     *   Scroller + NB
     *   NB + Scroller
     *     => SystemWindow = NavigationBar's width
     *     => Y = screenSize - (SystemWindow's width + Scroller.getRight())
     * Corner Cut Out or Tall Cut Out:
     *   cut out + Scroller + NB
     *   NB + Scroller + cut out
     *     => SystemWindow = NavigationBar's width
     *     => Y = screenSize - (SystemWindow's width + Scroller.getRight())
     * Double Cut Out:
     *   cut out left + Scroller + (NB + cut out right)
     *     SystemWindow = NavigationBar's width + cut out right width
     *     => Y = screenSize - (SystemWindow's width + Scroller.getRight())
     *   (cut out left + NB) + Scroller + cut out right
     *     SystemWindow = NavigationBar's width + cut out left width
     *     => Y = screenSize - (SystemWindow's width + Scroller.getRight())
     * @return the translation X value for RTL. In theory, it should be negative. i.e. -Y
     */
    private int getRtlTranslation() {
        if (mPoint == null) {
            mPoint = new Point();
        }

        int realDisplaySize = 0;
        if (mStackScroller.getDisplay() != null) {
            mStackScroller.getDisplay().getRealSize(mPoint);
            realDisplaySize = mPoint.x;
        }

        WindowInsets windowInset = mStackScroller.getRootWindowInsets();
        return windowInset.getSystemWindowInsetLeft() + mStackScroller.getRight()
                + windowInset.getSystemWindowInsetRight() - realDisplaySize;
    }

    public void updatePanelTranslation() {
        float newTranslation;
        if (mStackScroller.isLayoutRtl()) {
            newTranslation = getRtlTranslation();
        } else {
            newTranslation = mStackScroller.getLeft();
        }
        newTranslation += mStackScroller.getTranslationX();
        mHeadsUpStatusBarView.setPanelTranslation(newTranslation);
    }

    private void updateTopEntry() {
        NotificationData.Entry newEntry = null;
        if (!mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp()) {
            newEntry = mHeadsUpManager.getTopEntry();
        }
        NotificationData.Entry previousEntry = mHeadsUpStatusBarView.getShowingEntry();
        mHeadsUpStatusBarView.setEntry(newEntry);
        if (newEntry != previousEntry) {
            boolean animateIsolation = false;
            if (newEntry == null) {
                // no heads up anymore, lets start the disappear animation

                setShown(false);
                animateIsolation = !mIsExpanded;
            } else if (previousEntry == null) {
                // We now have a headsUp and didn't have one before. Let's start the disappear
                // animation
                setShown(true);
                animateIsolation = !mIsExpanded;
            }
            updateIsolatedIconLocation(false /* requireUpdate */);
            mNotificationIconAreaController.showIconIsolated(newEntry == null ? null
                    : newEntry.icon, animateIsolation);
        }
    }

    private void setShown(boolean isShown) {
        if (mShown != isShown) {
            mShown = isShown;
            if (isShown) {
                mHeadsUpStatusBarView.setVisibility(View.VISIBLE);
                CrossFadeHelper.fadeIn(mHeadsUpStatusBarView, CONTENT_FADE_DURATION /* duration */,
                        CONTENT_FADE_DELAY /* delay */);
                CrossFadeHelper.fadeOut(mClockView, CONTENT_FADE_DURATION/* duration */,
                        0 /* delay */, () -> mClockView.setVisibility(View.INVISIBLE));
            } else {
                CrossFadeHelper.fadeIn(mClockView, CONTENT_FADE_DURATION /* duration */,
                        CONTENT_FADE_DELAY /* delay */);
                CrossFadeHelper.fadeOut(mHeadsUpStatusBarView, CONTENT_FADE_DURATION/* duration */,
                        0 /* delay */, () -> mHeadsUpStatusBarView.setVisibility(View.GONE));

            }
        }
    }

    @VisibleForTesting
    public boolean isShown() {
        return mShown;
    }

    /**
     * Should the headsup status bar view be visible right now? This may be different from isShown,
     * since the headsUp manager might not have notified us yet of the state change.
     *
     * @return if the heads up status bar view should be shown
     */
    public boolean shouldBeVisible() {
        return !mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp();
    }

    @Override
    public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
        updateTopEntry();
        updateHeader(headsUp.getEntry());
    }

    public void setExpandedHeight(float expandedHeight, float appearFraction) {
        boolean changedHeight = expandedHeight != mExpandedHeight;
        mExpandedHeight = expandedHeight;
        mExpandFraction = appearFraction;
        boolean isExpanded = expandedHeight > 0;
        if (changedHeight) {
            updateHeadsUpHeaders();
        }
        if (isExpanded != mIsExpanded) {
            mIsExpanded = isExpanded;
            updateTopEntry();
        }
    }

    /**
     * Set a headsUp to be tracked, meaning that it is currently being pulled down after being
     * in a pinned state on the top. The expand animation is different in that case and we need
     * to update the header constantly afterwards.
     *
     * @param trackedChild the tracked headsUp or null if it's not tracking anymore.
     */
    public void setTrackingHeadsUp(ExpandableNotificationRow trackedChild) {
        ExpandableNotificationRow previousTracked = mTrackedChild;
        mTrackedChild = trackedChild;
        if (previousTracked != null) {
            updateHeader(previousTracked.getEntry());
        }
    }

    private void updateHeadsUpHeaders() {
        mHeadsUpManager.getAllEntries().forEach(entry -> {
            updateHeader(entry);
        });
    }

    public void updateHeader(NotificationData.Entry entry) {
        ExpandableNotificationRow row = entry.row;
        float headerVisibleAmount = 1.0f;
        if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild) {
            headerVisibleAmount = mExpandFraction;
        }
        row.setHeaderVisibleAmount(headerVisibleAmount);
    }

    @Override
    public void onDarkChanged(Rect area, float darkIntensity, int tint) {
        mHeadsUpStatusBarView.onDarkChanged(area, darkIntensity, tint);
    }

    public void setPublicMode(boolean publicMode) {
        mHeadsUpStatusBarView.setPublicMode(publicMode);
        updateTopEntry();
    }
}
