function Action (name, func)
{
    var self = this;

    self.name               = name;
    self.action             = func;
    self.on_queue           = true;
    self.original_callback  = null;

    self.run = function (callback)
    {
        self.original_callback = callback;

        self.action(self.callback);
    }

    self.quash = function ()
    {
        self.on_queue = false;
    }

    self.callback = function ()
    {
        if (self.on_queue)
        {
            self.original_callback();
        }
    }
}

function ActionQueue ()
{
    var self = this;

    self.actions = new Array();
    self.recurring_actions = new Array();

    self.current_action = null;
    self.running = false;

    self.queue = function (action)
    {
        self.actions.push(action);
    }

    self.queue_recurring = function (action)
    {
        self.recurring_actions.push(action);
    }

    self.clear_recurring_queue = function ()
    {
        self.recurring_actions = new Array();
    }

    self.quash = function (name)
    {
        if (self.running)
        {
            if (name)
            {
                if (self.current_action.name == name)
                {
                    self.current_action.quash();
                    self._run_next();
                }
            }
            else
            {
                self.current_action.quash();
                self._run_next();
            }
        }
    }

    self.toString = function ()
    {
        var action_names = new Array();
        $.each(self.actions, function () {
            action_names.push(this.name || '(no name)');
        });

        var recurring_action_names = new Array();
        $.each(self.recurring_actions, function () {
            recurring_action_names.push(this.name || '(no name)');
        });

        var total_actions = self.actions.length + self.recurring_actions.length;

        return '('+total_actions+'): '+action_names.join(', ')+' - '+recurring_action_names.join(', ');
    }

    self._debug = function ()
    {
        console.log(self.toString());
    }

    self._run_next = function ()
    {
        if (self.running)
        {
            if (self.actions.length > 0)
            {
                //self._debug();

                self.current_action = self.actions.shift();

                self.current_action.run(self._run_next);
            }
            else if (self.recurring_actions.length > 0)
            {
                //self._debug();

                self.current_action = self.recurring_actions.shift();
                self.recurring_actions.push(self.current_action);

                self.current_action.run(self._run_next);
            }
            else
            {
                //self._debug();

                self.stop();
            }
        }
        else
        {
            self.current_action = null;
        }
    }

    self.start = function ()
    {
        if (!self.running)
        {
            self.running = true;
            self._run_next();
        }
    }

    self.stop = function ()
    {
        if (self.running)
        {
            self.running = false;
        }
    }
}
