/********************************************************
	DOM Lib: core
		
	Provee de métodos para manipular objetos HTML mediante DOM
	
	Comentarios, dudas, sugerencias: jose@doubleyou.com
	
	Última revisión: 19/07/04
********************************************************/

/*
- Los métodos se han encapsulado dentro de un objeto
  para evitar sobreescrituras accidentales de nombres comunes (moveTo, setX,...) 
*/

/*
	TO DO
	- Organización de la librería
	- Sería interesante que el propio objeto se encargase de importar los scripts a medida que los necesitase
	- ¿Gestor de eventos?
*/

DOM = {
	//Comprobación básica de compatibilidad
	isDOM: function(){
		if (!document.getElementById) return false;
		return true;
	},
	
	//Devuelve una referencia a un objeto HTML a partir de su ID
	getElement: function(el){
		if (typeof(el)=='string'){
			if (document.getElementById) return document.getElementById(el);
			else return document.all[el];
		}
		else return el;
	},

	moveTo: function(el,x,y){
		this.setX(el,x);
		this.setY(el,y);
	},
	
	moveBy: function(el,x,y){
		var x = (x==null) ? DOM.getX(el) : DOM.getX(el)+x;
		var y = (y==null) ? DOM.getY(el) : DOM.getY(el)+y;
		
		this.moveTo(el,x,y);
	},
	
	setX: function(el,x){
		if (x==null || isNaN(parseInt(x,10))) return false;
		this.getElement(el).style.left = x+'px';
	},
	
	setY: function(el,y){
		if (y==null || isNaN(parseInt(y,10))) return false;
		this.getElement(el).style.top = y+'px';
	},
	
	getX: function(el){
		return parseInt(this.getElement(el).offsetLeft,10);
	},
	
	getY: function(el){
		return parseInt(this.getElement(el).offsetTop,10);
	},	

	setSize: function(el,w,h){
		this.setWidth(el,w);
		this.setHeight(el,h);
	},
	 
	setWidth: function(el,w){
		if (w==null || isNaN(parseInt(w,10))) return false;
		this.getElement(el).style.width = w+'px';		
	},
	
	setHeight: function(el,h){
		if (h==null || isNaN(parseInt(h,10))) return false;
		this.getElement(el).style.height = h+'px';				
	},
	
	getWidth: function(el){
		return parseInt(this.getElement(el).offsetWidth,10);
	},
	
	getHeight: function(el){
		return parseInt(this.getElement(el).offsetHeight,10);
	},
	
	setVisible: function(el,bol){
		this.getElement(el).style.visibility = (bol) ? 'visible' : 'hidden';	
	},
	
	getVisible: function(el){
		return (this.getElement(el).style.visibility=='visible');
	},
	
	setZIndex: function(el,z){
		this.getElement(el).style.zIndex = z;				
	},
	
	getZIndex: function(el){
		return parseInt(this.getElement(el).style.zIndex,10);
	},
	
	setClip: function(el,t,r,b,l){
		var el = this.getElement(el);
		
		//Para poder modificar los valores de clip, el elemento debe estar posicionado absolutamente
		if (this.getStyle(el,'position')!='absolute') return false;
		el.style.position = 'absolute';

		var t = (t!=null) ? t : 0;
		var r = (r!=null) ? r : this.getWidth(el);
		var b = (b!=null) ? b : this.getHeight(el);
		var l = (l!=null) ? l : 0;
		el.style.clip = 'rect('+t+'px, '+r+'px, '+b+'px, '+l+'px)';
	},
	
	getClip: function(el){
		
		var value = this.getStyle(this.getElement(el),'clip');

		if (!value || value==''){
			//@solved bug
			//Jose 22-07-2004
			//La propiedad "clip" sólo es accesible si se ha definido inline
			var arr = new Array();
			arr[0] = parseInt(this.getStyle(this.getElement(el),'clipTop'),10);
			arr[1] = parseInt(this.getStyle(this.getElement(el),'clipRight'),10);
			arr[2] = parseInt(this.getStyle(this.getElement(el),'clipBottom'),10);
			arr[3] = parseInt(this.getStyle(this.getElement(el),'clipLeft'),10);
		}
		else{
			value = value.substring(5);
			value = value.substring(0,value.length-1);
			var arr = value.split(' ');
			for (var i=0;i<arr.length;i++) arr[i] = parseInt(arr[i],10);
		}	

		return arr;
	},
	
	setStyle: function(el,property,value){
		if (property == "cursor" && value == "hand" && !this.browser.ie ) value="pointer";
		
		this.getElement(el).style[property] = value;
	},

	getStyle: function(el,property){
		var el = this.getElement(el);
		var value = el.style[property];
		
		//Si la propiedad no se ha declarado en el tag (<style="...">), buscamos si el valor se ha definido globalmente
		if (!value || value=='') value = this.getClassStyle(el,property);

		return value;
	},
	
	//Recupera un valor de estilo definido globalmente
	getClassStyle: function(el,property){
		var el = this.getElement(el);
		if (el.currentStyle) return el.currentStyle[property];//IE
		else if (window.getComputedStyle) {
			//Tenemos que convertir el nombre de la propiedad a tipo css: backgroundColor-->background-color
			var property = this.getJsToCssPropertyName(property);
			return window.getComputedStyle(el, "").getPropertyValue(property);
		}
	},
	
	getJsToCssPropertyName: function(str){
		var s = '';
		var len = str.length;
		var index = new Array();
		for (var i=0;i<len;i++){
			var chr = str.substring(i,i+1);
			if (chr==chr.toUpperCase()) index.push(i);
		}
		
		if (index.length==0) return str;

		s+=str.substring(0,index[0]);

		var n = index.length;

		for (var i=0;i<n;i++){
			s+='-'+str.substring(index[i],index[i]+1).toLowerCase();
			if (i<n-1) s+=str.substring(index[i]+1,index[i+1]);
			else s+=str.substring(index[i]+1);
		}

		return s;
	},
	
	getContentHeight: function(el){
		var el = this.getElement(el);
		var th = el.style.height;
		el.style.height = "auto";
	    var h = el.offsetHeight;
        el.style.height = th;
        return h;
	},

	getContentWidth: function(el){
		var el = this.getElement(el);
		var tw = el.style.width;
		el.style.width = "auto";
	    var w = el.offsetWidth;
        el.style.width = tw;
        return w;
	},	
	
	//Adaptado a partir del script de Ramón Illobre (ramon@doubleyou.com)
	//http://www.forum.dy/modules.php?name=Forums&file=viewtopic&t=6
/*
	getAbsolutePosition: function(el,bol) {
		if(!bol) var elX = elY = 0;
		else{
			var elX = DOM.getX(el);
			var elY = DOM.getY(el);
		}
		var el = this.getElement(el);
		while(el!=null){
			if (DOM.getStyle(el,'position')=='absolute') break;
			elX+=this.getX(el);
			elY+=this.getY(el);
			el = this.getElement(el.offsetParent);
		}
		return {x:elX,y:elY} 
	},	
*/

	getAbsolutePosition: function(el) {
		var el = this.getElement(el);
		if (this.getStyle(el,'position')=='absolute'){
			var elX = DOM.getX(el);
			var elY = DOM.getY(el);		
		}
		else var elX = elY = 0;
		
		while(el!=null){
			if (DOM.getStyle(el,'position')=='absolute') break;
			elX+=this.getX(el);
			elY+=this.getY(el);
			el = this.getElement(el.offsetParent);
		}
		return {x:elX,y:elY} 
	},	
	
	createElement: function(type,styleObject){
		var el = document.createElement(type);
		//for (var i in styleObject) el.style[i] = styleObject[i];
		for (var i in styleObject)  DOM.setStyle(el,i,styleObject[i])
		return el;
	}
}
DOM.resizeTo = function( elm, w, h, spd)
{
	if (spd)
	{
		var ex = false
		for (var i = 0; i < DOMResizeToArray.length; i++)
		{

			if(DOMResizeToArray[i].elm == DOM.getElement(elm))
			{
				DOMResizeToArray[i].endW=w
				DOMResizeToArray[i].endH=h
				if (!DOMResizeToArray[i].timer) DOMResizeToArray[i].loop()
				ex=true
			}
		}
		if (!ex)
		{
			var domres = new DOMresizeTo(elm,w,h,spd)
			DOMResizeToArray[DOMResizeToArray.length] = domres
		}
	}
	else
	{
		DOM.setWidth(elm,w)
		DOM.setHeight(elm,h)
	}
}

DOMresizeToCounter = 0
DOMResizeToArray = []
DOMresizeTo = function( elm, w, h, spd)
{
	this.elm = elm;
	this.endW = w || DOM.getClip(elm)[1];
	this.endH = h || DOM.getClip(elm)[2];
	this.spd = spd || 5;
	this.timer;
	this.obj = 'resizeTo'+DOMresizeToCounter++;
	eval(this.obj+'=this')
	this.loop();
}
DOMresizeTo.prototype.loop = function()
{
	var act_w = parseInt ( DOM.getStyle(this.elm,"width"), 10 );
	var act_h = parseInt ( DOM.getStyle(this.elm,"height"), 10 );
	var new_w = Math.round ( (this.endW - act_w ) / this.spd );
	var new_h = Math.round ( (this.endH - act_h ) / this.spd );
	if ( Math.abs( new_w ) < 1 && Math.abs( new_h ) < 1)
	{
		DOM.setWidth( this.elm, this.endW)
		DOM.setHeight( this.elm, this.endH)

		if (this.elm.onResizeTo) this.elm.onResizeTo();
		this.timer=null;
	}
	else 
	{
		DOM.setWidth( this.elm, act_w + new_w)
		DOM.setHeight( this.elm, act_h + new_h)
		this.timer = setTimeout(this.obj + ".loop()",30)
	}
}

DOM.getElementsByAttribute = function(attrib){
	var arr = document.getElementsByTagName('*');
	var arrResponse = new Array();
	
	for (var i=arr.length;i--;){
		if (arr[i].getAttribute(attrib)) arrResponse[arrResponse.length] = arr[i];
	}
	
	return arrResponse;
}

DOM.getDocumentW = function(){
	if (window.innerWidth) return window.innerWidth; 
	else if (document.body.clientWidth) return document.body.clientWidth; 
	else return false;
}

DOM.getDocumentH = function(){
	if (window.innerHeight) return window.innerHeight; 
	else {
		if(document.documentElement.clientHeight) return document.documentElement.clientHeight;
		else if (document.body.clientHeight) return document.body.clientHeight; 
		else return false;
	}

}