/*
 * jQuery Shout plugin
 * http://gnu.gabrielfalcao.com/shout
 *
 * Copyright (c) 2009 Gabriel Falcão
 * Dual licensed under the MIT and GPL 3+ licenses.
 *
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/copyleft/gpl.html
 *
 * Version: 0.1
 */
jQuery.extend({
    _jq_shout: {},
    shout: function (event, data) {
        jQuery._jq_shout.log(event, data);
        var items = this._jq_shout.registry[event];
        if (items) {
            jQuery.each(items, function () {
                this.callback.call(this.source, data);
            });
        }
    }
});

jQuery.extend(jQuery._jq_shout, {
    debug: Boolean(window.DEBUG),
    log: function(s) {
        if (jQuery._jq_shout.debug && console) {
            console.log('[shout] Trigger:', arguments);
        }
    },
    registry: {}
});

jQuery.extend(jQuery.fn, {
    hear: function(eventName, messageCallback) {
        if (messageCallback == undefined) {
            throw "Undefined callback function";
        }
        var list = jQuery._jq_shout.registry[eventName];
        if (!list) {
            jQuery._jq_shout.registry[eventName] = [];
        }
        var $this = this;
        var action = function() {
            var item = {
                source: $this,
                callback: messageCallback
            }
            jQuery._jq_shout.registry[eventName].push(item);
        }
        if (this.length > 0) {
            this.each(action);
        } else if (this.selector == 'document') {
            action.call();
        } else {
            throw 'The current DOM does not have any "' + this.selector + '" matched elements';
        }
    },
    unhear: function(eventName, messageCallback) {
        var listeners = [];
        jQuery.each(jQuery._jq_shout.registry[eventName] || [], function(i, data) {
            if (this.callback != messageCallback) {
                listeners.push(this);
            }
        });
        jQuery._jq_shout.registry[eventName] = listeners;
    }
});


