﻿/// <reference path="Queue.js" />

///
/// Throttles command execution by executing each command sequentialy off a queue (FIFO)
/// this class is implemented as singleton and can be used like this - 
/// CommandInvoker.getInstance().QueueCommand(myCommand)
///
var CommandInvoker = (function() {

    var instance = null;

    function PrivateConstructor() {

        //----------------------------------------------------------
        // Private fields
        //----------------------------------------------------------

        var throttlePeriod = 250; // Is in milliseconds
        var queue = new Queue()
        var initialized = false;
        var currentCommand = undefined;

        //----------------------------------------------------------
        // Private functions
        //----------------------------------------------------------

        //
        // Checks if the invoker is busy executing a command
        //
        function IsExecutingCommand() {

            if (currentCommand == undefined) {
                return false;
            }
            else {
                
                // We must still be executing if the command has not completed execution
                return !currentCommand.HasExecutionCompleted()
            }

        }

        ///
        /// Recursively retrieves commands off a queue and executes them. The commands are throttled by
        /// a timeout
        ///
        function executeCommands() {


            if (!IsExecutingCommand()) {

                //console.log("Get command off queue");

                // Get the next command from the queue
                currentCommand = queue.dequeue();

                // check if we got a command off the queue
                if (currentCommand != undefined) {
                    currentCommand.Execute();
                }

            }



            // Stop execution for a while so that the UI can queue some commands
            setTimeout(executeCommands, throttlePeriod);
        }

        //----------------------------------------------------------
        // Public functions
        //----------------------------------------------------------

        ///
        /// Adds a command to the internal queue
        ///
        this.QueueCommand = function(command) {

            // add the command to the internal queue
            queue.enqueue(command);

            // Initialize the invoker if not already initialized by executing the commands
            if (!initialized) {
                initialized = true;
                executeCommands();
            }

        }

    }

    ///
    /// Returns the singleton instance
    ///
    return new function() {
        this.getInstance = function() {
            if (instance == null) {
                instance = new PrivateConstructor();
                instance.constructor = null;
            }
            return instance;
        }
    }
})();

