'use strict';

/*@
Ox.Event <o> Basic event handler
@*/

Ox.Event = (function() {

    var self = {}, that = {};

    self.$eventHandler = $('<div>');

    /*@
    bind <f> Binds a callback to an event
        (event, callback) -> <o> The event handler
        ({event: callback, ...}) -> <o> The event handler
        callback <f> Callback function
            data <*> Event data
        event <s> Event name
            Event names can be namespaced, like <code>'click.foo'</code>
    @*/
    that.bind = function() {
        Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
            var foo = event;
            self.$eventHandler.bind('ox_' + event, function(event, data) {
                Ox.Log('Core', 'CALLBACK', foo, data.value);
                callback(data.value);
            });
        });
        return that;
    };

    /*@
    bindOnce <f> Binds a callback to an event, once
        (event, callback) -> <o> The event handler
        ({event: callback, ...}) -> <o> The event handler
        callback <f> Callback function
            data <*> Event data
        event <s> Event name
            Event names can be namespaced, like <code>'click.foo'</code>
    @*/
    that.bindOnce = function() {
        Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
            self.$eventHandler.one('ox_' + event, function(event, data) {
                callback(data.value);
            });
        });
        return that;
    };

    /*@
    trigger <function> Triggers an event
        (event) -> <o> The event handler
        (event, data) -> <o> The event handler
        ({event: data, ...}) -> <o> The event handler
        event <s> Event name
        data <*> Event data
    @*/
    that.trigger = function() {
        Ox.forEach(Ox.makeObject(arguments), function(data, event) {
            Ox.Log('Core', 'Ox.Event.trigger', event, data)
            self.$eventHandler.trigger('ox_' + event, {value: data});
        });
        return that;
    };

    /*@
    unbind <f> Unbinds all callbacks from an event
        To unbind a specific handler, use namespaced events, like
        <code>bind('click.foo', callback)</code>, and then
        <code>unbind('click.foo')</code>.
        () -> <o> The event handler
            Unbinds all events
        (event) -> <o> The event handler
            Unbinds one event
        (event, event, ...) -> <o> The event handler
            Unbinds multiple events
        ([event, event, ...]) -> <o> The event handler
            Unbinds multiple events
        event <s> Event name
    @*/
    that.unbind = function() {
        if (arguments.length == 0) {
            self.$eventHandler.unbind();
        } else {
            Ox.makeArray(arguments).forEach(function(event) {
                self.$eventHandler.unbind('ox_' + event);
            });
        }
        return that;
    };

    return that;

}());