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

import android.view.View;

import androidx.collection.ArraySet;

import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;

import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * A manager that ensures that notifications are visually stable. It will suppress reorderings
 * and reorder at the right time when they are out of view.
 */
@Singleton
public class VisualStabilityManager implements OnHeadsUpChangedListener {

    private final ArrayList<Callback> mCallbacks =  new ArrayList<>();

    private NotificationPresenter mPresenter;
    private boolean mPanelExpanded;
    private boolean mScreenOn;
    private boolean mReorderingAllowed;
    private VisibilityLocationProvider mVisibilityLocationProvider;
    private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
    private ArraySet<View> mLowPriorityReorderingViews = new ArraySet<>();
    private ArraySet<View> mAddedChildren = new ArraySet<>();
    private boolean mPulsing;

    @Inject
    public VisualStabilityManager(NotificationEntryManager notificationEntryManager) {
        notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
            @Override
            public void onEntryReinflated(NotificationData.Entry entry) {
                if (entry.hasLowPriorityStateUpdated()) {
                    onLowPriorityUpdated(entry);
                    if (mPresenter != null) {
                        mPresenter.updateNotificationViews();
                    }
                }
            }
        });
    }

    public void setUpWithPresenter(NotificationPresenter presenter) {
        mPresenter = presenter;
    }

    /**
     * Add a callback to invoke when reordering is allowed again.
     * @param callback
     */
    public void addReorderingAllowedCallback(Callback callback) {
        if (mCallbacks.contains(callback)) {
            return;
        }
        mCallbacks.add(callback);
    }

    /**
     * Set the panel to be expanded.
     */
    public void setPanelExpanded(boolean expanded) {
        mPanelExpanded = expanded;
        updateReorderingAllowed();
    }

    /**
     * @param screenOn whether the screen is on
     */
    public void setScreenOn(boolean screenOn) {
        mScreenOn = screenOn;
        updateReorderingAllowed();
    }

    /**
     * @param pulsing whether we are currently pulsing for ambient display.
     */
    public void setPulsing(boolean pulsing) {
        if (mPulsing == pulsing) {
            return;
        }
        mPulsing = pulsing;
        updateReorderingAllowed();
    }

    private void updateReorderingAllowed() {
        boolean reorderingAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
        boolean changed = reorderingAllowed && !mReorderingAllowed;
        mReorderingAllowed = reorderingAllowed;
        if (changed) {
            notifyCallbacks();
        }
    }

    private void notifyCallbacks() {
        for (int i = 0; i < mCallbacks.size(); i++) {
            Callback callback = mCallbacks.get(i);
            callback.onReorderingAllowed();
        }
        mCallbacks.clear();
    }

    /**
     * @return whether reordering is currently allowed in general.
     */
    public boolean isReorderingAllowed() {
        return mReorderingAllowed;
    }

    /**
     * @return whether a specific notification is allowed to reorder. Certain notifications are
     * allowed to reorder even if {@link #isReorderingAllowed()} returns false, like newly added
     * notifications or heads-up notifications that are out of view.
     */
    public boolean canReorderNotification(ExpandableNotificationRow row) {
        if (mReorderingAllowed) {
            return true;
        }
        if (mAddedChildren.contains(row)) {
            return true;
        }
        if (mLowPriorityReorderingViews.contains(row)) {
            return true;
        }
        if (mAllowedReorderViews.contains(row)
                && !mVisibilityLocationProvider.isInVisibleLocation(row.getEntry())) {
            return true;
        }
        return false;
    }

    public void setVisibilityLocationProvider(
            VisibilityLocationProvider visibilityLocationProvider) {
        mVisibilityLocationProvider = visibilityLocationProvider;
    }

    public void onReorderingFinished() {
        mAllowedReorderViews.clear();
        mAddedChildren.clear();
        mLowPriorityReorderingViews.clear();
    }

    @Override
    public void onHeadsUpStateChanged(NotificationData.Entry entry, boolean isHeadsUp) {
        if (isHeadsUp) {
            // Heads up notifications should in general be allowed to reorder if they are out of
            // view and stay at the current location if they aren't.
            mAllowedReorderViews.add(entry.getRow());
        }
    }

    private void onLowPriorityUpdated(NotificationData.Entry entry) {
        mLowPriorityReorderingViews.add(entry.getRow());
    }

    /**
     * Notify the visual stability manager that a new view was added and should be allowed to
     * reorder next time.
     */
    public void notifyViewAddition(View view) {
        mAddedChildren.add(view);
    }

    public interface Callback {
        /**
         * Called when reordering is allowed again.
         */
        void onReorderingAllowed();
    }

}
