
/**
 * (./) css.js, v0.3, 04/10/2010
 * (by) cousot stephane @ http://www.ubaa.net/
 * (cc) some right reserved
 *
 * Javascript CSS object.
 * Useful cross browsers methods to figure out or set miscellaneous element style properties value 
 * from Javascript, DOM properties or computed styles.
 *
 * This script is released under a Creative Commons Attribution 3.0 License
 * ‹ http://creativecommons.org/licenses/by/3.0/ ›
 */
 	 
 	 
 	 
 	 



var CSS = {
	
	
	
	// use to store miscellaneous element's properties
	_default : {},
	
	
	
	/**
	 * Return the computed CSS style property for the given element.
	 *
	 * @param elem	the element or element ID to retrieve style
	 * @param prop	the style property name
	 * @param parse	true to get the result as int (string by default)
	 * @return String or int
	 */
	get : function( elem, prop, parse ) {
		
		var val = "";
		
		elem = CSS.element( elem );
		
		if ( elem.currentStyle ) {
			val = elem.currentStyle[ prop ];
		}
		else if ( window.getComputedStyle && document.defaultView.getComputedStyle(elem,null) ) {
			val = document.defaultView.getComputedStyle(elem,null).getPropertyValue( prop );
		}
		
        if ( val && val=="none" ) return parse ? 0 : "0px";
		return parse ? parseInt(val) : val;
	},
	
	
	
	/**
	 * Compute and return the real top position for the specified object.
	 *
	 * @param elem	the element to be checked
	 * @return int
	 */
	offsetTop : function( elem ) {
		
		elem = CSS.element( elem );
		
		var t = elem.offsetTop;
		var p = elem.offsetParent;
  		while( p!=null) {
  			t += p.offsetTop;
	  		p = p.offsetParent;
  		}
		return t;
	},
	
	
	/**
	 * Compute and return the real left position for the specified object.
	 *
	 * @param elem	the element to be checked
	 * @return int
	 */
	offsetLeft : function( elem ) {
		
		elem = CSS.element( elem );
		
		var l = elem.offsetLeft;
		var p = elem.offsetParent;
  		while( p!=null) {
  			l += p.offsetLeft;
	  		p = p.offsetParent;
  		}
		return l;
	},
	
	
	
	/**
	 * Return both vertical and horizontal the page scroll offset.
	 * fix: window.pageXOffset + window.pageYOffset for IE
	 */
	pageOffset : function() {
		return { x: CSS.pageOffsetTop(), y: CSS.pageOffsetLeft() };
	},
	
	
	
	/**
	 * Return the page vertical scroll offset.
	 * fix: window.pageYOffset for IE
	 */
	pageOffsetTop : function() {
		if ( typeof(window.pageYOffset)=='number' ) return window.pageYOffset;	// netscape compliant
		else if ( document.body && document.body.scrollTop ) return document.body.scrollTop;  // DOM compliant
		else if ( document.documentElement && document.documentElement.scrollTop ) return document.documentElement.scrollTop; // IE compliant
		return 0;
	},
	
	
	/**
	 * Return the page horizontal scroll offset.
	 * fix: window.pageYOffset for IE
	 */
	pageOffsetLeft : function() {
		if ( typeof(window.pageXOffset)=='number' ) return window.pageXOffset;	// netscape compliant
		else if ( document.body && document.body.scrollLeft ) return document.body.scrollLeft; // DOM compliant
		else if ( document.documentElement && document.documentElement.scrollLeft ) return document.documentElement.scrollLeft; // IE compliant
	},
	
	
	/**
	 * Return both vertical and horizontal window inner dimension.
	 * fix: window.innerWidth + window.innerHeight for IE
	 */
	windowSize : function() {
		return { width: CSS.windowWidth(), height: CSS.windowHeight() };
	},
	
	
	/**
	 * Return the horizontal window dimension.
	 * fix: window.innerWidth for IE
	 */
	windowWidth : function() {
		if ( typeof(window.innerWidth)=='number' ) return window.innerWidth;	// netscape compliant
		else if ( document.documentElement && document.documentElement.clientWidth ) return document.documentElement.clientWidth; // IE compliant
		else if ( document.body && document.body.clientWidth ) return document.body.clientWidth; // DOM compliant
	},
	
	
	/**
	 * Return the vertical window dimension.
	 * fix: window.innerHeight for IE
	 */
	windowHeight : function() {
		if ( typeof(window.innerHeight)=='number' ) return window.innerHeight;	// netscape compliant
		else if ( document.documentElement && document.documentElement.clientHeight ) return document.documentElement.clientHeight; // IE compliant
		else if ( document.body && document.body.clientHeight ) return document.body.clientHeight; // DOM compliant
	},
	
	
	
	
	/**
	 * Try to return the element  specified by the given element ID.
	 *
	 * @param elem	the elment id (or the element itself)
	 * @return object
	 */
	element : function( elem ) {
		return typeof(elem)=="string" ? document.getElementById(elem) : elem;
	},
	
	
	
	/// TRANSFORM //////////////////////////////////////////////////////////////////////////////////
	
	
	/**
	 * Specifies a 2D scaling operation to the given dimensions.
	 * note: if h argument isn't specified, it is assumed to be equal to w.
	 *
	 * @param elem	the element or element id
	 * @param w		the new element width size
	 * @param h		[ the new element height size ]
	 *
	 * @return the new element size and scale properties as object { width:*, height:*, scale: {x:*,y:*} }
	 */
	scale : function( elem, w, h ) {
		
		elem = CSS.element( elem );
		if ( h==null ) h = w;
		
		
		// store default properties
		if ( !CSS._default[elem] ) CSS._default[ elem ] = {};
		if ( !CSS._default[elem].width  ) CSS._default[ elem ].width  = CSS.get( elem, "width", true );
		if ( !CSS._default[elem].height ) CSS._default[ elem ].height = CSS.get( elem, "height", true );

		
		var x = w / CSS._default[ elem ].width;
		var y = h / CSS._default[ elem ].height;
		
		
		
		// webkit > 525
		if ( elem.style.webkitTransform!==undefined ) {
			elem.style.webkitTransformOrigin = "0 0";
			elem.style.webkitTransform = "scale("+x+","+y+")";
		}
		// Gecko >= 1.9.1
		else if ( elem.style.MozTransform!==undefined ) {
			elem.style.MozTransformOrigin = "0 0";
			elem.style.MozTransform = "scale("+x+","+y+")";
		}
		// FIXME: Opera > 10.5
		else if ( elem.style.oTransform!==undefined ) {
			elem.style.oTransformOrigin = "0 0";
			elem.style.oTransform = "scale("+x+","+y+")";
		}
		// IE > 5.5
		else if ( elem.style.filter!==undefined ) {
			elem.style.width  = ( x>1 ? w : CSS._default[elem].width  ) + 'px';
			elem.style.height = ( y>1 ? h : CSS._default[elem].height ) + 'px';
			elem.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11="+x+",M22="+y+")";
		}
		
		
		// return element size
		return {
			width	: Math.round( CSS._default[elem].width  * x ),
			height	: Math.round( CSS._default[elem].height * y ),
			scale	: { x: x, y: y }
		};
	},
	
	
	/**
	 * Perform a 2D translation by the given amount along the X and Y axis.
	 * note: If y argument isn't specified, it is assumed to be equal to x. If element position is 
	 * not set to 'absolute' or 'fixed', it is assumed to be equal to 'absolute'.
	 *
	 * @param elem	the element or element id
	 * @param x		the amount along x axis
	 * @param y		[ the amount along y axis ]
	 */
	translate : function( elem, x, y ) {
		elem = CSS.element( elem );
		CSS.move( elem, CSS.parseInt(elem.style.left)+x, CSS.parseInt(elem.style.top)+y );
	},
	
	
	
	/**
	 * Move the specify element to the given location.
	 * note: If y argument isn't specified, it is assumed to be equal to x. If element position is 
	 * not set to 'absolute' or 'fixed', it is assumed to be equal to 'absolute'.
	 *
	 * @param elem	the element or element id
	 * @param x		the x coordinate position
	 * @param y		[ the y coordinate position ]
	 */
	move : function( elem, x, y ) {
		
		elem = CSS.element( elem );
		if ( y==null ) y = x;
		
		// fix position
		if ( CSS.get(elem,"position")=="static" || CSS.get(elem,"position")=="relative" ) 
			elem.style.position = "absolute";
		
		elem.style.left	= x + 'px';
		elem.style.top	= y + 'px';
	},

	
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	// return
	parseInt : function( val ) {
		return val=="" ? 0 : parseInt( val );
	}
}

