/* should change object name:
EventDefinition
EventDef
EventObject
EventBasis
EventRule
*/

function Event(sSelector, sDomEvent, iIndex) {
	this.selector = sSelector;	// selector to fetch the tag(s) for this event
	this.domEvent = sDomEvent;	// simple DOM event of that tag(s)
	this.index = iIndex;

	this.bindings = new Array();
}

Event.cancelBubble = function (ev) {
	if(!ev) {
		event.cancelBubble = true;	// IE
		event.returnValue = false;
	} else {
		ev.cancelBubble = true;		// Mozilla
	}	// other browsers?
}

Event.bubble = function (ev) {
	if(!ev) {
		event.cancelBubble = false;	// IE
		event.returnValue = true;
	} else {
		ev.cancelBubble = false;	// Mozilla
	}	// other browsers?
}

p = Event.prototype;

p.bind = function (action, options) {
	this.bindings.push(new Binding(action, options));
}

/*
p.unbind = function () {
	var binding = ???
	this.bindings.remove(binding);
}
*/

p.fire = function (tag, ev) {
	var returnValue = true;

	for(var iBinding = 0; iBinding < this.bindings.length; iBinding++) {
		var binding = this.bindings[iBinding];
//		alert(this.getString());	// debug
		returnValue &= binding.fire(this, ev, tag);
	}
	
	if(!returnValue)
		Event.cancelBubble(ev);
	
	return returnValue;
}

p.getString = function () {
	var sEvent = this.selector + ':' + this.domEvent;
	return sEvent;
}


addOnload(
	function () {
		//var logNoAttach = new CountLog();
		
		for(var iEvent = Events.list.length - 1; iEvent >= 0; iEvent--) {
			var ntevent = Events.list[iEvent];
			var iIndex = ntevent.index;

			var tags = document.getBySelector(ntevent.selector);
			
			for(var iTag = tags.length - 1; iTag >= 0; iTag--) {
				var tag = tags[iTag];

				/* Does not override inline events
					Priority:
					1. Inline events (onclick="blah()")
					2. Lower events (events created later in script)
					3. Higher events (events created earlier in script) - because this loop loops backwards
				*/
				if(!tag[ntevent.domEvent]) {
					// create a closure object for each event call in the loop; will maintain
					// iEventIndex even after this entire function has fallen out of scope
					function eventClosure(iEventIndex) {
						tag[ntevent.domEvent] = function (ev) {
							return Events.list[iEventIndex].fire(this, ev);
						}
					}
					eventClosure(iIndex);
				} else {
					//logNoAttach.log(tag.tagName + '.' + ntevent.domEvent);
				}
			}
		}
	}
);
