
function getMouseLoc(e, obj) {
	var c = obj ? getPagePosition(obj) : new Coord();

	// CODE TAKEN FROM THE INTARWEB
	// Maybe needs improving... 'isIE' is bad practice
	var IE = document.all ? true : false;
	var tempX = 0;
	var tempY = 0;
	if (IE) { // grab the x-y pos.s if browser is IE
		tempX = event.clientX + document.body.scrollLeft;
		tempY = event.clientY + document.body.scrollTop;
	} else {  // grab the x-y pos.s if browser is NS
		tempX = e.pageX;
		tempY = e.pageY;
	}  
	// END INTARWEB CODE

	return new Coord(tempX - c.x, tempY - c.y);
}

function stopPropagation(e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

Event.stopPropagation = function(event) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
};

function document_body() {
	return document.getElementsByTagName('body')[0];
}

function addEvent(el, evt, _func, capture) {
	if(capture == undefined) capture = false;
	if(typeof(el) == 'string') el = $(el);
	var func = function(e) { 
		e = e || event; 
		return _func(e); 
	};
	if(el.addEventListener) {
		el.addEventListener(evt, func, capture);
	} else if (el.attachEvent) {
		el.attachEvent('on'+evt, func);
	} else {
		el['on'+evt] = func;
	}
}



function EventObj() {
}
EventObj.prototype.eventsInit = function() {
	this._events = {};
}

EventObj.prototype.addEvent = function(name, func, context, start) {
	if(!this._events) {
		this.eventsInit();
	}
	if(!this._events[name]) this._events[name] = [];
	//TODO: remove dups? or not? or optional?
	this._events[name][start ? 'unshift':'push']({func:func, context:context});
}
EventObj.prototype.addEventPropagator = function(name, obj) {
	this.addEvent(name, function() { obj.triggerEvent(arguments); }, obj);
}
EventObj.prototype.removeEvent = function(name, func, context) {
	if(!this._events) this.eventsInit();
	if(!this._events[name]) return;
	this._events[name].reject(function(ev) { return 
			(!func || ev.func == func) && (!context || ev.context == context);
		});
/*	for(var i = 0; i < this._events[name].length; i++) {
		var ev = this._events[name][i];
		if(ev.func == func) {
				this._events[name].splice(i, 1);
				i--;
		}
	}
	alert("Unimplemented: EventObj.removeEvent");*/
}
EventObj.prototype.triggerEvent = function(name) {
	if(!this._events) this.eventsInit();
	if(!this._events[name]) return;
	for(var i = 0; i < this._events[name].length; i++) {
/*		var func = this._events[name][i].func;
		var ctxt = this._events[name][i].context;
		if(!ctxt) ctxt = this; //important default.
		func.call(ctxt, this); */
		var func = this._events[name][i].func.apply(this, arguments);
	}
}

function getEventKeycode(e) {
	if (window.event) return window.event.keyCode;
	else if (e) return e.which;
}

var KeyState = {};

KeyState.ENTER = 13;
KeyState.SHIFT = 16;
KeyState.CTRL = 17;
KeyState.ALT = 18;
KeyState.ESC = 27;
KeyState.INS = 45;
KeyState.DEL = 46;
KeyState.HOME = 36;
KeyState.END = 35;
KeyState.PGUP = 33;
KeyState.PGDN = 34;
KeyState.LEFT = 37;
KeyState.UP = 38;
KeyState.RIGHT = 39;
KeyState.DOWN = 40;
KeyState.states = {};

addEvent(window, 'keydown', function(e) {
	var keycode = getEventKeycode(e);

	KeyState.states[keycode] = true;
});

addEvent(window, 'keyup', function(e) {
	var keycode = getEventKeycode(e);

	KeyState.states[keycode] = false;
});


