//Пространство имен для библиотек CMS
OPR={};


/*
Диспетчер событий EventDispatcher для диспетчеризации событий между различными блоками страницы и внутри них.
Схема работы:

    диспетчер обеспечивает подписку на события неограниченного количества обработчиков.
    диспетчер обеспечивает прием информации о событиях и их рассылку заинтересованным обработчикам (в порядке их регистрации).
    Методы:
    handlerID addHandler(string eventID, function callback);
    removeHandler(handlerID);
    dispatchEvent(string eventID, object eventData);
    eventData - произвольный набор данных, специфичный для события

Обработчик:
boolean eventHandler(string eventID, object eventData);
обработчик возвращает признак "прекратить дальнейшую обработку события" - не 0, '', nil, undefined и прочее.
 */

//Singleton
OPR.EventDispatcher=(function (){
//-----------------   Protected   -----------------
    var EventHandlers={};
    var RegisteredHandlers={};
    var RegisteredHandlersCounter=0;

    //У нас синглтон. один раз определили, больше не надо
    if (typeof(OPR.EventDispatcher)!='undefined') return OPR.EventDispatcher;

//-----------------    Public    -----------------
    return {
        addHandler: function (eventID, callBack){
            //check Event
            if (typeof(EventHandlers[eventID])=='undefined') EventHandlers[eventID]={};

            var handlerID=RegisteredHandlersCounter++;

            EventHandlers[eventID][handlerID]=callBack;

            RegisteredHandlers[handlerID]=eventID;
            return handlerID;
        },
        removeHandler: function (handlerID){
            var eventID=RegisteredHandlers[handlerID];
            delete EventHandlers[eventID][handlerID];
        },
        //returns 0 on success, 1 if the sequence was terminated
        dispatchEvent: function (eventID, eventData){
            if (typeof(EventHandlers[eventID])=='undefined') return 0;
            var handlers=EventHandlers[eventID];
            var res;
            for (var i in handlers){
                try{
                    res=handlers[i](eventData);
                } catch (e) {
                    //брошено исключение, выходим:
                    return 1;
                }
                //не 0, '', nil, undefined и прочее -- выходим
                if (typeof(res)!='undefined' && res) return 1;
            }
            return 0;
        }
    }

})();

// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
OPR.templater = (function() {
	var cache = {};
	return function f(str, data) {
		var fn = !/\W/.test(str) ?
			cache[str] = cache[str] || f(document.getElementById(str).innerHTML) :
			new Function("obj",
				"var p=[],print=function(){p.push.apply(p,arguments)};" +
				"with(obj){p.push('" +
					str
						.replace(/[\r\t\n]/g, " ")
						.split("<%").join("\t")
						.replace(/((^|%>)[^\t]*)'/g, "$1\r")
						.replace(/\t=(.*?)%>/g, "',$1,'")
						.split("\t").join("');")
						.split("%>").join("p.push('")
						.split("\r").join("\\'")
				+ "')}return p.join('')");
		return data ? fn(data) : fn;
	}
})();

/**
 * Инициализация плагина history для работы через диспетчер событий.
 */
$(document).ready(function() {
	$.history.init(function(hash) {
		OPR.EventDispatcher.dispatchEvent('History:onMove', hash);
	});
});

