/** 

 * This plugin overrides jQuery's height() and width() functions and

 * adds more handy stuff for cross-browser compatibility.

 */



/**

 * Returns the css height value for the first matched element.

 * If used on document, returns the document's height (innerHeight)

 * If used on window, returns the viewport's (window) height

 *

 * @example $("#testdiv").height()

 * @result "200px"

 *

 * @example $(document).height();

 * @result 800

 *

 * @example $(window).height();

 * @result 400

 * 

 * @name height

 * @type Object

 * @cat Plugins/Dimensions

 */

jQuery.fn.height = function() {

	if ( this.get(0) == window )

		return self.innerHeight ||

			jQuery.boxModel && document.documentElement.clientHeight ||

			document.body.clientHeight;

	

	if ( this.get(0) == document )

		return Math.max( document.body.scrollHeight, document.body.offsetHeight );

	

	return this.css("height", arguments[0]);

};



/**

 * Returns the css width value for the first matched element.

 * If used on document, returns the document's width (innerWidth)

 * If used on window, returns the viewport's (window) width

 *

 * @example $("#testdiv").width()

 * @result "200px"

 *

 * @example $(document).width();

 * @result 800

 *

 * @example $(window).width();

 * @result 400

 * 

 * @name width

 * @type Object

 * @cat Plugins/Dimensions

 */

jQuery.fn.width = function() {

	if ( this.get(0) == window )

		return self.innerWidth ||

			jQuery.boxModel && document.documentElement.clientWidth ||

			document.body.clientWidth;

	

	if ( this.get(0) == document )

		return Math.max( document.body.scrollWidth, document.body.offsetWidth );

	

	return this.css("width", arguments[0]);

};



/**

 * Returns the inner height value (without border) for the first matched element.

 * If used on document, returns the document's height (innerHeight)

 * If used on window, returns the viewport's (window) height

 *

 * @example $("#testdiv").innerHeight()

 * @result 800

 * 

 * @name innerHeight

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.innerHeight = function() {

	return this.get(0) == window || this.get(0) == document ?

		this.height() :

		this.get(0).offsetHeight - parseInt(this.css("borderTop") || 0) - parseInt(this.css("borderBottom") || 0);

};



/**

 * Returns the inner width value (without border) for the first matched element.

 * If used on document, returns the document's Width (innerWidth)

 * If used on window, returns the viewport's (window) width

 *

 * @example $("#testdiv").innerWidth()

 * @result 1000

 * 

 * @name innerWidth

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.innerWidth = function() {

	return this.get(0) == window || this.get(0) == document ?

		this.width() :

		this.get(0).offsetWidth - parseInt(this.css("borderLeft") || 0) - parseInt(this.css("borderRight") || 0);

};



/**

 * Returns the outer height value (including border) for the first matched element.

 * Cannot be used on document or window.

 *

 * @example $("#testdiv").outerHeight()

 * @result 1000

 * 

 * @name outerHeight

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.outerHeight = function() {

	return this.get(0) == window || this.get(0) == document ?

		this.height() :

		this.get(0).offsetHeight;	

};



/**

 * Returns the outer width value (including border) for the first matched element.

 * Cannot be used on document or window.

 *

 * @example $("#testdiv").outerWidth()

 * @result 1000

 * 

 * @name outerWidth

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.outerWidth = function() {

	return this.get(0) == window || this.get(0) == document ?

		this.width() :

		this.get(0).offsetWidth;	

};



/**

 * Returns how many pixels the user has scrolled to the right (scrollLeft).

 * Works on containers with overflow: auto and window/document.

 *

 * @example $("#testdiv").scrollLeft()

 * @result 100

 * 

 * @name scrollLeft

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.scrollLeft = function() {

	if ( this.get(0) == window || this.get(0) == document )

		return self.pageXOffset ||

			jQuery.boxModel && document.documentElement.scrollLeft ||

			document.body.scrollLeft;

	

	return this.get(0).scrollLeft;

};



/**

 * Returns how many pixels the user has scrolled to the bottom (scrollTop).

 * Works on containers with overflow: auto and window/document.

 *

 * @example $("#testdiv").scrollTop()

 * @result 100

 * 

 * @name scrollTop

 * @type Number

 * @cat Plugins/Dimensions

 */

jQuery.fn.scrollTop = function() {

	if ( this.get(0) == window || this.get(0) == document )

		return self.pageYOffset ||

			jQuery.boxModel && document.documentElement.scrollTop ||

			document.body.scrollTop;



	return this.get(0).scrollTop;

};



/**

 * This returns an object with top, left, width, height, borderLeft,

 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop, 

 * pageXOffset, pageYOffset.

 *

 * The top and left values include the scroll offsets but the

 * scrollLeft and scrollTop properties of the returned object

 * are the combined scroll offets of the parent elements 

 * (not including the window scroll offsets). This is not the

 * same as the element's scrollTop and scrollLeft.

 * 

 * For accurate readings make sure to use pixel values.

 *

 * @name offset	

 * @type Object

 * @cat Plugins/Dimensions

 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)

 */

/**

 * This returns an object with top, left, width, height, borderLeft,

 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop, 

 * pageXOffset, pageYOffset.

 *

 * The top and left values include the scroll offsets but the

 * scrollLeft and scrollTop properties of the returned object

 * are the combined scroll offets of the parent elements 

 * (not including the window scroll offsets). This is not the

 * same as the element's scrollTop and scrollLeft.

 * 

 * For accurate readings make sure to use pixel values.

 *

 * @name offset	

 * @type Object

 * @param String refElement This is an expression. The offset returned will be relative to the first matched element.

 * @cat Plugins/Dimensions

 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)

 */

/**

 * This returns an object with top, left, width, height, borderLeft,

 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop, 

 * pageXOffset, pageYOffset.

 *

 * The top and left values include the scroll offsets but the

 * scrollLeft and scrollTop properties of the returned object

 * are the combined scroll offets of the parent elements 

 * (not including the window scroll offsets). This is not the

 * same as the element's scrollTop and scrollLeft.

 * 

 * For accurate readings make sure to use pixel values.

 *

 * @name offset	

 * @type Object

 * @param jQuery refElement The offset returned will be relative to the first matched element.

 * @cat Plugins/Dimensions

 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)

 */

/**

 * This returns an object with top, left, width, height, borderLeft,

 * borderTop, marginLeft, marginTop, scrollLeft, scrollTop, 

 * pageXOffset, pageYOffset.

 *

 * The top and left values include the scroll offsets but the

 * scrollLeft and scrollTop properties of the returned object

 * are the combined scroll offets of the parent elements 

 * (not including the window scroll offsets). This is not the

 * same as the element's scrollTop and scrollLeft.

 * 

 * For accurate readings make sure to use pixel values.

 *

 * @name offset	

 * @type Object

 * @param HTMLElement refElement The offset returned will be relative to this element.

 * @cat Plugins/Dimensions

 * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)

 */

jQuery.fn.offset = function(refElem) {

	if (!this[0]) throw 'jQuery.fn.offset requires an element.';



	refElem = (refElem) ? jQuery(refElem)[0] : null;

	var x = 0, y = 0, elem = this[0], parent = this[0], sl = 0, st = 0;

	do {

		if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {

			// Safari and IE don't add margin for static and relative

			if ((jQuery.browser.safari || jQuery.browser.msie) && jQuery.css(parent, 'position') != 'absolute') {

				x += parseInt(jQuery.css(parent, 'marginLeft')) || 0;

				y += parseInt(jQuery.css(parent, 'marginTop'))  || 0;

			}

			break;

		}



		x += parent.offsetLeft || 0;

		y += parent.offsetTop  || 0;



		// Mozilla and IE do not add the border

		if (jQuery.browser.mozilla || jQuery.browser.msie) {

			x += parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;

			y += parseInt(jQuery.css(parent, 'borderTopWidth'))  || 0;

		}



		// Mozilla removes the border if the parent has overflow hidden

		if (jQuery.browser.mozilla && jQuery.css(parent, 'overflow') == 'hidden') {

			x += parseInt(jQuery.css(parent, 'borderLeftWidth')) || 0;

			y += parseInt(jQuery.css(parent, 'borderTopWidth'))  || 0;

		}



		// Need to get scroll offsets in-between offsetParents

		var op = parent.offsetParent;

		do {

			sl += parent.scrollLeft || 0;

			st += parent.scrollTop  || 0;

			parent = parent.parentNode;

		} while (parent != op);

	} while (parent);



	if (refElem) { // Get the relative offset

		var offset = jQuery(refElem).offset();

		x  = x  - offset.left;

		y  = y  - offset.top;

		sl = sl - offset.scrollLeft;

		st = st - offset.scrollTop;

	}



	// Safari and Opera do not add the border for the element

	if (jQuery.browser.safari || jQuery.browser.opera) {

		x += parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0;

		y += parseInt(jQuery.css(elem, 'borderTopWidth'))  || 0;

	}



	return {

		top:  y - st,

		left: x - sl,

		width:  elem.offsetWidth,

		height: elem.offsetHeight,

		borderTop:  parseInt(jQuery.css(elem, 'borderTopWidth'))  || 0,

		borderLeft: parseInt(jQuery.css(elem, 'borderLeftWidth')) || 0,

		marginTop:  parseInt(jQuery.css(elem, 'marginTopWidth'))  || 0,

		marginLeft: parseInt(jQuery.css(elem, 'marginLeftWidth')) || 0,

		scrollTop:  st,

		scrollLeft: sl,

		pageYOffset: window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop  || 0,

		pageXOffset: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0

	};

};