/**
 * Forms Framework Javascript Handling Object
 *	ffEvents' namespace
 */

ff.ffEvents = function () {
//privates

var that = {
// publics
events : ff.hash(),

"addEvent" : function (params) {
	var event_name		= params.event_name			|| console.log("event_name required");
	var func_name		= params.func_name			|| console.log("func_name required");
	var priority		= params.priority			=== undefined ? ff.ffEvent.PRIORITY_DEFAULT : params.priority;
	var break_when		= params.break_when;
	var break_value		= params.break_value;
	var additional_data	= params.additional_data	|| [];

	var event = ff.ffEvent.factory({"func_name" : func_name, "break_when" : break_when, "break_value" : break_value, "additional_data" : additional_data});
	if (that.events.isset(event_name) === undefined)
		that.events.set(event_name, ff.hash());

	switch (priority) {
		case ff.ffEvent.PRIORITY_TOPLEVEL:
			if (that.events.get(event_name).get("toplevel") !== undefined)
				console.log("A toplevel event already exists");
			else
				that.events.get(event_name).set("toplevel", event);
			break;

		case ff.ffEvent.PRIORITY_FINAL:
			if (that.events.isset(event_name).get("final") !== undefined)
				console.log("A final event already exists");
			else
				that.events.get(event_name).set("final", event);
			break;

		default:
			var queue = that.events.get(event_name).get(priority);
			if (queue === undefined)
				queue = [];
			//queue.push({"index" : index, "counter" : queue.length, "event" : event});
			queue.push(event);
			that.events.get(event_name).set(priority, queue);
			break;
	}
},

"doEvent" : function (params) {
	var event_name		= params.event_name		|| console.log("event_name required");
	var event_params	= params.event_params	|| [];
	var results			= [];

	var tmp_queue = that.events.get(event_name);
	var event;
	var tmp_args;

	if (tmp_queue !== undefined) {
		if (tmp_queue.isset("toplevel") !== undefined) {
			event = tmp_queue.get("toplevel");
			tmp_args = event_params.slice().concat(event.additional_data.slice());
			tmp_args.push(undefined);
			results.push(event.func_name.apply(event, tmp_args));

			if (event.checkBreak(results[results.length - 1]))
				return results;
		}

		for (var q = ff.ffEvent.PRIORITY_TOPLEVEL + 1; q < ff.ffEvent.PRIORITY_FINAL; q++) {
			if (undefined !== (event = tmp_queue.get(q))) {
				for (var e = 0; e < event.length; e++) {
					tmp_args = event_params.slice().concat(event[e].additional_data.slice());
					tmp_args.push(results[results.length - 1]);
					results.push(event[e].func_name.apply(event[e], tmp_args));

					if (event[e].checkBreak(results[results.length - 1]))
						return results;
				}
			}
		}

		if (tmp_queue.isset("final") !== undefined) {
			event = tmp_queue.get("final");
			tmp_args = event_params.slice().concat(event.additional_data.slice());
			tmp_args.push(results[results.length - 1]);
			results.push(event.func_name.apply(event, tmp_args));

			if (event.checkBreak(results[results.length - 1]))
				return results;
		}
	}

	return results;
}

}; // publics' end

return that;

// code's end.
};

