/**
 * Inicializace observeru a f-ci na ktere ma observer reagovat
 *
 * @param {Array} events retezce na ktere obsluha udalosti reagovat
 */
var Observeable = function(subject, events) {

    var observers = {};
    events.each(function(event) {
        observers[event] = [];
    });

    /**
     * uklada f-ci do pole observeru do noveho indexu, zvysi index o 1, vraci objekt pomoci ktereho lze
     * observing vypnout
     *
     * @param string event je jedna z funkci na kterou posloucha observer moznosti jsou dany spustenim f-ce _defineEvents
     * @param function observer je volana funkce v pripade zavolani notify
     */
    subject.observe = function(event, observer) {
        observers[event].push(observer);
        return subject;
    };

    /**
     * zastaveni observeru, smaze f-ci na danem observeru
     *
     * @param string event je jedna z funkci na kterou posloucha observer moznosti jsou dany spustenim f-ce _defineEvents
     * @param function observer je volana funkce v pripade zavolani fire
     */
    subject.stopObserving = function(event, observer) {
        observers[event] = observers[event].reject(function(value) {
            return value == observer;
        });
        return subject;
    };

    /**
     * trignuti udalosti na kterou se maji spustit registrovane udalosti
     *
     * @param prvni argument f-ce je udalost, dalsi argumenty jsou predany f-cim v observeru
     */
    subject.fire = function(event) {
        var args  = $A(arguments);
        args.shift();
        observers[event].each(function(observer) {
            observer.curry.apply(observer, args)();
        });
        return subject;
    };

    /**
     * Objekt se pomoci teto metody muze sam zbavit observeru
     */
    subject.clearObservers = function() {
        var events = [];

        // najde vsechny definovane eventy
        $H(observers).each(function(item) {
            events.push(item.key);
        });

        // pro kazdy event zrusi observery
        events.each(function(event) {
            observers[event] = [];
        });
        return subject;
    };

    return subject;
};

