// JavaScript Document
/* 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();
 