/* This script and many more are available free online at
The JavaScript Source :: http://javascript.internet.com
Created by: Drew Diller :: http://www.dillerdesign.com/
Licensed under: MIT License */

/**
* DD_roundies, this adds rounded-corner CSS in standard browsers and VML sublayers in IE that accomplish a similar appearance when comparing said browsers.
* Author: Drew Diller
* URL: http://www.dillerdesign.com/experiment/DD_roundies/
* Version: 0.0.1a / December 2, 2008
* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_roundies/#license
*
* Usage:
* DD:roundtangle.addRule('#doc .container', 5); // selector and radius
* DD:roundtangle.addRule('.box', 5, true); // selector, radius, and optional addition of border-radius code for standard browsers.
**/

var DD_roundies = {
	ns: 'DD_roundies',
	createVmlNameSpace: function() { /* enable VML */
		if (document.namespaces && !document.namespaces[this.ns]) {
		  document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml');
		}
	},
	createVmlStyleSheet: function() { /* style VML, enable behaviors */
		/*
			Just in case lots of other developers have added
			lots of other stylesheets using document.createStyleSheet
			and hit the 31-limit mark, let's not use that method!
			further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx
		*/
		var style = document.createElement('style');
		document.documentElement.firstChild.insertBefore(style, document.documentElement.firstChild.firstChild);
		if (style.styleSheet) { /* IE */
			var styleSheet = style.styleSheet;
			styleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}');
			styleSheet.addRule(this.ns + '\\:shape', 'position:absolute; left:0px; top:0px;  z-index:-1;');
			this.styleSheet = styleSheet;
		}
		else {
			this.styleSheet = style;
		}
	},

	/**
	* This is the method to use in a document.
	* @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container'
	* @param {Integer} radius - REQUIRED - the desired radius for the box corners
	* @param {Boolean} standards - OPTIONAL - true if you also wish to output -moz-border-radius/-webkit-border-radius/border-radius declarations
	**/
	addRule: function(selector, radius, standards) {
		if (this.styleSheet.addRule) { /* IE */
			this.styleSheet.addRule(selector, 'behavior:expression(DD_roundies.roundifyElement.call(this, ' + radius + '))'); /* seems to execute the function without adding it to the stylesheet - interesting... */
		}
		else {
			this.styleSheet.appendChild(document.createTextNode(selector + ' {border-radius:' + radius + 'px; -moz-border-radius:' + radius + 'px; -webkit-border-radius:' + radius + 'px;}'));
		}
	},

	roundifyElement: function(rad) {
		this.style.behavior = 'none';
		this.style.zoom = 1;
		if (this.currentStyle.position == 'static') {
			this.style.position = 'relative';
		}
		this.vml = document.createElement(DD_roundies.ns + ':shape');

		/* methods */
		var self = this;
		this.interceptPropertyChanges = function() {
			switch (event.propertyName) {
				case 'style.border':
				case 'style.borderWidth':
				case 'style.padding':
					self.applyVML.call(self);
					break;
				case 'style.borderColor':
					self.updateVmlStrokeColor.call(self);
					break;
				case 'style.backgroundColor':
					self.updateVmlFill.call(self);
			};
		};
		this.applyVML = function() {
			this.runtimeStyle.cssText = '';
			this.updateVmlFill();
			this.updateVmlStrokeWeight();
			this.updateVmlStrokeColor();
			this.updateVmlDimensions();
			this.updateVmlPath();
			this.hideSourceBorder();
		};
		this.hideSourceBorder = function() {
			this.runtimeStyle.border = 'none';
			var sides = ['Top', 'Left', 'Right', 'Bottom'];
			for (var i=0; i<4; i++) {
				this.runtimeStyle['padding' + sides[i]] = parseInt(this.currentStyle['padding' + sides[i]]) + parseInt(this.realBorderWidth) + 'px';
			}
		};
		this.updateVmlStrokeWeight = function() {
			this.realBorderWidth = parseInt(this.currentStyle.borderWidth, 10);
			if (this.realBorderWidth.toString() == 'NaN') {
				this.realBorderWidth = 0;
			}
			this.halfRealBorderWidth = Math.floor(this.realBorderWidth/2);
			this.vml.strokeweight = this.realBorderWidth + 'px';
			this.vml.stroked = !(this.realBorderWidth === 0);
		};
		this.updateVmlStrokeColor = function() {
			this.vml.strokecolor = this.currentStyle.borderColor;
		};
		this.updateVmlFill = function() {
			this.runtimeStyle.backgroundColor = '';
			if (this.currentStyle && (this.currentStyle.backgroundImage != 'none' || (this.currentStyle.backgroundColor && this.currentStyle.backgroundColor != 'transparent'))) {
				this.vml.filled = true;
				if (!this.vml.filler) {
					this.vml.filler = document.createElement(DD_roundies.ns + ':fill');
					this.vml.appendChild(this.vml.filler);
				}
				if (this.currentStyle.backgroundImage) {
					var bg = this.currentStyle.backgroundImage;
					this.vml.filler.src = bg.substr(5, bg.lastIndexOf('")')-5);
					this.vml.filler.type = 'tile';
				}
				if (this.currentStyle.backgroundColor) {
					this.vml.filler.color = this.currentStyle.backgroundColor;
				}
				this.runtimeStyle.background = 'none';
			}
			else {
				this.vml.filled = false;
			}
		};
		this.updateVmlDimensions = function() {
			if (!this.dim) {
				this.dim = {};
			}
			this.dim.w = this.offsetWidth;
			this.dim.h = this.offsetHeight;
			this.vml.style.width = this.dim.w;
			this.vml.style.height = this.dim.h;
			this.vml.coordorigin = -this.halfRealBorderWidth + ' ' + -this.halfRealBorderWidth;
			this.vml.coordsize = (this.dim.w+this.realBorderWidth) + ' '+ (this.dim.h+this.realBorderWidth);
		};
		this.updateVmlPath = function() {
			this.vml.path = 'm0,'+rad+'qy'+rad+',0l'+(this.dim.w-rad)+',0qx'+this.dim.w+','+rad+'l'+this.dim.w+','+(this.dim.h-rad)+'qy'+(this.dim.w-rad)+','+this.dim.h+'l'+rad+','+this.dim.h+'qx0,'+(this.dim.h-rad)+'xe';
		};
		this.handlePseudoHover = function() {
			setTimeout(function() { /* wouldn't work as intended without setTimeout */
				self.runtimeStyle.backgroundColor = '';
				self.updateVmlFill.call(self);
				self.updateVmlStrokeColor.call(self);
			}, 1);
		};

		/* set up element */
		this.insertBefore(this.vml, this.firstChild);
		this.applyVML();

		/* add change handlers */
		if (this.nodeName == 'A') {
			this.attachEvent('onmouseleave', this.handlePseudoHover);
			this.attachEvent('onmouseenter', this.handlePseudoHover);
		}
		this.attachEvent('onpropertychange', this.interceptPropertyChanges);
		this.attachEvent('onresize', function() {
			self.updateVmlDimensions.call(self);
			self.updateVmlPath.call(self);
		});
	}
};
DD_roundies.createVmlNameSpace();
DD_roundies.createVmlStyleSheet();
