/*
 * 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;

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

    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();
        }

        /**
         * Whether to timeout wallpaper or not.
         */
        @Override
        public boolean shouldTimeoutWallpaper() {
            return mPulseReason == DozeLog.PULSE_REASON_DOCKING;
        }
    };

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

    @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);
    }

    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() {
        DozeLog.tracePulseStart(mPulseReason);
        if (mPulseCallback != null) {
            mPulseCallback.onPulseStarted();
        }
    }

    private void pulseFinished() {
        DozeLog.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);
    }
}