﻿//namespace
if (typeof GP == "undefined") { var GP = {}; }
if (typeof GP.util == "undefined") { GP.util = {}; }

/**
 * класс для вызова обработчиков событий наподобии YAHOO CustomEvents
 * Удобен в случаях когда на одно событие есть много независимых обработчиков
 */
GP.util.Event=(function() {
	/**
	 * хранит обработчики событий {type : [handler1, handler2 ...],...}
	 */
	var handlers={};
	/**
	 * регистрирует обработчик на данный тип события
	 * @param string type - название события
	 * @param function func - функция обработчика
	 */
	var registerHandler=function(type,func,one_time) {
		if(!handlers[type]) handlers[type]=[];
		handlers[type][handlers[type].length]={func:func,one_time:one_time};
	};
	
	/**
	 * удаляет обработчик на данный тип события
	 * @param string type - название события
	 */
	var unregisterHandler=function(type,func) {
		if(!func) delete handlers[type];
		else {
			var h=handlers[type].length;
			while(h--) {
				if(handlers[type][h].func===func) {
					removeHandler(type,h);
					break;
				}
			}
		}
	}
	
	var removeHandler=function(type,h) {
		handlers[type].splice(h,1);
	};
	
	var unregisterHandlerByNums=function(type,unregisterHandlerNums) {
		if(unregisterHandlerNums && unregisterHandlerNums.length) {
			var h=unregisterHandlerNums.length;
			while(h--) {
				removeHandler(type,unregisterHandlerNums[h]);
			}
		}
	};
	/**
	 * находит зарегестрированные обработчики по типу и выполняет их
	 *  @param string type - название события
	 *  @param object data - данные передаваемые в обработчик
	 */
	var fire=function(type,data) {
		if(handlers[type]) {
			var unregisterHandlerNums=[];
			var h=handlers[type].length;
			for (h in handlers[type]) {
				handlers[type][h].func(data);
				if(handlers[type][h].one_time) unregisterHandlerNums[unregisterHandlerNums.length]=h; 
			}
			unregisterHandlerByNums(type,unregisterHandlerNums);
		}
	};
	
	return {
		addListener : registerHandler,
		removeListener : unregisterHandler,
		fire : fire
	}
})();