/*
 *     Copyright (c) 2008-2016 CoNWeT Lab., Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/* globals Promise, StyledElements, Symbol */

(function () {

    "use strict";

    /**
     * Creates an asyncrhonous FIFO queue.
     */
    var CommandQueue = function CommandQueue(context, callback, stepFunc) {
        this[_attrs.elements] = [];
        this[_attrs.running] = false;
        this[_attrs.step] = 0;
        this[_attrs.stepTimes] = null;

        Object.defineProperties(this, {
            callback: {
                value: callback
            },
            context: {
                value: context
            },
            running: {
                get: running_getter
            },
            stepFunc: {
                value: stepFunc
            }
        });
    };

    /**
     * Adds a new command into this queue
     *
     * @param command command to add into the queue
     */
    CommandQueue.prototype.addCommand = function addCommand(command) {
        if (command === undefined) {
            return;
        }

        this[_attrs.elements].push(command);

        if (!this.running) {
            this[_attrs.running] = true;
            doInit.call(this);
        }
    };

    var doStep = function doStep() {
        var cont;

        try {
            cont = this.stepFunc(this[_attrs.step], this.context);
        } catch (e) {
            doInit.call(this);
        }

        if (cont) {
            var timeDiff = this[_attrs.stepTimes][this[_attrs.step]] - (new Date()).getTime();
            if (timeDiff < 0) {
                timeDiff = 0;
            }

            this[_attrs.step]++;
            setTimeout(doStep.bind(this), timeDiff);
        } else {
            doInit.call(this);
        }
    };

    var doInit = function doInit() {
        var command, action, timeDiff;

        do {
            command = this[_attrs.elements].shift();
        } while (command !== undefined && !(action = this.callback(this.context, command)));

        if (command === undefined) {
            this[_attrs.running] = false;
        } else if (action instanceof Promise) {
            action.then(doInit.bind(this), doInit.bind(this));
        } else {
            this[_attrs.step] = 0;
            this[_attrs.stepTimes] = action;

            timeDiff = this[_attrs.stepTimes][this[_attrs.step]] - (new Date()).getTime();
            if (timeDiff < 0) {
                timeDiff = 0;
            }
            setTimeout(doStep.bind(this), timeDiff);
        }
    };

    var running_getter = function running_getter() {
        return this[_attrs.running];
    };

    var _attrs = {
        callback: Symbol("callback"),
        elements: Symbol("elements"),
        running: Symbol("running"),
        step: Symbol("step"),
        stepTimes: Symbol("stepTimes")
    };

    StyledElements.CommandQueue = CommandQueue;

})();

@@ -897,16 +897,8 @@
 ents
-, Symbol
  */%0A
@@ -909,16 +909,21 @@
 nction (
+utils
 ) %7B%0A%0A   
@@ -3410,178 +3410,69 @@
 s = 
-%7B%0A        callback: Symbol(%22callback%22),%0A        elements: Symbol(%22elements%22),%0A        running: Symbol(%22running%22),%0A        step: Symbol(%22step%22),%0A        stepTimes: Symbol(
+utils.privateKeys(%22callback%22, %22elements%22, %22running%22, %22step%22, 
 %22ste
@@ -3479,22 +3479,16 @@
 pTimes%22)
-%0A    %7D
 ;%0A%0A    S
@@ -3535,10 +3535,30 @@
 e;%0A%0A
-
 %7D)(
+StyledElements.Utils
 );%0A

Make CommandQueue to use privateKeys