// Compatibilidad con el innombrable engendro de mocosoft
var is_ie = navigator.appName == 'Microsoft Internet Explorer';
// Compatibilidad con Opera
var is_op = navigator.appName == 'Opera' ? true : false;
// Compatibilidad con firefox o netscape
var is_ns = !is_ie && !is_op ? true : false;

function js_drag(e,elemento)
{
// Por situaciónes de compatibilidad para ns es 'e' suficiente, en cambio para IE e no basta sino window
// aún no entiendo ¿por qué? acaso no se supone que TODO se basa en el objeto window 8-)
e||window.event;
var e = e;
// Creamos un nuevo Objeto
var Obj = new Object();
// Obtenemos el tag BODY, ( siempre hay uno de esos )...
var body = document.getElementsByTagName('body')[0];
// El z-index ( el arrange , Hasta al frente, Hasta el fondo etc.. )
Obj.zI = 0;
// Ahora, el argumento 'elemento' puede ser un objeto o bien una id del elemento
// es decir js_drag(event,this) ó js_drag(event,'id')
Obj.Elemento = typeof(elemento) == 'object' ? elemento : document.getElementById(elemento);

// Esta función obtiene la posición en la que está el elemento HTML.
js_position = function(ly,x,y)
{
/*
Si es IE u Opera sumamos:
clientX ( que es la posición del ratón en la ventana )
document.documentElement.scrollLeft ( qué es la posición del mouse en el elemento )
body.scrollLeft ( que es el scroll que se le ha dado a la página )
Si es ns ( firefox, netscape, etcétera, )
Sólo sumamos la posición del raton en la ventana y el scroll que se le ha dado a la página.
*/
x = is_ie||is_op ? e.clientX + document.documentElement.scrollLeft + body.scrollLeft : e.clientX + window.scrollX;
y = is_ie||is_op ? e.clientY + document.documentElement.scrollTop + body.scrollTop : e.clientY + window.scrollY;
// Guardamos la posición 'x' y 'y' inicial del elemento en una variable ( contando el scroll ).
Obj.startX=x;
Obj.startY=y;
// Guardamos la posición 'Left' y 'Right' inicial del elemento en una variable ( sin contar el scroll ).
Obj.startL=parseInt(Obj.Elemento.style.left,10);
Obj.startT=parseInt(Obj.Elemento.style.top,10);
Obj.startL=isNaN(Obj.startL) ? 0 : Obj.startL;
Obj.startT=isNaN(Obj.startT) ? 0 : Obj.startT;
// Aumentamos el z-index del objeto para enviarlo hasta el frente ( aunque para IE esto no significa NADA )
Obj.Elemento.style.zIndex = ++Obj.zI;

/*
js_addEvent() es una función propia, que añade al primer argumento en este caso 'document'
una función en este caso 'startdrag' que se ejecuta cada segundo argumento en este caso 'mousemove'
*/
js_addEvent(document,'mousemove',startdrag);
// mouseup para cuando se 'suelte' el elemento
js_addEvent(document,'mouseup',enddrag);
// keypress para cuando se presione una tecla o se haga click por cuestiones conocidas
// ¿ realmente necesito explicar que es por IE ?
js_addEvent(document,'keypress',enddrag);

// Ahora prevenimos que los eventos que acabamos de agregar se ejecuten inmediatamente
if(is_ie){ e.cancelBubble = true; e.returnValue = false; } else
{
e.preventDefault();
}
};

startdrag = function(e)
{
// Esto ya lo expliqué arriba...
var x, y;
e||event;
x = is_ie||is_op ? e.clientX + document.documentElement.scrollLeft + body.scrollLeft : e.clientX + window.scrollX;
y = is_ie||is_op ? e.clientY + document.documentElement.scrollTop + body.scrollTop : e.clientY + window.scrollY;

// Sumamos las posiciones guardardas y las actuales y ésa es la posición actual ( a donde debe moverse )
ILeft = ( Obj.startL + x - parseInt(Obj.startX) );
ITop = ( Obj.startT + y - parseInt(Obj.startY) );

// js_moveTo esta función cambia la posición del elemento cambiando el estilo css presizamente 'top' y 'left'
js_moveTo(Obj.Elemento,ILeft,ITop);

// Esto también lo expliqué arriba...
if(is_ie){ e.cancelBubble = true; e.returnValue = false; }else
{
e.preventDefault();
}
};

enddrag = function (e)
{ // Cuando se deje de arrastrar entonces eliminamos los eventos que ya no nos sirven.
js_detEvent(document,'mousemove',startdrag);
js_detEvent(document,'mouseup',enddrag);
};

// Aquí inicializamos el arrastrar y soltar....
js_position(Obj.Elemento,e.clientX,e.clientY);
};

js_moveTo = function(element,Left,Top)
{
element.style.left = Left + "px";
element.style.top = Top + "px";
};

// Función que agrega los eventos
js_addEvent = function(Layer,eventype,func)
{
// addEventListener,attachEvent son propiedades para agregar funciones a eventos
if( is_ns )
Layer.addEventListener( eventype, func, true );
else if( is_ie )
Layer.attachEvent( "on" + eventype, func );
else
// Opera simplemente lo usa como un array.
Layer[ "on" + eventype ] = func;
};

// Igual que la función de arriba sólo que aquí quitamos las funciones a los eventos.
js_detEvent = function(Layer,typef,func)
{
if(is_ie)
Layer.detachEvent("on" + typef, func);
else if(is_ns)
Layer.removeEventListener( typef, func, true);
else
Layer["on" + typef] = null;
};
