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

const TrickleScene = (function () {
    const DISTANCE = 20;
    const LENGTH = 3;
    const BACKGROUND_SPEED_FACTOR = 4;

    function getName() {
        return "Trickle";
    }

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

    function getParameters() {
        return [
            {
                name: "color_hint",
                title: "Define 2 colors for your scene.",
                type: "hint"
            },
            {
                name: "foreground",
                title: "Foreground",
                type: "color",
                default: "#0000ff"
            },
            {
                name: "background",
                title: "Background",
                type: "color",
                default: "#261300"
            },
            {
                name: "speed",
                title: "Speed",
                type: "int_enum",
/*jslint-disable*/
                values: {300: "Very Slow", 100: "Slow", 55: "Medium", 10: "Fast"},
/*jslint-enable*/
                default: 55
            },
            {
                name: "direction",
                title: "Direction",
                type: "int_enum",
/*jslint-disable*/
                values: {1: "Forward", 2: "Backwards"},
/*jslint-enable*/
                default: 1
            }
        ];
    }

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

        const config = getParameters();
        const background = ScenesCommon.colorFromHexString(ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'background'));
        const foreground = ScenesCommon.colorFromHexString(ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'foreground'));
        const speed = ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'speed');
        const direction = ScenesCommon.valueOrDefaultFromParameters(parameters, config, 'direction');

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

        // Create "pulsing" background
        // fade to color, then fade to black, then stay on black for a bit
        let totalBackgroundSteps = DISTANCE * BACKGROUND_SPEED_FACTOR;
        let fadeBackgroundSteps = Math.round(totalBackgroundSteps * 0.45);
        let blackBackgroundSteps = Math.round(totalBackgroundSteps * 0.1);

        let colorGradient = ScenesCommon.gradientColors(ScenesCommon.BLACK_COLOR, background, fadeBackgroundSteps);
        let reversedColorGradient = colorGradient.slice().reverse();
        let blackGradient = ScenesCommon.gradientColors(ScenesCommon.BLACK_COLOR, ScenesCommon.BLACK_COLOR, blackBackgroundSteps);

        let backgroundColors = colorGradient.concat(reversedColorGradient).concat(blackGradient);

        // To make background pulsing slower than one ants cycle, spread background colors across BACKGROUND_SPEED_FACTORx ants cycles
        if (parseInt(direction) === 1) {
            for (i = 0; i < totalBackgroundSteps; i += 1) {
                addAntsToSceneData(sceneData, i % DISTANCE, numLeds, speed, backgroundColors[i], foreground);
            }
        } else {
            for (i = totalBackgroundSteps - 1; i >= 0; i -= 1) {
                addAntsToSceneData(sceneData, i % DISTANCE, numLeds, speed, backgroundColors[i], foreground);
            }
        }

        return sceneData;
    }

    function addAntsToSceneData(sceneData, setIndex, numLeds, speed, background, foreground) {

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

        let antStart = setIndex % DISTANCE;
        let antEnd = (setIndex + LENGTH) % DISTANCE;
        let led = 0;

        // Set colors
        for (led = 0; led < numLeds; led += 1) {
            let antLed = led % DISTANCE;

            if (((antLed >= antStart) && (antLed < (antStart + LENGTH))) || ((antEnd < antStart) && (antEnd > antLed))) {
                ScenesCommon.pushColor(sceneDataSet.rgbArray, foreground);
            } else {
                ScenesCommon.pushColor(sceneDataSet.rgbArray, background);
            }
        }

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

    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="M10.298,3.573c0.195,0.195 0.195,0.512 0,0.707l-0.768,0.768c-0.195,0.195 -0.512,0.195 -0.707,0c-0.195,-0.195 -0.195,-0.512 0,-0.707l0.414,-0.414l-1.767,-1.768c-0.195,-0.195 -0.195,-0.512 -0,-0.707c0.195,-0.195 0.512,-0.195 0.707,-0l2.121,2.121Zm-6.337,5.663l0.442,-0.442c0.191,-0.191 0.5,-0.191 0.691,-0c0.191,0.19 0.191,0.5 0,0.69l-0.796,0.796c-0.003,0.003 -0.005,0.006 -0.008,0.008c-0.191,0.191 -0.5,0.191 -0.691,0c-0.003,-0.002 -0.005,-0.005 -0.008,-0.008l-2.121,-2.121c-0.195,-0.195 -0.195,-0.512 -0,-0.707c0.195,-0.195 0.512,-0.195 0.707,-0l1.784,1.784Zm3.033,-3.236l1.252,-0c0.413,-0 0.748,0.335 0.748,0.749l0,0.751l2.252,0c0.689,0 1.248,0.559 1.248,1.249l0,2.497c0,0.689 -0.559,1.248 -1.248,1.248l-2.497,0c-0.69,0 -1.249,-0.559 -1.249,-1.248l0,-2.252l-0.751,0c-0.414,0 -0.749,-0.335 -0.749,-0.748l0,-1.252c-0.001,0 -0.003,0 -0.004,0l-1.997,0c-0.552,0 -0.999,-0.447 -0.999,-0.998l0,-1.997c0,-0.552 0.447,-0.999 0.999,-0.999l1.997,0c0.551,0 0.998,0.447 0.998,0.999l0,1.997c0,0.001 0,0.003 0,0.004Zm4,3l-1.994,0l0,1.994l1.994,0l0,-1.994Zm1.311,-4.304c0.092,0.019 0.18,0.065 0.252,0.136l2.241,2.241c0.195,0.195 0.195,0.512 0,0.707c-0.195,0.195 -0.512,0.195 -0.707,0l-1.89,-1.89l-1.024,1.024c-0.195,0.195 -0.512,0.195 -0.707,0c-0.195,-0.195 -0.195,-0.512 -0,-0.707l1.375,-1.376c0.125,-0.124 0.299,-0.169 0.46,-0.135Zm-7.601,7.415c0.015,-0.104 0.062,-0.204 0.142,-0.283c0.011,-0.012 0.023,-0.023 0.036,-0.033l1.209,-1.209c0.195,-0.195 0.512,-0.195 0.707,-0c0.195,0.195 0.195,0.512 0,0.707l-0.89,0.89l1.89,1.89c0.195,0.195 0.195,0.512 0,0.707c-0.195,0.195 -0.512,0.195 -0.707,0l-2.204,-2.204c-0.015,-0.011 -0.029,-0.024 -0.042,-0.037c-0.117,-0.117 -0.163,-0.277 -0.141,-0.428Z"/>
</svg>`;
    }

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


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

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

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

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

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