/*jslint single: true, long:true, for:true, unordered:true*/
/*global ScenesCommon*/

const TrailblazerScene = (function () {
    function getName() {
        return "Trailblazer";
    }

    function getIdentifier() {
        return "com.corsair.cc.sc.trailblazer";
    }

    function getParameters() {
        return [
            {
                name: "color_hint",
                title: "Define up to 7 colors for your scene.",
                type: "hint"
            },
            {
                name: "colors",
                title: "Colors",
                type: "color_list",
                min: 1,
                max: 6,
                default: ["#0000ff", "#00ff00", "#FC6500"]
            },
            {
                name: "background",
                title: "Background",
                type: "color",
                default: "#000000"
            },
            {
                name: "speed",
                title: "Speed",
                type: "int_enum",
/*jslint-disable*/
                values: {400: "Very Slow", 100: "Slow", 50: "Medium", 10: "Fast"},
/*jslint-enable*/
                default: 50
            },
            {
                name: "direction",
                title: "Direction",
                type: "int_enum",
/*jslint-disable*/
                values: {1: "Forward", 2: "Backwards"},
/*jslint-enable*/
                default: 1
            }
        ];
    }

    function generateScene(sceneID, sceneName, numLeds, parameters) {


        // Config
        const config = getParameters();
        const parameterColors = ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'colors');
        const background = ScenesCommon.colorFromHexString(ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'background'));
        const speed = ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'speed');
        const direction = ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'direction');

        const colors = [];
        let color;
        let i = 0;
        for (i = 0; i < parameterColors.length; i += 1) {
            color = ScenesCommon.colorFromHexString(parameterColors[i]);
            if (!ScenesCommon.colorEqual(color, ScenesCommon.BLACK_COLOR)) {
                colors.push(color);
            }
        }

        let sceneData = ScenesCommon.createSceneData(sceneID, numLeds, sceneName);
        let c = 0;

        for (c = 0; c < colors.length; c += 1) {
            color = colors[c];
            let j = 0;

            const randomSnakeLength = getRandomArbitrary(5, 40);
            const randomSnakeSpeed = getRandomArbitrary(speed * 0.4, speed * 1.3);

            // Cycle through all sets
            for (j = 0; j < numLeds; j += 1) {

                // Create scene data set
                let sceneDataSet = ScenesCommon.createSceneDataSet(numLeds, randomSnakeSpeed);

                if (parseInt(direction) === 1) {
                    for (i = 0; i < numLeds; i += 1) {
                        addSnakeToSceneDataSet(sceneDataSet, i, j, color, randomSnakeLength, background);
                    }
                } else {
                    for (i = numLeds - 1; i >= 0; i -= 1) {
                        addSnakeToSceneDataSet(sceneDataSet, i, j, color, randomSnakeLength, background);
                    }
                }

                // Add set
                sceneData.sceneDatas.push(sceneDataSet);
            }
        }

        return sceneData;
    }

    function addSnakeToSceneDataSet(sceneDataSet, i, offset, color, snakeLength, background) {
        if (i >= offset && i < offset + snakeLength) {
            ScenesCommon.pushColor(sceneDataSet.rgbArray, color);
        } else {
            ScenesCommon.pushColor(sceneDataSet.rgbArray, background);
        }
    }

    function getRandomArbitrary(min, max) {
        return Math.random() * (max - min) + min;
      }

    function getIcon() {
        return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 16 16">
<path id="icon" fill="#d8d8d8" fill-rule="evenodd" d="M6.709,4.598l-1.898,1.898c-0.775,0.774 -0.775,2.033 0,2.808c0.775,0.774 2.033,0.774 2.808,-0l1.391,-1.392c0.293,-0.292 0.768,-0.292 1.061,0c0.293,0.293 0.293,0.768 0,1.061l-1.391,1.391c-1.36,1.361 -3.569,1.361 -4.929,0c-1.361,-1.36 -1.361,-3.569 -0,-4.929l1.897,-1.898l1.061,1.061Zm0,-2.122l0.91,-0.91c0.293,-0.292 0.768,-0.292 1.061,0c0.293,0.293 0.293,0.768 -0,1.061l-0.91,0.91l-1.061,-1.061Zm2.754,8.754l1.726,-1.726c0.775,-0.774 0.775,-2.033 -0,-2.808c-0.775,-0.774 -2.033,-0.774 -2.808,0l-1.391,1.392c-0.293,0.292 -0.768,0.292 -1.061,-0c-0.293,-0.293 -0.293,-0.768 -0,-1.061l1.391,-1.391c1.36,-1.361 3.569,-1.361 4.929,-0c1.361,1.36 1.361,3.569 0,4.929l-1.725,1.726l-1.061,-1.061Zm-0,2.122l-1.082,1.082c-0.293,0.292 -0.768,0.292 -1.061,-0c-0.293,-0.293 -0.293,-0.768 0,-1.061l1.082,-1.082l1.061,1.061Z"/>
</svg>`;
    }
    
    function parametersForAIColors(parameters, colors, dynamism) {
        const config = getParameters();
        const background = ScenesCommon.valueOrDefaultFromParameters(parameters, config, "background");
        const speed = ScenesCommon.valueOrDefaultFromParameters(parameters, config, "speed");
        const direction = ScenesCommon.valueOrDefaultFromParameters(parameters, config, "direction");

        let result = {
            "colors": [],
            "background": background,
            "speed": speed,
            "direction": direction
        };

        if (colors === null) {
            colors = ScenesCommon.generateAIColorFromParameters(parameters, config);
        } else {
            colors = ScenesCommon.alterArrayForMinMaxParameterName(colors, config, "colors");
        }

        colors.forEach(function (color) {
            result.colors.push(color.colorString);
        });

        if (dynamism !== null) {
            let dynamismFloat = parseFloat(dynamism);

            if (dynamismFloat < ScenesCommon.DYNAMISM_SLOW) { // Slow
                result.speed = 100;
            } else if (dynamismFloat < ScenesCommon.DYNAMISM_MEDIUM) { // Medium
                result.speed = 50;
            } else if (dynamismFloat < ScenesCommon.DYNAMISM_FAST) { // Fast
                result.speed = 10;
            } else { // Fast, too
                result.speed = 10;
            }
        }

        return result;
    }

    return {
        name: getName,
        identifier: getIdentifier,
        parameters: getParameters,
        generate_scene: generateScene,
        icon: getIcon,
        "parametersForAIColors": parametersForAIColors
    };
}());


function getName() {
    return TrailblazerScene.name();
}

function getIdentifier() {
    return TrailblazerScene.identifier();
}

function getParameters() {
    return TrailblazerScene.parameters();
}

function generateScene(sceneID, sceneName, numLeds, parameters) {
    return TrailblazerScene.generate_scene(sceneID, sceneName, numLeds, parameters);
}

function getIcon() {
    return TrailblazerScene.icon();
}

function parametersForAIColors(parameters, colors, dynamism) {
    return TrailblazerScene.parametersForAIColors(parameters, colors, dynamism);
}