/******************************************************************************************************

		Funciones para el manejo de EVENTOS dentro del navegador (C) Alberto Blanco 2008
		Necesita el fichero de script ManejoObjetos.js

---------------------------------------
Ejemplo de estas funciones:
---------------------------------------
<input id="ElTxt1">
<input id="ElTxt2">
<input type="button" value="quita" onClick="EVTEliminaEvento(document.getElementById('ElTxt1'), 'click', EsLaKaka);">

<script>
// Funcion que será llamada por los eventos
function EsLaKaka(e)
{
var obj=EVTDimeObjeto(e); // recogemos el objeto que provoco el evento

	alert(obj.id); // Mostramos su ID
};

EVTAsignaEvento(document.getElementById('ElTxt1'), 'click', EsLaKaka); // asignamos eventos a los elementos
EVTAsignaEvento(document.getElementById('ElTxt2'), 'keypress', EsLaKaka);
</script>
---------------------------------------------------------------------------------------------------------------------------


--------------------------------------------
Common event Object Properties and Methods
------------------------------------------------------------------------------------
Property/Action				IE4+			W3C DOM
------------------------------------------------------------------------------------
Target element				srcElement		target
Event type					type			type
X coordinate in element 	offsetX			n/a†
Y coordinate in element		offsetY			n/a†
X coordinate on page		n/a†			pageX††
Y coordinate on page		n/a†			pageY††
X coordinate in window		clientX			clientX
Y coordinate in window		clientY			clientY
X coordinate on screen		screenX			screenX
Y coordinate on screen		screenY			screenY
Mouse button				button			button
Keyboard key				keyCode			keyCode††
Shift key pressed			shiftKey		shiftKey
Alt key pressed				altKey			altKey
Ctrl key pressed			ctrlKey			ctrlKey
Previous Element			fromElement		relatedTarget
Next Element				toElement		relatedTarget
Cancel bubbling				cancelBubble	preventBubble()
Prevent default action		returnValue		preventDefault()
------------------------------------------------------------------------------------
†Value can be derived through calculations with other properties.
††Not an official W3C DOM property, but is supported in Mozilla, Safari, and Opera.

******************************************************************************************************/






/*****************************************************************************************************************
	Asigna una funcion al evento de un objeto
	Tiene en cuenta las diferencias de tratamiento entre navegadores
	
	obj es una referencia a un objeto
	TipoEvento es un tipo de evento permitido para el objeto. p.ej "mousedown" o "keyup"
	funcion es la referencia a la funcion que hay que asignar al evento. Puede recibir como parametro el evento
	
	Se le puede asignar al mismo objeto / evento tantas funciones como se quieran. Se dispararán en el orden que 
	se asignaron.
*******************************************************************************************************************/
function EVTAsignaEvento(obj, TipoEvento, funcion)
{
	if (obj.addEventListener)
		obj.addEventListener(TipoEvento, funcion, false);
	else 
		if (obj.attachEvent)
			obj.attachEvent("on" + TipoEvento, funcion);
		else 
			obj["on" + TipoEvento] = funcion;
};

/*****************************************************************************************************************
	Elimina una funcion del evento de un objeto
	Tiene en cuenta las diferencias de tratamiento entre navegadores
	
	obj es una referencia a un objeto
	TipoEvento es el tipo de evento que se había asignado previamente. p.ej "mousedown" o "keyup"
	funcion es la referencia a la funcion que se le asigno al evento
*******************************************************************************************************************/
function EVTEliminaEvento(obj, TipoEvento, funcion)
{
	if (obj.removeEventListener) 
		obj.removeEventListener(TipoEvento, funcion, false);
	else 
		if (obj.detachEvent) 
			obj.detachEvent("on" + TipoEvento, funcion);
		else
			elem["on" + TipoEvento] = null;
};

/****************************************************************
 Se le pasa un evento generado por un objeto y nos devuelve una 
 referencia válida al mismo dependiendo del navegador
****************************************************************/
function EVTDimeEvento(evt)
{
	return (evt) ? evt : ((window.event) ? window.event : null);
};

/************************************************************************************
 Se le pasa un objeto evento y nos devuelve una referencia al objeto que lo provoco
*************************************************************************************/
function EVTDimeObjeto(evt)
{
	evt=EVTDimeEvento(evt); // Cogemos la referencia válida al evento
	if (evt)
		return (evt.target) ? evt.target : evt.srcElement;
	else
		return null;
};


/***********************************************
 Calcula en que coordenada X dentro del objeto
 se ha producido el evento
***********************************************/
function EVTCoorX(evt)
{
var x;
var left=0;
var obj;

	evt=EVTDimeEvento(evt); // Cogemos la referencia válida al evento
	obj=EVTDimeObjeto(evt);
	switch(OBJQueNavegador())
		{
		case 'IE':
		case 'GC':
			x=evt.offsetX;
			break;

		default:
			left=OBJLeft(obj);
			x=evt.pageX - left;
			break;
		};
		
	return x;
};

/***********************************************
 Calcula en que coordenada Y dentro del objeto
 se ha producido el evento
***********************************************/
function EVTCoorY(evt)
{
var y;
var top=0;
var obj;

	evt=EVTDimeEvento(evt); // Cogemos la referencia válida al evento
	obj=EVTDimeObjeto(evt);
	switch(OBJQueNavegador())
		{
		case 'IE':
		case 'GC':
			y=evt.offsetY;
			break;

		default:
			top=OBJTop(obj);
			y=evt.pageY - top;
			break;
		};
		
	return y;
};


/***********************************************
 Calcula en que coordenada X dentro de la pagina
 se ha producido el evento
***********************************************/
function EVTCoorXAbs(evt)
{
var x;
var left=0;
var obj;

	evt=EVTDimeEvento(evt); // Cogemos la referencia válida al evento
	obj=EVTDimeObjeto(evt);
	switch(OBJQueNavegador())
		{
		case 'IE':
		case 'GC':
			left=OBJLeft(obj);
			x=evt.offsetX + left;
			break;

		default:
			x=evt.pageX;
			break;
		};
		
	return x;
};

/***********************************************
 Calcula en que coordenada Y dentro de la pagina
 se ha producido el evento
***********************************************/
function EVTCoorYAbs(evt)
{
var y;
var top=0;
var obj;

	evt=EVTDimeEvento(evt); // Cogemos la referencia válida al evento
	obj=EVTDimeObjeto(evt);
	switch(OBJQueNavegador())
		{
		case 'IE':
		case 'GC':
			top=OBJTop(obj);
			y=evt.offsetY + top;
			break;

		default:
			y=evt.pageY;
			break;
		};
		
	return y;
};


/******************************************************************************
		 Devuelve la tecla pulsada

Si tipo="ASCII" devuelve el código ASCII
Si tipo="CODE" devuelve el código de la tecla

@@@ OJO que las funciones EVTCodeToAscii y EVTAsciiToCode no estan hechas
Lo unico que funciona para ambos navegadores es el CODE en el keyDown y keyUP
y el ASCII en el keyPress
*********************************************************************************/
function EVTDimeTecla(evt,tipo)
{
var PulsadoEsp=0;

	evt=EVTDimeEvento(evt);	//Cogemos la referencia valida al evento dependiendo del navegador

	//Nos preparamos una variable con la convinacion de teclas especiales pulsadas
	if (evt.shiftKey) PulsadoEsp|=1;
	if (evt.ctrlKey) PulsadoEsp|=2;
	if (evt.altKey) PulsadoEsp|=4;
	
	//Y ahora dependemos del navegador y del tipo de evento
	if (OBJQueNavegador()=='IE') 
		{
		/* En el explorer keyCode tiene el código de la tecla en los eventos keyup y keydown
		 y en el evento keypress el ascii */
		switch (evt.type)
			{
			case 'keydown':
			case 'keyup':
				if (tipo=='ASCII')
					return EVTCodeToAscii(evt.keyCode,PulsadoEsp);
				else
					return evt.keyCode;
				break;
			
			case 'keypress':
				if (tipo=='ASCII')
					return evt.keyCode;
				else
					return EVTAsciiToCode(evt.keyCode);
				break;
			};
		}
	else
		{
		/* En el firefox en el kyedown y keyup lleva en keyCode y which el código de la tecla y en keypress lleva en
		keyCode el código de la tecla y en which el ascii */
		switch (evt.type)
			{
			case 'keydown':
			case 'keyup':
				if (tipo=='ASCII')
					return EVTCodeToAscii(evt.keyCode,PulsadoEsp);
				else
					return evt.keyCode;
				break;
			
			case 'keypress':
				if (tipo=='ASCII')
					{
					if (evt.which==8) return 0;	//El retroceso no es ascii, joder
					return evt.which;
					}
				else
					return evt.keyCode;
				break;
			};		
		};
		
	return 0;	//Si no es nada de esto, un 0 y pista
};

/***************************************
 Cambia la tecla (ascii) en un evento
***************************************/
function EVTCambiaASCII(evt,ascii)
{
var obj;

	//Cogemos la referencia valida al evento dependiendo del navegador
	evt=EVTDimeEvento(evt);
	
	//Y ahora dependemos del navegador y del tipo de evento
	if (OBJQueNavegador()=='IE') 
		{
		evt.keyCode=ascii;
		}
	else
		{
		//Toda esta movida es por que la propiedad which y keyCode del evento en firefox es de solo lectura.
		evt.stopPropagation(); //Cancelo el evento original que me viene	
		evt.preventDefault();
		obj=evt.target;	//El objeto que provocó el evento
		newevt=document.createEvent('KeyboardEvent');  //me creo un nuevo evento de teclado
		newevt.initKeyEvent(evt.type,true,true,null,false,false,false,false,evt.keyCode, ascii); //Le asigno todo
		evt.target.dispatchEvent(newevt); //Y lo disparo
		};
};


/************************************************************************
			 Devuelve el ASCII de un código de tecla @@@
************************************************************************/
function EVTCodeToAscii(Code,PulsadoEsp)
{
	
	return 0;
};

/************************************************************************
			 Devuelve el CODE de la tecla de un ascii @@@
************************************************************************/
function EVTAsciiToCode(Ascii)
{
	return 0;
};


/*****************************************************************************************************************
	 Cancela la propagación en cascada del evento.
	 se le pasa la referencia al objeto evento

Supongamos que tenemos un evento de keypress en una caja de texto y en el objeto document.
Si no hacemos la llamada a esta funcion desde la funcion de evento, ocurrira que cada vez que pulsemos una tecla 
en la caja de texto, tambien se disparará el evento de la tecla pulsada del document.
******************************************************************************************************************/
function EVTNoPropagarEvento(evt)
{
	evt=EVTDimeEvento(evt);	//Cogemos la referencia valida al evento dependiendo del navegador
	if (OBJQueNavegador()=='IE') 
		{
		evt.cancelBubble=true;
		evt.returnValue=false;
		}
	else
		{
		evt.stopPropagation();
		evt.preventDefault();
		};
};

