var LEFT_BUTTON=1;
var RIGHT_BUTTON=2;
var CAN_USE_DHTML=canUseDHTML();
var CAN_USE_DOM=canUseW3CDOM();
//alert('can use DHTML = '+CAN_USE_DHTML);
//alert('can use W3C DOM = '+CAN_USE_DOM);
var mozReconnu=false;
function checkEventObject(e){
  if(window.event) e=window.event;
  if(e===undefined||e===null) return null;
	e.mouseButton=e.button;
//		recordEvent(mozReconnu);
//		recordProps(e,'srcElement',new Array('id','parentElement','parentNode'));
	if(mozReconnu||e.srcElement===undefined){
		mozReconnu=true;
		if(e.type=="mouseout"){
		  e.srcElement=e.target;
		  e.fromElement=e.originalTarget;
		  e.toElement=e.relatedTarget;
		}else if(e.type=="mouseover"){
		  e.srcElement=e.target;
		  e.fromElement=e.relatedTarget;
		  e.toElement=e.originalTarget;
		}else if(e.type=="mousemove"||e.type=="mousedown"||e.type=="mouseup"){
		  e.srcElement=e.target;
		  e.fromElement=null;
		  e.toElement=null;
		}
		if(e.mouseButton==0) e.mouseButton=1;
		if(e.srcElement&&e.srcElement.parentElement===undefined&&e.srcElement.parentNode!==undefined) e.srcElement.parentElement=e.srcElement.parentNode;
		if(e.fromElement&&e.fromElement.parentElement===undefined&&e.fromElement.parentNode!==undefined) e.fromElement.parentElement=e.fromElement.parentNode;
		if(e.toElement&&e.toElement.parentElement===undefined&&e.toElement.parentNode!==undefined) e.toElement.parentElement=e.toElement.parentNode;
		e.offsetX=e.layerX;
		e.offsetY=e.layerY;
	}
	e.toString=function(){ return eventDetails(this); }
	return e;
}
function eventDetails(e){
	var desc="EventObject[";
	desc+="type:"+e.type+", btn:"+e.mouseButton+", key:"+e.keyCode;
	desc+=",\noffset:"+e.offsetX+" "+e.offsetY;
	desc+=",\nclient:"+e.clientX+" "+e.clientY;
	desc+=",\npageIE:"+e.x+" "+e.y;
	desc+=",\npage:"+e.pageX+" "+e.pageY;
	if(e.srcElement){
		desc+=",\nsrc:"+e.srcElement.id;
		if(e.srcElement.parentElement) desc+=" < "+e.srcElement.parentElement.id;
	}
	if(this.fromElement){
		e+=",\nfrom:"+e.fromElement.id;
		if(e.fromElement.parentElement) desc+=" < "+e.fromElement.parentElement.id;
	}
	if(e.toElement){
		desc+=",\nto:"+e.toElement.id;
		if(e.toElement.parentElement) desc+=" < "+e.toElement.parentElement.id;
	}
	desc+="]";
	return desc;
}
function EventManager(cancelPropagation,eventName){
	this.eventNames=new Array();
	if(eventName!==undefined) this.eventNames[0]=eventName;
	this.listeners=new Array();
	this.lastEvent=null;
	this.onEvent=function(e,debug){
		try{
			this.lastEvent=checkEventObject(e);
			if(this.lastEvent){
				if(this.listeners.length){
					for(var i=1;i<this.listeners.length;++i){
						if(this.listeners[i]) this.listeners[i].doEvent(this.lastEvent);
					}
					if(this.listeners[0]) return this.listeners[0].doEvent(this.lastEvent);
					//if(this.listeners[0]) this.listeners[0].doEvent(this.lastEvent);
				}
			}
			return true;
		}catch(e){
			return true;
		}
	}
	this.addEventListener=function(listener){
		if(listener.doEvent) this.listeners[this.listeners.length]=listener;
	}
	this.addEvent=function(eventName){
		this.eventNames[this.eventNames.length]=eventName;
		if(window.captureEvents&&Event) window.captureEvents(eval("Event."+eventName));
	}
	//add one first lisener
	this.addEventListener(new PropagationListener(cancelPropagation));
}
function PropagationListener(stopper){
	if(stopper) this.doEvent=function(e){ if(e.preventDefault) e.preventDefault(); return false; }
	else this.doEvent=function(e){ return true; }
}
function MouseListener(){
	this.doEvent=function(e){
		switch(e.type){
			case "mousedown": if(this.mouseDown) this.mouseDown(e); break;
			case "mouseup": if(this.mouseUp) this.mouseUp(e); break;
			case "mouseover": if(this.mouseOver) this.mouseOver(e); break;
			case "mouseout": if(this.mouseOut) this.mouseOut(e); break;
			case "mousemove": if(this.mouseMove) this.mouseMove(e); break;
		}
	}
}

//var mouseEventManager=new EventManager(true);
var mouseEventManager=new EventManager(false);
mouseEventManager.addEvent("MOUSEDOWN");
mouseEventManager.addEvent("MOUSEUP");
//mouseEventManager.addEvent("MOUSEOVER");
mouseEventManager.addEvent("MOUSEOUT");
mouseEventManager.addEvent("MOUSEMOVE");
var keyDownEvtMngr=new EventManager(false,"KEYDOWN");
var cancellerEvtMngr=new EventManager(true,"ERROR");

// delegates
function onMouseEvent(e){ return mouseEventManager.onEvent(e); }
function onKeyDownEvent(e){ return keyDownEvtMngr.onEvent(e); }
function onCancellerEvent(e){ return cancellerEvtMngr.onEvent(e); }

//document.oncontextmenu=onCancellerEvent;
//document.onselectstart=onCancellerEvent;
if(document.layers){
	window.onmousedown=onMouseEvent;
	window.onmouseup=onMouseEvent;
	window.onmouseover=onMouseEvent;
	window.onmouseout=onMouseEvent;
	window.onmousemove=onMouseEvent;
	window.onkeydown=onKeyDownEvent;
}else{
	document.onmousedown=onMouseEvent;
	document.onmouseup=onMouseEvent;
	document.onmouseover=onMouseEvent;
	document.onmouseout=onMouseEvent;
	document.onmousemove=onMouseEvent;
	document.onkeydown=onKeyDownEvent;
}
