/*
 * Copyright (C) 2018 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.RecordingState = class RecordingState
{
    constructor(data, {source} = {})
    {
        this._data = data;
        this._source = source || null;
    }

    // Static

    static fromContext(type, context, options = {})
    {
        if (type !== WI.Recording.Type.Canvas2D)
            return null;

        let matrix = context.getTransform();

        let data = {};

        if (WI.ImageUtilities.supportsCanvasPathDebugging()) {
            data.currentX = context.currentX;
            data.currentY = context.currentY;
        }

        data.direction = context.direction;
        data.fillStyle = context.fillStyle;
        data.font = context.font;
        data.globalAlpha = context.globalAlpha;
        data.globalCompositeOperation = context.globalCompositeOperation;
        data.imageSmoothingEnabled = context.imageSmoothingEnabled;
        data.imageSmoothingQuality = context.imageSmoothingQuality;
        data.lineCap = context.lineCap;
        data.lineDash = context.getLineDash();
        data.lineDashOffset = context.lineDashOffset;
        data.lineJoin = context.lineJoin;
        data.lineWidth = context.lineWidth;
        data.miterLimit = context.miterLimit;
        data.shadowBlur = context.shadowBlur;
        data.shadowColor = context.shadowColor;
        data.shadowOffsetX = context.shadowOffsetX;
        data.shadowOffsetY = context.shadowOffsetY;
        data.strokeStyle = context.strokeStyle;
        data.textAlign = context.textAlign;
        data.textBaseline = context.textBaseline;
        data.transform = [matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f];
        data.webkitImageSmoothingEnabled = context.webkitImageSmoothingEnabled;
        data.webkitLineDash = context.webkitLineDash;
        data.webkitLineDashOffset = context.webkitLineDashOffset;

        if (WI.ImageUtilities.supportsCanvasPathDebugging())
            data.setPath = [context.getPath()];

        return new WI.RecordingState(data, options);
    }

    static async swizzleInitialState(recording, initialState)
    {
        if (recording.type === WI.Recording.Type.Canvas2D) {
            let swizzledState = {};

            for (let [name, value] of Object.entries(initialState)) {
                // COMPATIBILITY (iOS 12.0): Recording.InitialState.states did not exist yet
                let nameIndex = parseInt(name);
                if (!isNaN(nameIndex))
                    name = await recording.swizzle(nameIndex, WI.Recording.Swizzle.String);

                switch (name) {
                case "setTransform":
                    value = [await recording.swizzle(value, WI.Recording.Swizzle.DOMMatrix)];
                    break;

                case "fillStyle":
                case "strokeStyle":
                    var [gradient, pattern, string] = await Promise.all([
                        recording.swizzle(value, WI.Recording.Swizzle.CanvasGradient),
                        recording.swizzle(value, WI.Recording.Swizzle.CanvasPattern),
                        recording.swizzle(value, WI.Recording.Swizzle.String),
                    ]);
                    if (gradient && !pattern)
                        value = gradient;
                    else if (pattern && !gradient)
                        value = pattern;
                    else
                        value = string;
                    break;

                case "direction":
                case "font":
                case "globalCompositeOperation":
                case "imageSmoothingQuality":
                case "lineCap":
                case "lineJoin":
                case "shadowColor":
                case "textAlign":
                case "textBaseline":
                    value = await recording.swizzle(value, WI.Recording.Swizzle.String);
                    break;

                case "globalAlpha":
                case "lineWidth":
                case "miterLimit":
                case "shadowOffsetX":
                case "shadowOffsetY":
                case "shadowBlur":
                case "lineDashOffset":
                    value = await recording.swizzle(value, WI.Recording.Swizzle.Number);
                    break;

                case "setPath":
                    value = [await recording.swizzle(value[0], WI.Recording.Swizzle.Path2D)];
                    break;
                }

                if (value === undefined || (Array.isArray(value) && value.includes(undefined)))
                    continue;

                swizzledState[name] = value;
            }

            return new WI.RecordingState(swizzledState);
        }

        return null;
    }

    // Public

    get source() { return this._source; }

    has(name)
    {
        return name in this._data;
    }

    get(name)
    {
        return this._data[name];
    }

    apply(type, context)
    {
        for (let [name, value] of this) {
            if (!(name in context))
                continue;

            // Skip internal state used for path debugging.
            if (name === "currentX" || name === "currentY")
                continue;

            try {
                if (WI.RecordingAction.isFunctionForType(type, name))
                    context[name](...value);
                else
                    context[name] = value;
            } catch { }
        }
    }

    toJSON()
    {
        return this._data;
    }

    [Symbol.iterator]()
    {
        return Object.entries(this._data)[Symbol.iterator]();
    }
};
