/*
 * 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 android.view;

import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.graphics.Insets;
import android.view.WindowInsets.Type.InsetsType;
import android.view.WindowInsetsAnimation.Bounds;

/**
 * Controller for app-driven animation of system windows.
 *  <p>
 *  {@code WindowInsetsAnimationController} lets apps animate system windows such as
 *  the {@link android.inputmethodservice.InputMethodService IME}. The animation is
 *  synchronized, such that changes the system windows and the app's current frame
 *  are rendered at the same time.
 *  <p>
 *  Control is obtained through {@link WindowInsetsController#controlWindowInsetsAnimation}.
 */
@SuppressLint("NotCloseable")
public interface WindowInsetsAnimationController {

    /**
     * Retrieves the {@link Insets} when the windows this animation is controlling are fully hidden.
     * <p>
     * Note that these insets are always relative to the window, which is the same as being relative
     * to {@link View#getRootView}
     * <p>
     * If there are any animation listeners registered, this value is the same as
     * {@link Bounds#getLowerBound()} that is being be passed into the root view of the
     * hierarchy.
     *
     * @return Insets when the windows this animation is controlling are fully hidden.
     *
     * @see Bounds#getLowerBound()
     */
    @NonNull Insets getHiddenStateInsets();

    /**
     * Retrieves the {@link Insets} when the windows this animation is controlling are fully shown.
     * <p>
     * Note that these insets are always relative to the window, which is the same as being relative
     * to {@link View#getRootView}
     * <p>
     * If there are any animation listeners registered, this value is the same as
     * {@link Bounds#getUpperBound()} that is being passed into the root view of hierarchy.
     *
     * @return Insets when the windows this animation is controlling are fully shown.
     *
     * @see Bounds#getUpperBound()
     */
    @NonNull Insets getShownStateInsets();

    /**
     * Retrieves the current insets.
     * <p>
     * Note that these insets are always relative to the window, which is the same as
     * being relative
     * to {@link View#getRootView}
     * @return The current insets on the currently showing frame. These insets will change as the
     * animation progresses to reflect the current insets provided by the controlled window.
     */
    @NonNull Insets getCurrentInsets();

    /**
     *  Returns the progress as previously set by {@code fraction} in {@link #setInsetsAndAlpha}
     *
     *  @return the progress of the animation, where {@code 0} is fully hidden and {@code 1} is
     *  fully shown.
     * <p>
     *  Note: this value represents raw overall progress of the animation
     *  i.e. the combined progress of insets and alpha.
     *  <p>
     */
    @FloatRange(from = 0f, to = 1f)
    float getCurrentFraction();

    /**
     * Current alpha value of the window.
     * @return float value between 0 and 1.
     */
    float getCurrentAlpha();

    /**
     * @return The {@link InsetsType}s this object is currently controlling.
     */
    @InsetsType int getTypes();

    /**
     * Modifies the insets for the frame being drawn by indirectly moving the windows around in the
     * system that are causing window insets.
     * <p>
     * Note that these insets are always relative to the window, which is the same as being relative
     * to {@link View#getRootView}
     * <p>
     * Also note that this will <b>not</b> inform the view system of a full inset change via
     * {@link View#dispatchApplyWindowInsets} in order to avoid a full layout pass during the
     * animation. If you'd like to animate views during a window inset animation, register a
     * {@link WindowInsetsAnimation.Callback} by calling
     * {@link View#setWindowInsetsAnimationCallback(WindowInsetsAnimation.Callback)} that will be
     * notified about any insets change via {@link WindowInsetsAnimation.Callback#onProgress} during
     * the animation.
     * <p>
     * {@link View#dispatchApplyWindowInsets} will instead be called once the animation has
     * finished, i.e. once {@link #finish} has been called.
     * Note: If there are no insets, alpha animation is still applied.
     *
     * @param insets The new insets to apply. Based on the requested insets, the system will
     *               calculate the positions of the windows in the system causing insets such that
     *               the resulting insets of that configuration will match the passed in parameter.
     *               Note that these insets are being clamped to the range from
     *               {@link #getHiddenStateInsets} to {@link #getShownStateInsets}.
     *               If you intend on changing alpha only, pass null or {@link #getCurrentInsets()}.
     * @param alpha  The new alpha to apply to the inset side.
     * @param fraction instantaneous animation progress. This value is dispatched to
     *                 {@link WindowInsetsAnimation.Callback}.
     *
     * @see WindowInsetsAnimation.Callback
     * @see View#setWindowInsetsAnimationCallback(WindowInsetsAnimation.Callback)
     */
    void setInsetsAndAlpha(@Nullable Insets insets, @FloatRange(from = 0f, to = 1f) float alpha,
            @FloatRange(from = 0f, to = 1f) float fraction);

    /**
     * Finishes the animation, and leaves the windows shown or hidden.
     * <p>
     * After invoking {@link #finish}, this instance is no longer {@link #isReady ready}.
     * <p>
     * Note: Finishing an animation implicitly {@link #setInsetsAndAlpha sets insets and alpha}
     * according to the requested end state without any further animation.
     *
     * @param shown if {@code true}, the windows will be shown after finishing the
     *              animation. Otherwise they will be hidden.
     */
    void finish(boolean shown);

    /**
     * Returns whether this instance is ready to be used to control window insets.
     * <p>
     * Instances are ready when passed in {@link WindowInsetsAnimationControlListener#onReady}
     * and stop being ready when it is either {@link #isFinished() finished} or
     * {@link #isCancelled() cancelled}.
     *
     * @return {@code true} if the instance is ready, {@code false} otherwise.
     */
    default boolean isReady() {
        return !isFinished() && !isCancelled();
    }

    /**
     * Returns whether this instance has been finished by a call to {@link #finish}.
     *
     * @see WindowInsetsAnimationControlListener#onFinished
     * @return {@code true} if the instance is finished, {@code false} otherwise.
     */
    boolean isFinished();

    /**
     * Returns whether this instance has been cancelled by the system, or by invoking the
     * {@link android.os.CancellationSignal} passed into
     * {@link WindowInsetsController#controlWindowInsetsAnimation}.
     *
     * @see WindowInsetsAnimationControlListener#onCancelled
     * @return {@code true} if the instance is cancelled, {@code false} otherwise.
     */
    boolean isCancelled();
}
