//Gestionaire de méthodes de la structure DOM
var DOMElement =
	{
	extend: function(name,fn)
		{
		if(navigator.appName != "Microsoft Internet Explorer")
			eval("HTMLElement.prototype." + name + " = fn");
		else
			{
			//IE doesn't allow access to HTMLElement
			//so we need to override
			//*document.createElement
			//*document.getElementById
			//*document.getElementsByTagName

			//take a copy of
			//document.createElement
			var _createElement = document.createElement;

			//override document.createElement
			document.createElement = function(tag)
				{
				var _elem = _createElement(tag);
				eval("_elem." + name + " = fn");
				return _elem;
				}

			//take copy of
			//document.getElementById
			var _getElementById = document.getElementById;

			//override document.getElementById
			document.getElementById = function(id)
				{
				var _elem = _getElementById(id);
				eval("_elem." + name + " = fn");
				return _elem;
				}

			//take copy of
			//document.getElementsByTagName
			var _getElementsByTagName = document.getElementsByTagName;

			//override document.getElementsByTagName
			document.getElementsByTagName = function(tag)
				{
				var _arr = _getElementsByTagName(tag);
				for(var _elem=0;_elem<_arr.length;_elem++)
					eval("_arr[_elem]." + name + " = fn");
				return _arr;
				}
			}
		}
	};

//Réécriture de la méthode PUSH de l'objet Array pour IE
/*Array.prototype.push = function (element)
	{ this[this.length] = element; }*/

//Vérifie si l'objet DOM contient la classe CSS recherchée
DOMElement.extend("hasClass", function ( className ) { return (this.className && this.className.match(new RegExp("\\b"+className+"\\b"))) ? true : false; });

//Optention d'élements sous forme de tableau par leur TAG et leur Classe CSS
document.getElementsByTagAndClassName = function ( tagName, className, parentElement )
	{
	var elements = new Array ();
	var parent = ( parentElement ) ? parentElement : document;
	var children = parent.getElementsByTagName(tagName);
	for ( var a = 0; a < children.length; a++ )
		{
		if ( children[a].hasClass ( className ) )
			elements.push ( children[a] );
		}
	return elements;
	};

//Optention d'élements sous forme de tableau par leur Classe CSS
document.getElementsByClassName = function ( className, parentElement )
	{ return document.getElementsByTagAndClassName( "*", className, parentElement ); };

//Optention d'élements enfants de l'objet sous forme de tableau par leur TAG et leur Classe CSS
DOMElement.extend("getElementsByTagAndClassName", function ( tagName, className )
	{ return document.getElementsByTagAndClassName ( tagName, className, this ); });

//Optention d'élements enfants de l'objet sous forme de tableau par leur TAG
DOMElement.extend("getElementsByClassName", function ( className )
	{ return document.getElementsByClassName ( className, this ); });

//Appel d'objets DOM suivant la syntaxe CSS en Global
$ =  function (str, parentElement)
	{
	var elements = new Array ();
	var parent = ( parentElement ) ? parentElement : document;

	reg = new RegExp("([A-Za-z0-9]*)(\.|\#?)(.*)");
	if (reg.test(str)) 
		{ 
		var match = reg.exec(str);
		
		switch (match[2])
			{
			case "." :
				if (match[1] != "")
					return parent.getElementsByTagAndClassName(match[1], match[3]);
				else
					return parent.getElementsByClassName(match[3]);
				break;

			case "#" :
				if (elem = parent.getElementById(match[3]))
					{
					if (match[1] != elem.nodeName && match[1] != "") 
						return false;
					
					return elem;
					}
				return false;
				break;

			default :
				return parent.getElementsByTagName(match[0]);
				break;
			}
		}
	else
		return false;
	};

//Optention d'élements enfants de l'objet 'document' suivant la syntaxe CSS contenu l'objet document
document.$ = function (str) { return $(str); };

//Optention d'élements enfants de l'objet DOM suivant la syntaxe CSS contenu l'objet document
DOMElement.extend("$", function (str) { return $(str, this); }); 

//Supprimer de l'objet
DOMElement.extend("remove", function () { this.parentNode.removeChild(this); }); 

//Supprimer de l'objet
DOMElement.extend("replace", function (newElem) { this.parentNode.replaceChild(newElem); }); 

//Masquer l'objet
DOMElement.extend("hide", function () { this.style.display = 'none'; }); 

//Afficher l'objet
DOMElement.extend("show", function (displayOpt) 
	{ (displayOpt != null && displayOpt != false) ? this.style.display = displayOpt : this.style.display = "block"; });

/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************/

var Drag = {

	obj : null,

	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
	{
		o.onmousedown = Drag.start;

		o.hmode			= bSwapHorzRef ? false : true ;
		o.vmode			= bSwapVertRef ? false : true ;

		o.root = oRoot && oRoot != null ? oRoot : o ;

		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

		o.minX	= typeof minX != 'undefined' ? minX : null;
		o.minY	= typeof minY != 'undefined' ? minY : null;
		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
		o.maxY	= typeof maxY != 'undefined' ? maxY : null;

		o.xMapper = fXMapper ? fXMapper : null;
		o.yMapper = fYMapper ? fYMapper : null;

		o.root.onDragStart	= new Function();
		o.root.onDragEnd	= new Function();
		o.root.onDrag		= new Function();
	},

	start : function(e)
	{
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.hmode) {
			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
		} else {
			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
		}

		if (o.vmode) {
			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
		} else {
			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
		}

		document.onmousemove	= Drag.drag;
		document.onmouseup		= Drag.end;

		return false;
	},

	drag : function(e)
	{
		e = Drag.fixE(e);
		var o = Drag.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		var nx, ny;

		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

		if (o.xMapper)		nx = o.xMapper(y)
		else if (o.yMapper)	ny = o.yMapper(x)

		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
		Drag.obj.lastMouseX	= ex;
		Drag.obj.lastMouseY	= ey;

		Drag.obj.root.onDrag(nx, ny);
		return false;
	},

	end : function()
	{
		document.onmousemove = null;
		document.onmouseup   = null;
		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]), 
									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
		Drag.obj = null;
	},

	fixE : function(e)
	{
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};

//Glissé/déposé de l'objet
DOMElement.extend("drag", function (oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
	{ 
	this.style.position = "absolute";
	Drag.init(this, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper);
	});

DOMElement.extend("insertAfter", function (nodeToMove, sibling) 
	{
	this.insertBefore(sibling, nodeToMove);
	});

//Glissé/déposé de l'objet
DOMElement.extend("order", function (next)
	{ 
	var parent = this.parentNode;
	//alert(parent.nodeName);
	if (next && next != null)
		(this.nextSibling != null) ? parent.insertAfter(this, this.nextSibling) : false;
	else
		(this.previousSibling != null) ? parent.insertBefore(this, this.previousSibling) : false;
	});


