/*
 * Copyright (C) 2020 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.Animation = class Animation extends WI.Object
{
    constructor(animationId, {cssAnimationName, cssTransitionProperty, effect, backtrace} = {})
    {
        super();

        console.assert(animationId);
        console.assert((!cssAnimationName && !cssTransitionProperty) || !!cssAnimationName !== !!cssTransitionProperty);

        this._animationId = animationId;

        this._cssAnimationName = cssAnimationName || null;
        this._cssTransitionProperty = cssTransitionProperty || null;
        this._updateEffect(effect);
        this._backtrace = backtrace || [];

        this._effectTarget = undefined;
        this._requestEffectTargetCallbacks = null;
    }

    // Static

    static fromPayload(payload)
    {
        return new WI.Animation(payload.animationId, {
            cssAnimationName: payload.cssAnimationName,
            cssTransitionProperty: payload.cssTransitionProperty,
            effect: payload.effect,
            backtrace: Array.isArray(payload.backtrace) ? payload.backtrace.map((item) => WI.CallFrame.fromPayload(WI.mainTarget, item)) : [],
        });
    }

    static displayNameForAnimationType(animationType, plural)
    {
        switch (animationType) {
        case WI.Animation.Type.WebAnimation:
            return plural ? WI.UIString("Web Animations") : WI.UIString("Web Animation");
        case WI.Animation.Type.CSSAnimation:
            return plural ? WI.UIString("CSS Animations") : WI.UIString("CSS Animation");
        case WI.Animation.Type.CSSTransition:
            return plural ? WI.UIString("CSS Transitions") : WI.UIString("CSS Transition");
        }

        console.assert(false, "Unknown animation type", animationType);
        return null;
    }

    static displayNameForPlaybackDirection(playbackDirection)
    {
        switch (playbackDirection) {
        case WI.Animation.PlaybackDirection.Normal:
            return WI.UIString("Normal", "Web Animation Playback Direction Normal", "Indicates that the playback direction of this web animation is normal (e.g. forwards)");
        case WI.Animation.PlaybackDirection.Reverse:
            return WI.UIString("Reverse", "Web Animation Playback Direction Reverse", "Indicates that the playback direction of this web animation is reversed (e.g. backwards)");
        case WI.Animation.PlaybackDirection.Alternate:
            return WI.UIString("Alternate", "Web Animation Playback Direction Alternate", "Indicates that the playback direction of this web animation alternates between normal and reversed on each iteration");
        case WI.Animation.PlaybackDirection.AlternateReverse:
            return WI.UIString("Alternate Reverse", "Web Animation Playback Direction Alternate Reverse", "Indicates that the playback direction of this web animation alternates between reversed and normal on each iteration");
        }

        console.assert(false, "Unknown playback direction", playbackDirection);
        return null;
    }

    static displayNameForFillMode(fillMode)
    {
        switch (fillMode) {
        case WI.Animation.FillMode.None:
            return WI.UIString("None", "Web Animation Fill Mode None", "Indicates that this web animation does not apply any styles before it begins and after it ends");
        case WI.Animation.FillMode.Forwards:
            return WI.UIString("Forwards", "Web Animation Fill Mode Forwards", "Indicates that this web animation also applies styles after it ends");
        case WI.Animation.FillMode.Backwards:
            return WI.UIString("Backwards", "Web Animation Fill Mode Backwards", "Indicates that this web animation also applies styles before it begins");
        case WI.Animation.FillMode.Both:
            return WI.UIString("Both", "Web Animation Fill Mode Both", "Indicates that this web animation also applies styles before it begins and after it ends");
        case WI.Animation.FillMode.Auto:
            return WI.UIString("Auto", "Web Animation Fill Mode Auto", "Indicates that this web animation either does not apply any styles before it begins and after it ends or that it applies to both, depending on it's configuration");
        }

        console.assert(false, "Unknown fill mode", fillMode);
        return null;
    }

    static resetUniqueDisplayNameNumbers()
    {
        WI.Animation._nextUniqueDisplayNameNumber = 1;
    }

    // Public

    get animationId() { return this._animationId; }
    get backtrace() { return this._backtrace; }

    get animationType()
    {
        if (this._cssAnimationName)
            return WI.Animation.Type.CSSAnimation;
        if (this._cssTransitionProperty)
            return WI.Animation.Type.CSSTransition;
        return WI.Animation.Type.WebAnimation;
    }

    get startDelay()
    {
        return "startDelay" in this._effect ? this._effect.startDelay : NaN;
    }

    get endDelay()
    {
        return "endDelay" in this._effect ? this._effect.endDelay : NaN;
    }

    get iterationCount()
    {
        return "iterationCount" in this._effect ? this._effect.iterationCount : NaN;
    }

    get iterationStart()
    {
        return "iterationStart" in this._effect ? this._effect.iterationStart : NaN;
    }

    get iterationDuration()
    {
        return "iterationDuration" in this._effect ? this._effect.iterationDuration : NaN;
    }

    get timingFunction()
    {
        return "timingFunction" in this._effect ? this._effect.timingFunction : null;
    }

    get playbackDirection()
    {
        return "playbackDirection" in this._effect ? this._effect.playbackDirection : null;
    }

    get fillMode()
    {
        return "fillMode" in this._effect ? this._effect.fillMode : null;
    }

    get keyframes()
    {
        return "keyframes" in this._effect ? this._effect.keyframes : [];
    }

    get displayName()
    {
        if (this._cssAnimationName)
            return this._cssAnimationName;

        if (this._cssTransitionProperty)
            return this._cssTransitionProperty;

        if (!this._uniqueDisplayNameNumber)
            this._uniqueDisplayNameNumber = WI.Animation._nextUniqueDisplayNameNumber++;
        return WI.UIString("Animation %d").format(this._uniqueDisplayNameNumber);
    }

    requestEffectTarget(callback)
    {
        if (this._effectTarget !== undefined) {
            callback(this._effectTarget);
            return;
        }

        if (this._requestEffectTargetCallbacks) {
            this._requestEffectTargetCallbacks.push(callback);
            return;
        }

        this._requestEffectTargetCallbacks = [callback];

        WI.domManager.ensureDocument();

        let target = WI.assumingMainTarget();
        target.AnimationAgent.requestEffectTarget(this._animationId, (error, nodeId) => {
            this._effectTarget = !error ? WI.domManager.nodeForId(nodeId) : null;

            for (let requestEffectTargetCallback of this._requestEffectTargetCallbacks)
                requestEffectTargetCallback(this._effectTarget);

            this._requestEffectTargetCallbacks = null;
        });
    }

    // AnimationManager

    effectChanged(effect)
    {
        this._updateEffect(effect);
    }

    targetChanged()
    {
        this._effectTarget = undefined;

        this.dispatchEventToListeners(WI.Animation.Event.TargetChanged);
    }

    // Private

    _updateEffect(effect)
    {
        this._effect = effect || {};

        if (this._effect.timingFunction)
            this._effect.timingFunction = WI.CubicBezier.fromString(this._effect.timingFunction);

        if (this._effect.keyframes) {
            for (let keyframe of this._effect.keyframes) {
                if (keyframe.easing)
                    keyframe.easing = WI.CubicBezier.fromString(keyframe.easing);

                if (keyframe.style)
                    keyframe.style = keyframe.style.replaceAll(/;\s+/g, ";\n");
            }
        }

        this.dispatchEventToListeners(WI.Animation.Event.EffectChanged);
    }
};

WI.Animation._nextUniqueDisplayNameNumber = 1;

WI.Animation.Type = {
    WebAnimation: "web-animation",
    CSSAnimation: "css-animation",
    CSSTransition: "css-transition",
};

WI.Animation.PlaybackDirection = {
    Normal: "normal",
    Reverse: "reverse",
    Alternate: "alternate",
    AlternateReverse: "alternate-reverse",
};

WI.Animation.FillMode = {
    None: "none",
    Forwards: "forwards",
    Backwards: "backwards",
    Both: "both",
    Auto: "auto",
};

WI.Animation.Event = {
    EffectChanged: "animation-effect-changed",
    TargetChanged: "animation-target-changed",
};
