/**
 * FCL version of the observer pattern
 *
 * @author          Ryan Blunden
 * @modifiedby      $LastChangedBy$
 * @copyright       Copyright Flight Centre Ltd. All rights reserved.
 * @version         $Revision$
 * @lastmodified    $Date$
 * @requires        FCL, FCL.UTIL
 */
;FCL.SIGNALS =
{
    name: 'FCL.SIGNALS',

    namespaces: {},

    errors:
    {
        namespace: 'FCL.SIGNALS.listen must receive a "namespace" as the first argument',
        signal: 'FCL.SIGNALS.listen must receive a "signal" as the second argument',
        callback: 'FCL.SIGNALS.listen must receive a "callback" as the third argument'
    },

    listen: function(namespace, signalName, callback, context)
    {
        var _this = this, signal = {}, error = false;

        signal.namespace = namespace || 'undefined';
        signal.name = signalName || 'undefined';
        signal.callback = callback || 'undefined';
        signal.context = context || window;

        $.each(signal, function(key, value)
        {
            if(value == 'undefined')
            {
                FCL.UTIL.throwError(_this.errors[key]);
                error = true;
                return false;
            }
        });

        // Check if namespace defined
        if(typeof this.namespaces[namespace] == 'undefined')
        {
            this.namespaces[namespace] = {};
        }

        // Check if signal for namespace is defined
        if(typeof this.namespaces[namespace][signalName] == 'undefined')
        {
            this.namespaces[namespace][signalName] = [];
        }

        this.namespaces[namespace][signalName].push(signal);
    },

    send: function(namespace, signal)
    {
		var args = Array.prototype.slice.call(arguments, 2);
		
        if(typeof this.namespaces[namespace] == 'undefined' || typeof this.namespaces[namespace][signal] == 'undefined')
        {
            return FCL.UTIL.log('FCL.SIGNALS.send didn\'t find listeners for "{1}" signal on namespace {2}'.fclFormat(signal, namespace));
        }

        $.each(this.namespaces[namespace][signal], function(i, signal)
        {
		
            try
            {
                signal.callback.apply(signal.context, args);
                FCL.UTIL.log(signal.namespace + ' => "' + signal.name + '" signal called.');
            }
            catch(e)
            {
                FCL.UTIL.throwError(e.message);
            }
        });
    }
};
