/*
 * Copyright (C) 2015 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.graphics.drawable;

import android.animation.Animator;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.DisplayListCanvas;
import android.view.RenderNodeAnimator;

import java.util.ArrayList;

/**
 * Abstract class that handles hardware/software hand-off and lifecycle for
 * animated ripple foreground and background components.
 */
abstract class RippleComponent {
    private final RippleDrawable mOwner;

    /** Bounds used for computing max radius. May be modified by the owner. */
    protected final Rect mBounds;

    /** Whether we can use hardware acceleration for the exit animation. */
    private boolean mHasDisplayListCanvas;

    private boolean mHasPendingHardwareAnimator;
    private RenderNodeAnimatorSet mHardwareAnimator;

    private Animator mSoftwareAnimator;

    /** Whether we have an explicit maximum radius. */
    private boolean mHasMaxRadius;

    /** How big this ripple should be when fully entered. */
    protected float mTargetRadius;

    /** Screen density used to adjust pixel-based constants. */
    protected float mDensity;

    public RippleComponent(RippleDrawable owner, Rect bounds) {
        mOwner = owner;
        mBounds = bounds;
    }

    public void onBoundsChange() {
        if (!mHasMaxRadius) {
            mTargetRadius = getTargetRadius(mBounds);
            onTargetRadiusChanged(mTargetRadius);
        }
    }

    public final void setup(float maxRadius, float density) {
        if (maxRadius >= 0) {
            mHasMaxRadius = true;
            mTargetRadius = maxRadius;
        } else {
            mTargetRadius = getTargetRadius(mBounds);
        }

        mDensity = density;

        onTargetRadiusChanged(mTargetRadius);
    }

    private static float getTargetRadius(Rect bounds) {
        final float halfWidth = bounds.width() / 2.0f;
        final float halfHeight = bounds.height() / 2.0f;
        return (float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight);
    }

    /**
     * Starts a ripple enter animation.
     *
     * @param fast whether the ripple should enter quickly
     */
    public final void enter(boolean fast) {
        cancel();

        mSoftwareAnimator = createSoftwareEnter(fast);

        if (mSoftwareAnimator != null) {
            mSoftwareAnimator.start();
        }
    }

    /**
     * Starts a ripple exit animation.
     */
    public final void exit() {
        cancel();

        if (mHasDisplayListCanvas) {
            // We don't have access to a canvas here, but we expect one on the
            // next frame. We'll start the render thread animation then.
            mHasPendingHardwareAnimator = true;

            // Request another frame.
            invalidateSelf();
        } else {
            mSoftwareAnimator = createSoftwareExit();
            mSoftwareAnimator.start();
        }
    }

    /**
     * Cancels all animations. Software animation values are left in the
     * current state, while hardware animation values jump to the end state.
     */
    public void cancel() {
        cancelSoftwareAnimations();
        endHardwareAnimations();
    }

    /**
     * Ends all animations, jumping values to the end state.
     */
    public void end() {
        endSoftwareAnimations();
        endHardwareAnimations();
    }

    /**
     * Draws the ripple to the canvas, inheriting the paint's color and alpha
     * properties.
     *
     * @param c the canvas to which the ripple should be drawn
     * @param p the paint used to draw the ripple
     * @return {@code true} if something was drawn, {@code false} otherwise
     */
    public boolean draw(Canvas c, Paint p) {
        final boolean hasDisplayListCanvas = c.isHardwareAccelerated()
                && c instanceof DisplayListCanvas;
        if (mHasDisplayListCanvas != hasDisplayListCanvas) {
            mHasDisplayListCanvas = hasDisplayListCanvas;

            if (!hasDisplayListCanvas) {
                // We've switched from hardware to non-hardware mode. Panic.
                endHardwareAnimations();
            }
        }

        if (hasDisplayListCanvas) {
            final DisplayListCanvas hw = (DisplayListCanvas) c;
            startPendingAnimation(hw, p);

            if (mHardwareAnimator != null) {
                return drawHardware(hw);
            }
        }

        return drawSoftware(c, p);
    }

    /**
     * Populates {@code bounds} with the maximum drawing bounds of the ripple
     * relative to its center. The resulting bounds should be translated into
     * parent drawable coordinates before use.
     *
     * @param bounds the rect to populate with drawing bounds
     */
    public void getBounds(Rect bounds) {
        final int r = (int) Math.ceil(mTargetRadius);
        bounds.set(-r, -r, r, r);
    }

    /**
     * Starts the pending hardware animation, if available.
     *
     * @param hw hardware canvas on which the animation should draw
     * @param p paint whose properties the hardware canvas should use
     */
    private void startPendingAnimation(DisplayListCanvas hw, Paint p) {
        if (mHasPendingHardwareAnimator) {
            mHasPendingHardwareAnimator = false;

            mHardwareAnimator = createHardwareExit(new Paint(p));
            mHardwareAnimator.start(hw);

            // Preemptively jump the software values to the end state now that
            // the hardware exit has read whatever values it needs.
            jumpValuesToExit();
        }
    }

    /**
     * Cancels any current software animations, leaving the values in their
     * current state.
     */
    private void cancelSoftwareAnimations() {
        if (mSoftwareAnimator != null) {
            mSoftwareAnimator.cancel();
            mSoftwareAnimator = null;
        }
    }

    /**
     * Ends any current software animations, jumping the values to their end
     * state.
     */
    private void endSoftwareAnimations() {
        if (mSoftwareAnimator != null) {
            mSoftwareAnimator.end();
            mSoftwareAnimator = null;
        }
    }

    /**
     * Ends any pending or current hardware animations.
     * <p>
     * Hardware animations can't synchronize values back to the software
     * thread, so there is no "cancel" equivalent.
     */
    private void endHardwareAnimations() {
        if (mHardwareAnimator != null) {
            mHardwareAnimator.end();
            mHardwareAnimator = null;
        }

        if (mHasPendingHardwareAnimator) {
            mHasPendingHardwareAnimator = false;

            // Manually jump values to their exited state. Normally we'd do that
            // later when starting the hardware exit, but we're aborting early.
            jumpValuesToExit();
        }
    }

    protected final void invalidateSelf() {
        mOwner.invalidateSelf(false);
    }

    protected final boolean isHardwareAnimating() {
        return mHardwareAnimator != null && mHardwareAnimator.isRunning()
                || mHasPendingHardwareAnimator;
    }

    protected final void onHotspotBoundsChanged() {
        if (!mHasMaxRadius) {
            final float halfWidth = mBounds.width() / 2.0f;
            final float halfHeight = mBounds.height() / 2.0f;
            final float targetRadius = (float) Math.sqrt(halfWidth * halfWidth
                    + halfHeight * halfHeight);

            onTargetRadiusChanged(targetRadius);
        }
    }

    /**
     * Called when the target radius changes.
     *
     * @param targetRadius the new target radius
     */
    protected void onTargetRadiusChanged(float targetRadius) {
        // Stub.
    }

    protected abstract Animator createSoftwareEnter(boolean fast);

    protected abstract Animator createSoftwareExit();

    protected abstract RenderNodeAnimatorSet createHardwareExit(Paint p);

    protected abstract boolean drawHardware(DisplayListCanvas c);

    protected abstract boolean drawSoftware(Canvas c, Paint p);

    /**
     * Called when the hardware exit is cancelled. Jumps software values to end
     * state to ensure that software and hardware values are synchronized.
     */
    protected abstract void jumpValuesToExit();

    public static class RenderNodeAnimatorSet {
        private final ArrayList<RenderNodeAnimator> mAnimators = new ArrayList<>();

        public void add(RenderNodeAnimator anim) {
            mAnimators.add(anim);
        }

        public void clear() {
            mAnimators.clear();
        }

        public void start(DisplayListCanvas target) {
            if (target == null) {
                throw new IllegalArgumentException("Hardware canvas must be non-null");
            }

            final ArrayList<RenderNodeAnimator> animators = mAnimators;
            final int N = animators.size();
            for (int i = 0; i < N; i++) {
                final RenderNodeAnimator anim = animators.get(i);
                anim.setTarget(target);
                anim.start();
            }
        }

        public void cancel() {
            final ArrayList<RenderNodeAnimator> animators = mAnimators;
            final int N = animators.size();
            for (int i = 0; i < N; i++) {
                final RenderNodeAnimator anim = animators.get(i);
                anim.cancel();
            }
        }

        public void end() {
            final ArrayList<RenderNodeAnimator> animators = mAnimators;
            final int N = animators.size();
            for (int i = 0; i < N; i++) {
                final RenderNodeAnimator anim = animators.get(i);
                anim.end();
            }
        }

        public boolean isRunning() {
            final ArrayList<RenderNodeAnimator> animators = mAnimators;
            final int N = animators.size();
            for (int i = 0; i < N; i++) {
                final RenderNodeAnimator anim = animators.get(i);
                if (anim.isRunning()) {
                    return true;
                }
            }
            return false;
        }
    }
}
