/// class PD.BCL.Observable

PD.BCL.Observable = Class.extend({

    //===================================
    // FIELDS
    //===================================

    _map: null,

    //===================================
    // CONSTRUCTOR
    //===================================

    init: function () {
        this._map = {};
    },

    //===================================
    // PUBLIC METHODS
    //===================================

    bind: function (eventName, callback, context) {

        if (!this._map.hasOwnProperty(eventName)) {
            this._map[eventName] = [];
        }

        this._map[eventName].push({
            callback: callback,
            context: context !== "undefined" ? context : null
        });

    },

    unbind: function (eventName, callback) {

        var eventMap = this._map[eventName];

        if (eventMap) {
            for (var i = 0; i < eventMap.length; i++) {
                if (callback == eventMap[i].callback) {
                    eventMap.splice(i, 1);
                    break;
                }
            }
        }

    },

    trigger: function (eventName, args) {

        var eventMap = this._map[eventName];

        if (eventMap) {
            for (var i = 0; i < eventMap.length; i++) {
                var context = eventMap[i].context;
                var callback = eventMap[i].callback;
                if (callback) {
                    callback.call(context, args);
                }
            }
        }

    }

});

PD.BCL.Observable.mixin = function (target) {
    var o = new PD.BCL.Observable();
    target.bind = $.proxy(o.bind, o);
    target.unbind = $.proxy(o.unbind, o);
    target.trigger = $.proxy(o.trigger, o);
};