/*
 * 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.annotation.NonNull;
import android.os.Handler;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;

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

/**
 * Controller which handles all the doze animations of the scrims.
 */
@Singleton
public class DozeScrimController implements StateListener {
    private static final String TAG = "DozeScrimController";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    private final DozeLog mDozeLog;
    private final DozeParameters mDozeParameters;
    private final Handler mHandler = new Handler();

    private boolean mDozing;
    private DozeHost.PulseCallback mPulseCallback;
    private int mPulseReason;
    private boolean mFullyPulsing;

    private final ScrimController.Callback mScrimCallback = new ScrimController.Callback() {
        @Override
        public void onDisplayBlanked() {
            if (DEBUG) {
                Log.d(TAG, "Pulse in, mDozing=" + mDozing + " mPulseReason="
                        + DozeLog.reasonToString(mPulseReason));
            }
            if (!mDozing) {
                return;
            }

            // Signal that the pulse is ready to turn the screen on and draw.
            pulseStarted();
        }

        @Override
        public void onFinished() {
            if (DEBUG) {
                Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
            }
            if (!mDozing) {
                return;
            }
            // Notifications should time out on their own.  Pulses due to notifications should
            // instead be managed externally based off the notification's lifetime.
            // Dock also controls the time out by self.
            if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION
                    && mPulseReason != DozeLog.PULSE_REASON_DOCKING) {
                mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
                mHandler.postDelayed(mPulseOutExtended,
                        mDozeParameters.getPulseVisibleDurationExtended());
            }
            mFullyPulsing = true;
        }

        /**
         * Transition was aborted before it was over.
         */
        @Override
        public void onCancelled() {
            pulseFinished();
        }
    };

    @Inject
    public DozeScrimController(DozeParameters dozeParameters, DozeLog dozeLog) {
        mDozeParameters = dozeParameters;
        //Never expected to be destroyed
        Dependency.get(StatusBarStateController.class).addCallback(this);
        mDozeLog = dozeLog;
    }

    @VisibleForTesting
    public void setDozing(boolean dozing) {
        if (mDozing == dozing) return;
        mDozing = dozing;
        if (!mDozing) {
            cancelPulsing();
        }
    }

    /** When dozing, fade screen contents in and out using the front scrim. */
    public void pulse(@NonNull DozeHost.PulseCallback callback, int reason) {
        if (callback == null) {
            throw new IllegalArgumentException("callback must not be null");
        }

        if (!mDozing || mPulseCallback != null) {
            if (DEBUG) {
                Log.d(TAG, "Pulse supressed. Dozing: " + mDozeParameters + " had callback? "
                        + (mPulseCallback != null));
            }
            // Pulse suppressed.
            callback.onPulseFinished();
            return;
        }

        // Begin pulse. Note that it's very important that the pulse finished callback
        // be invoked when we're done so that the caller can drop the pulse wakelock.
        mPulseCallback = callback;
        mPulseReason = reason;
    }

    public void pulseOutNow() {
        if (mPulseCallback != null && mFullyPulsing) {
            mPulseOut.run();
        }
    }

    public boolean isPulsing() {
        return mPulseCallback != null;
    }

    public boolean isDozing() {
        return mDozing;
    }

    public void extendPulse() {
        mHandler.removeCallbacks(mPulseOut);
    }

    /**
     * When pulsing, cancel any timeouts that would take you out of the pulsing state.
     */
    public void cancelPendingPulseTimeout() {
        mHandler.removeCallbacks(mPulseOut);
        mHandler.removeCallbacks(mPulseOutExtended);
    }

    private void cancelPulsing() {
        if (mPulseCallback != null) {
            if (DEBUG) Log.d(TAG, "Cancel pulsing");
            mFullyPulsing = false;
            mHandler.removeCallbacks(mPulseOut);
            mHandler.removeCallbacks(mPulseOutExtended);
            pulseFinished();
        }
    }

    private void pulseStarted() {
        mDozeLog.tracePulseStart(mPulseReason);
        if (mPulseCallback != null) {
            mPulseCallback.onPulseStarted();
        }
    }

    private void pulseFinished() {
        mDozeLog.tracePulseFinish();
        if (mPulseCallback != null) {
            mPulseCallback.onPulseFinished();
            mPulseCallback = null;
        }
    }

    private final Runnable mPulseOutExtended = new Runnable() {
        @Override
        public void run() {
            mHandler.removeCallbacks(mPulseOut);
            mPulseOut.run();
        }
    };

    private final Runnable mPulseOut = new Runnable() {
        @Override
        public void run() {
            mFullyPulsing = false;
            mHandler.removeCallbacks(mPulseOut);
            mHandler.removeCallbacks(mPulseOutExtended);
            if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
            if (!mDozing) return;
            pulseFinished();
        }
    };

    public ScrimController.Callback getScrimCallback() {
        return mScrimCallback;
    }

    @Override
    public void onStateChanged(int newState) {
        // don't care
    }

    @Override
    public void onDozingChanged(boolean isDozing) {
        setDozing(isDozing);
    }
}