/**
* box-sizing Polyfill
* 
* A polyfill for box-sizing: border-box for IE6 & IE7.
* 
* JScript
* 
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published 
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* 
* See <http://www.gnu.org/licenses/lgpl-3.0.txt>
* 
* @category  JScript 
* @package   box-sizing-polyfill
* @author    Christian Schepp Schaefer <schaepp@gmx.de> <http://twitter.com/derSchepp>
* @copyright 2012 Christian Schepp Schaefer
* @license   http://www.gnu.org/copyleft/lesser.html The GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0
* @link      http://github.com/Schepp/box-sizing-polyfill 
*
* PREFACE:
*
* This box-sizing polyfill is based on previous work done by Erik Arvidsson, 
* which he published in 2002 on http://webfx.eae.net/dhtml/boxsizing/boxsizing.html.
*
* USAGE:
* 	
* Add the behavior/HTC after every `box-sizing: border-box;` that you assign:
* 
* box-sizing: border-box;
* *behavior: url(/scripts/boxsizing.htc);`
* 
* Prefix the `behavior` property with a star, like seen above, so it will only be seen by 
* IE6 & IE7, not by IE8+ who already implement box-sizing.
*
* The URL to the HTC file must be relative to your HTML(!) document, not relative to your CSS.
* That's why I'd advise you to use absolute paths like in the example.
*
*/
<component lightWeight="true">
<attach event="onpropertychange" onevent="checkPropertyChange()" />
<attach event="ondetach" onevent="restore()" />
<attach event="onresize" for="window" onevent="update()" />
<script type="text/javascript">
	//<![CDATA[

	var viewportwidth = (typeof window.innerWidth != 'undefined' ? window.innerWidth : element.document.documentElement.clientWidth);

	// Shortcut for the document object
	var doc = element.document;

	// Buffer for multiple resize events
	var resizetimeout = null;

	// Don't apply box-sizing to certain elements
	var apply = false;
	switch (element.nodeName) {
		case '#comment':
		case 'HTML':
		case 'HEAD':
		case 'TITLE':
		case 'SCRIPT':
		case 'STYLE':
		case 'LINK':
		case 'META':
			break;

		default:
			apply = true;
			break;
	}

	/*
	* update gets called during resize events, then waits until there are no further resize events, and finally triggers a recalculation
	*/
	function update() {
		if (resizetimeout !== null) {
			window.clearTimeout(resizetimeout);
		}
		resizetimeout = window.setTimeout(function () {
			restore();
			init();
			resizetimeout = null;
		}, 100);
	}

	/*
	* restore gets called when the behavior is being detached (see event binding at the top),
	* resets everything like it was before applying the behavior
	*/
	function restore() {
		if (apply) {
			element.runtimeStyle.removeAttribute("width");
			element.runtimeStyle.removeAttribute("height");
		}
	}

	/*
	* init gets called once at the start and then never again, 
	* triggers box-sizing calculations and updates width and height
	*/
	function init() {
		if (apply) {
			updateBorderBoxWidth();
			updateBorderBoxHeight();
		}
	}

	/*
	* checkPropertyChange gets called as soon as an element property changes 
	* (see event binding at the top), it then checks if any property influencing its 
	* dimensions was changed and if yes recalculates width and height 
	*/
	function checkPropertyChange() {
		if (apply) {
			var pn = event.propertyName;
			if (pn === "style.boxSizing" && element.style.boxSizing === "") {
				element.style.removeAttribute("boxSizing");
				element.runtimeStyle.removeAttribute("boxSizing");
				element.runtimeStyle.removeAttribute("width");
				element.runtimeStyle.removeAttribute("height");
			}
			switch (pn) {
				case "style.width":
				case "style.borderLeftWidth":
				case "style.borderLeftStyle":
				case "style.borderRightWidth":
				case "style.borderRightStyle":
				case "style.paddingLeft":
				case "style.paddingRight":
					updateBorderBoxWidth();
					break;

				case "style.height":
				case "style.borderTopWidth":
				case "style.borderTopStyle":
				case "style.borderBottomWidth":
				case "style.borderBottomStyle":
				case "style.paddingTop":
				case "style.paddingBottom":
					updateBorderBoxHeight();
					break;

				case "className":
				case "style.boxSizing":
					updateBorderBoxWidth();
					updateBorderBoxHeight();
					break;
			}
		}
	}

	/* 
	 * Helper function, taken from Dean Edward's IE7 framework,
	 * added by Schepp on 12.06.2010.
	 * http://code.google.com/p/ie7-js/
	 *
	 * Allows us to convert from relative to pixel-values.
	 */
	function getPixelValue(value) {
		var PIXEL = /^\d+(px)?$/i;
		if (PIXEL.test(value)) return parseInt(value);
		var style = element.style.left;
		var runtimeStyle = element.runtimeStyle.left;
		element.runtimeStyle.left = element.currentStyle.left;
		element.style.left = value || 0;
		value = parseInt(element.style.pixelLeft);
		element.style.left = style;
		element.runtimeStyle.left = runtimeStyle;

		return value;
	}

	function getPixelWidth(object, value) {
		// For Pixel Values
		var PIXEL = /^\d+(px)?$/i;
		if (PIXEL.test(value)) return parseInt(value);

		// For Percentage Values
		var PERCENT = /^[\d\.]+%$/i;
		if (PERCENT.test(value)) {
			try {
				parentWidth = getPixelWidth(object.parentElement, (object.parentElement.currentStyle.width != "auto" ? object.parentElement.currentStyle.width : "100%"));
				value = (parseFloat(value) / 100) * parentWidth;
			}
			catch (e) {
				value = (parseFloat(value) / 100) * element.document.documentElement.clientWidth;
			}
			return parseInt(value);
		}

		// For EM Values
		var style = object.style.left;
		var runtimeStyle = object.runtimeStyle.left;
		object.runtimeStyle.left = object.currentStyle.left;
		object.style.left = value || 0;
		value = parseInt(object.style.pixelLeft);
		object.style.left = style;
		object.runtimeStyle.left = runtimeStyle;

		return value;
	}

	function getPixelHeight(object, value) {
		// For Pixel Values
		var PIXEL = /^\d+(px)?$/i;
		if (PIXEL.test(value)) return parseInt(value);

		// For Percentage Values
		var PERCENT = /^[\d\.]+%$/i;
		if (PERCENT.test(value)) {
			try {
				if (object.parentElement.currentStyle.height != "auto") {
					switch (object.parentElement.nodeName) {
						default:
							parentHeight = getPixelHeight(object.parentElement, object.parentElement.currentStyle.height);
							if (parentHeight !== "auto") {
								value = (parseFloat(value) / 100) * parentHeight;
							}
							else {
								value = "auto";
							}
							break;

						case 'HTML':
							parentHeight = element.document.documentElement.clientHeight;
							if (parentHeight !== "auto") {
								value = (parseFloat(value) / 100) * parentHeight;
							}
							else {
								value = "auto";
							}
							break;
					}
					if (value !== "auto") value = parseInt(value);
				}
				else {
					value = "auto";
				}
			}
			catch (e) {
				value = "auto";
			}
			return value;
		}

		// For EM Values
		var style = object.style.left;
		var runtimeStyle = object.runtimeStyle.left;
		object.runtimeStyle.left = object.currentStyle.left;
		object.style.left = value || 0;
		value = parseInt(object.style.pixelLeft);
		object.style.left = style;
		object.runtimeStyle.left = runtimeStyle;

		return value;
	}


	/*
	 * getBorderWidth & friends
	 * Border width getters
	 */
	function getBorderWidth(sSide) {
		if (element.currentStyle["border" + sSide + "Style"] == "none") {
			return 0;
		}
		var n = getPixelValue(element.currentStyle["border" + sSide + "Width"]);
		return n || 0;
	}
	function getBorderLeftWidth() { return getBorderWidth("Left"); }
	function getBorderRightWidth() { return getBorderWidth("Right"); }
	function getBorderTopWidth() { return getBorderWidth("Top"); }
	function getBorderBottomWidth() { return getBorderWidth("Bottom"); }


	/*
	 * getPadding & friends
	 * Padding width getters
	 */
	function getPadding(sSide) {
		var n = getPixelValue(element.currentStyle["padding" + sSide]);
		return n || 0;
	}
	function getPaddingLeft() { return getPadding("Left"); }
	function getPaddingRight() { return getPadding("Right"); }
	function getPaddingTop() { return getPadding("Top"); }
	function getPaddingBottom() { return getPadding("Bottom"); }



	/*
	 * getBoxSizing
	 * Get the box-sizing value for the current element
	 */
	function getBoxSizing() {
		var s = element.style;
		var cs = element.currentStyle
		if (typeof s.boxSizing != "undefined" && s.boxSizing != "") {
			return s.boxSizing;
		}
		if (typeof s["box-sizing"] != "undefined" && s["box-sizing"] != "") {
			return s["box-sizing"];
		}
		if (typeof cs.boxSizing != "undefined" && cs.boxSizing != "") {
			return cs.boxSizing;
		}
		if (typeof cs["box-sizing"] != "undefined" && cs["box-sizing"] != "") {
			return cs["box-sizing"];
		}
		return getDocumentBoxSizing();
	}


	/*
	 * getDocumentBoxSizing
	 * Get the default document box sizing (check for quirks mode)
	 */
	function getDocumentBoxSizing() {
		if (doc.compatMode === null || doc.compatMode === "BackCompat") {
			return "border-box";
		}
		return "content-box"
	}


	/*
	 * setBorderBoxWidth & friends
	 * Width and height setters
	 */
	function setBorderBoxWidth(n) {
		element.runtimeStyle.width = Math.max(0, n - getBorderLeftWidth() -
			getPaddingLeft() - getPaddingRight() - getBorderRightWidth()) + "px";
	}
	function setBorderBoxHeight(n) {
		element.runtimeStyle.height = Math.max(0, n - getBorderTopWidth() -
			getPaddingTop() - getPaddingBottom() - getBorderBottomWidth()) + "px";
	}
	function setContentBoxWidth(n) {
		element.runtimeStyle.width = Math.max(0, n + getBorderLeftWidth() +
			getPaddingLeft() + getPaddingRight() + getBorderRightWidth()) + "px";
	}
	function setContentBoxHeight(n) {
		element.runtimeStyle.height = Math.max(0, n + getBorderTopWidth() +
			getPaddingTop() + getPaddingBottom() + getBorderBottomWidth()) + "px";
	}


	/*
	 * updateBorderBoxWidth & updateBorderBoxHeight
	 * 
	 */
	function updateBorderBoxWidth() {
		if (getDocumentBoxSizing() == getBoxSizing()) {
			return;
		}
		var csw = element.currentStyle.width;
		if (csw != "auto") {
			csw = getPixelWidth(element, csw);
			if (getBoxSizing() == "border-box") {
				setBorderBoxWidth(parseInt(csw));
			}
			else {
				setContentBoxWidth(parseInt(csw));
			}
		}
	}

	function updateBorderBoxHeight() {
		if (getDocumentBoxSizing() == getBoxSizing()) {
			return;
		}
		var csh = element.currentStyle.height;
		if (csh != "auto") {
			csh = getPixelHeight(element, csh);
			if (csh !== "auto") {
				if (getBoxSizing() == "border-box") {
					setBorderBoxHeight(parseInt(csh));
				}
				else {
					setContentBoxHeight(parseInt(csh));
				}
			}
		}
	}


	// Run the calculations
	init();

	//]]>
</script>
</component>