/*
 * 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 = {};

        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;

        data.currentX = context.currentX;
        data.currentY = context.currentY;
        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]();
    }
};
