/************************************
    Core module for Doubleyou.Dom scripting

    Uses:
        - Provides convenience methods for getting and setting common style properties (position, visibility, size, etc)
        -

    Version 1.0

    Author: Jose
************************************/

Doubleyou.registerModule('doubleyou.dom.core');

Doubleyou.Dom = (function(){

    var $toString = 'doubleyou.dom';

    constructorFn = function(){}

    constructorFn.getDocument = Doubleyou.getDocument;

    constructorFn.getElement = Doubleyou.getElement;

    constructorFn.toString = Doubleyou.toString;

    return constructorFn;

})();


Doubleyou.Dom.moveTo = function(el, x, y){
	this.setX(el, x);
	this.setY(el, y);
}

Doubleyou.Dom.moveBy = function(el, x, y){
	var x = (x == null) ? this.getX(el) : this.getX(el) + x;
	var y = (y == null) ? this.getY(el) : this.getY(el) + y;

	this.moveTo(el, x, y);
}

Doubleyou.Dom.setX = function(el,x){
	if (x == null || isNaN(parseInt(x, 10))) return false;

	this.getElement(el).style.left = x+'px';
}

Doubleyou.Dom.setY = function(el, y){
	if (y == null || isNaN(parseInt(y, 10))) return false;
	this.getElement(el).style.top = y+'px';
}

Doubleyou.Dom.getX = function(el){
	return parseInt(this.getElement(el).offsetLeft, 10);
}

Doubleyou.Dom.getY = function(el){
	return parseInt(this.getElement(el).offsetTop, 10);
}

Doubleyou.Dom.setSize = function(el, w, h){
	this.setWidth(el, w);
	this.setHeight(el, h);
}

Doubleyou.Dom.setWidth = function(el, w){
	if (w == null
        || isNaN(parseInt(w, 10))
        || w < 0
    ) return false;

	this.getElement(el).style.width = w+'px';
}

Doubleyou.Dom.setHeight = function(el, h){
	if (h == null
        || isNaN(parseInt(h, 10))
        || h < 0
    ) return false;

    this.getElement(el).style.height = h+'px';
}

/*
	Devuelve la anchura "real" del objeto, independientemente de los valores establecidos a través de css.


	Las propiedades <em>offsetWidth</em> y <em>offsetHeight</em> no forman parte del standard,
	pero están implementadas en todos los navegadores de última generación.

	Se utiliza estas propiedades porque el tamaño al que se renderiza
	el elemento puede variar respecto del definido a través de css:
	- El tamaño puede no estar definido o estar definido como "auto".
	- Puede que el contenido expanda el elemento.


	TO DO:
	¿Añadir una comprobación de los valores de clip?

	Parameters:
	String el - Id del elemento

	Return:
	Number - Coordenada
*/
Doubleyou.Dom.getWidth = function(el){
	return parseInt(this.getElement(el).offsetWidth, 10);
}

/*
	Name: Doubleyou.Dom.getHeiht
	Devuelve la altura "real" del objeto, independientemente de los valores establecidos a través de css.

	Ver Doubleyou.Dom.getWidth para más información.

	Parameters:
	String el - Id del elemento

	Return:
	Number - Coordenada
*/
Doubleyou.Dom.getHeight = function(el){
	return parseInt(this.getElement(el).offsetHeight, 10);
}

/*
	Name: Doubleyou.Dom.setVisible
	Establece el valor de visibilidad del elemento

	Parameters:
	String el - Id del elemento
	Boolean bol - Indica si el elemento debe hacerse visible o no

*/
Doubleyou.Dom.setVisible = function(el, bol){
	this.getElement(el).style.visibility = (bol) ? 'visible' : 'hidden';
}

/*
	Name: Doubleyou.Dom.getVisible
	Devuelve el valor de visibilidad del elemento

	Parameters:
	String el - Id del elemento

	Returns:
	Boolean - Indica si el elemento es visible o no.
*/
Doubleyou.Dom.getVisible = function(el){
	return (this.getElement(el).style.visibility == 'visible');
}

/*
	Name: Doubleyou.Dom.setZIndex
	Establece el valor de la propiedad z-index para el elemento

	Parameters:
	String el - Id del elemento
	Number z - Valor de la propiedad
*/
Doubleyou.Dom.setZIndex = function(el, z){
	this.getElement(el).style.zIndex = z;
}

/*
	Name: Doubleyou.Dom.getZIndex
	Devuelve el valor de la propiedad z-index del elemento.

	Parameters:
	String el - Id del elemento

	Returns:
	Number - Valor de la propiedad
*/

Doubleyou.Dom.getZIndex = function(el){
	return parseInt(this.getElement(el).style.zIndex,10);
}

/*
	Name: Doubleyou.Dom.setClip
	Establece el valor de las propiedades de clip para el elemento.

	Requires:
	Para poder modificar los valores de clip, el elemento debe estar posicionado absolutamente.
	El método devuelve <code>false</code> si no se cumple esta condición.

	Parameters:
	String el - Id del elemento.
	Number t - Valor de la propiedad clipTop.
	Number r - Valor de la propiedad clipRight.
	Number b - Valor de la propiedad clipBottom.
	Number l - Valor de la propiedad clipLeft.

	Returns:
	false - Si el elemento no está posicionado en absoluto.
*/

Doubleyou.Dom.setClip = function(el, t, r, b, l){
	var el = this.getElement(el);

	if (this.getStyle(el,'position')!='absolute') return false;

	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)';

	return true;
}

/*
	Name: Doubleyou.Dom.getCLip
	Devuelve un array con los valores de clip del elemento ordenados siguiendo el patrón habitual [t,r,b,l].

	Parameters:
	String el - Id del elemento

	Returns:
	Array - Conjunto de valores clip del elemento
*/
Doubleyou.Dom.getClip = function(el){

	var value = this.getStyle(this.getElement(el),'clip');

	if (!value || value==''){
		//La propiedad "clip" sólo es accesible si se ha definido inline.
		//En caso contrario, tenemos que acceder a los distintos valores por separado.
		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;
}

/*
	Name: Doubleyou.Dom.setStyle
	Establece el valor de una propiedad css.

	Parameters:
	String el - Id del elemento.
	String property - Propiedad a modificar.
	String / Number value - Valor de la propiedad.
*/
Doubleyou.Dom.setStyle = function(el, property, value){
	if (property == "cursor" && value == "hand") value = "hand, pointer";
	this.getElement(el).style[property] = value;
}

/*
	Name: Doubleyou.Dom.getStyle
	Recupera el valor de una propiedad css.

	Parameters:
	String el - Id del elemento.

	Returns:
	String / Number - Valor de la propiedad.
*/
Doubleyou.Dom.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;
}

/*
	Name: Doubleyou.Dom.getClassStyle
	Recupera un valor de estilo definido globalmente.

	En principio, este método sólo debería invocarse internamente. Para acceder a los valores debe invocarse el método @link[core.js.htm#Doubleyou.Dom.getStyle,Doubleyou.Dom.getStyle].

	Parameters:
	String el - ID del elemento
	String property - Propiedad de la que se quiere averiguar el valor

	Returns:
	String - Valor de la propiedad.
*/
Doubleyou.Dom.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);
	}
}

/*
	Name: Doubleyou.Dom.getJsToCssPropertyName
	Traduce el nombre de una propiedad css de sintaxis javascript a sintaxis css.

	Parameters:
	String str - Nombre de la propiedad

	Return:
	String
*/
Doubleyou.Dom.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;
}

Doubleyou.Dom.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;
}

Doubleyou.Dom.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;
}


Doubleyou.Dom.getAbsolutePosition = function(el) {
	var el = this.getElement(el);

	var pos = this.getStyle(el,'position');
	if (pos == 'absolute' || pos == 'relative'){
		var elX = Doubleyou.Dom.getX(el);
		var elY = Doubleyou.Dom.getY(el);
	}
	else var elX = elY = 0;

	while(el!=null){
		pos = this.getStyle(el,'position');
		if (pos == 'absolute' || pos == 'relative'){
			break;
		}
		elX+=this.getX(el);
		elY+=this.getY(el);
		el = this.getElement(el.offsetParent);
	}
	return {x:elX,y:elY}
}

Doubleyou.Dom.createElement = function(type,styleObject){
	var el = document.createElement(type);

	for (var i in styleObject)  Doubleyou.Dom.setStyle(el,i,styleObject[i]);

	return el;
}

Doubleyou.Dom.getDocumentWidth = function(){
	if (window.innerWidth) return window.innerWidth;
	else if (document.body.clientWidth) return document.body.clientWidth;
	else return false;
}

Doubleyou.Dom.getDocumentHeight = function(){

	if (window.innerHeight) return window.innerHeight;
	else{
		if(document.documentElement){
			return Math.max(document.documentElement.clientHeight, document.body.clientHeight);
		}

		else if (document.body.clientHeight){
			return document.body.clientHeight;
		}
		else return false;
	}


}
