/*
Events class written by Neil McCorrison
*/
Events_class = function() {
	this.init();
}

Events_class.prototype.init = function(args) {
	this._events = [];
	this.add({element:window,type:"unload",handler:this.removeAll,context:this});
}

Events_class.prototype.add = function(args) {
	
	var el = args.element;
	if (!el) { return; }
	if (!args.handler) { return; }

	var type = args.type;
	var handler = args.handler || null;
	var context = args.context || null;
	var data = args.data || {};
	var delay = args.delay || null;

	var els = [];
	var setEvents = [];

	if (el instanceof Array) {
		for (var i=0; i<el.length; i++) {
			els.push(el[i]);
		}
	}
	else {
		els.push(el);	
	}

	if (context) {
		handler = hitch(context,handler)
	}

	for (var i=0; i<els.length; i++) {
		if (!els[i]) { continue; }
		if (els[i].addEventListener) {
			els[i].addEventListener(type,eventClosure,false)
		}
		else if (els[i].attachEvent) {
			els[i].attachEvent('on'+type,eventClosure)
		}
		else {
			els[i]['on'+type] = eventClosure;
		}
		if (!els[i]._events) { els[i]._events = {}; }
		if (!els[i]._events[type]) { els[i]._events[type] = []; }
		els[i]._events[type].push({handler:handler,closure:eventClosure,data:data});
		setEvents.push({el:els[i],type:type,handler:handler,closure:eventClosure,data:data});
	}

	function cancel(el,type,handler) {

	}

	var self = this;
	function eventClosure(e) {
		if (!e) e = window.event;
		var element = self.getSourceElement(e)
		if (delay) {
			var timerId = type+"_Timer";
			if (el[timerId]) { clearTimeout(el[timerId]); }
			el[timerId] = setTimeout(function() { handler(null,element,data); },delay)
		}
		else {
			handler(e,element,data);
		}
	}


	function hitch(obj, meth) {
		return function () {
			return typeof meth == "function" ? meth.apply(obj, arguments) : obj[meth].apply(obj, arguments);
		};
	};

	this._events = this._events.concat(setEvents);
	return setEvents;

}

Events_class.prototype.getSourceElement = function(e) {
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ && targ.nodeType && targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	return targ
}

Events_class.prototype.cancel = function(e) {
	if (e) {
		if (e.stopPropagation) { e.stopPropagation; }
		else { e.cancleBubble = true; }
		if (e.preventDefault) { e.preventDefault(); }
		else { e.returnValue = false; }
		return false;
	}
}

Events_class.prototype._removeEventListener = function(el,type,handler) {
		if (el.removeEventListener) {
			el.removeEventListener(type,handler,false)
		}
		else if (el.detachEvent) {
			el.detachEvent('on'+type,handler)
		}
		else {
			el['on'+type] = null;
		}
}

Events_class.prototype.remove = function(el,type) {
	if (el instanceof Array) {
		this.removeAll(el);
		return;
	}

	if (!el._events || !el._events[type]) { return; }

	for (var i=0; i<el._events[type].length; i++) {
		this._removeEventListener(el,type,el._events[type][i].closure);
	}

	delete el._events[type];
}

// Removes the delay timer for an event type on an el
Events_class.prototype.removeDelay = function(el,type) {
	var timerId = type+"_Timer";
	if (el[timerId]) { clearTimeout(el[timerId]); }
}

Events_class.prototype.removeAll = function(events) {
	events = events || this._events;
 	for (var i=0; i<events.length; i++) {
		this._removeEventListener(events[i].el,events[i].type,events[i].closure);
	}
	if (events == this._events) {
		this.init();
	}
}

Events_class.prototype.fire = function(setEvents) {
	for (var i=0; i<setEvents.length; i++) {
		setEvents[i].handler(null,setEvents[i].el,setEvents[i].data);
	}
}




Events = new Events_class();




Common = function() { }


Common.prototype.get = function(f) {
	if (typeof f == "string") {
		return document.getElementById(f);
	}

	return f;	

}

Common.prototype.formToObject = function(f,args) {

	args = args || {};
	var obj = {values:args.values||{},elements:{}};
	args.valueMap = args.valueMap || {};
	f = this.get(f);

	obj = obj || {};
	var els = f.elements;
	var el, tag, type, name, id, elName;
	var val = "";
	elLoop: for (var i=0; i<els.length; i++) {
		val = "";
		el = els[i];
		tag = el.tagName.toLowerCase();
		id = el.id
		name = el.getAttribute("name")
		type = el.getAttribute("type")

		if (tag == "input") {
			if (/text|hidden|password/.test(type)) { val = el.value; }
			else if (type == "radio") {
				for (var x=0; x<f[name].length; x++) {
					if (f[name][x].checked) { val = f[name][x].value; break; }
				}
			}
			else if (type == "checkbox") {
				val = el.checked;
			}
			else if (type == "button") {
				val = el.value;
			}

		}
		else if (tag == "textarea") {
			val = el.value;
		}
		else if (tag == "select") {
			var vals = [];
			var options = el.getElementsByTagName("option");

			for (var x=0; x<options.length;x++) {
				if (options[x].selected) {

					vals.push(options[x].value || options[x].text);
				}
			}
			val = vals.join(",");
		}


		// use name then id and assign to mapped value or element's value
		elName = name || id || (tag+i);
		obj.values[elName] = args.valueMap[val] != undefined ? args.valueMap[val] : val;
		obj.elements[elName] = el;


	}

	return args.elements ? obj : obj.values;

}

Common = new Common();


