/*======================================================================================================================================================
* 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
* Email: drew.diller@gmail.com
* URL: http://www.dillerdesign.com/experiment/DD_roundies/
* Version: 0.0.2a
* Licensed under the MIT License: http://dillerdesign.com/experiment/DD_roundies/#license
*
* Usage:
* DD_roundies.addRule('#doc .container', '10px 5px'); // selector and multiple radii
* DD_roundies.addRule('.box', 5, true); // selector, radius, and optional addition of border-radius code for standard browsers.
* 
* Just want the PNG fixing effect for IE6, and don't want to also use the DD_belatedPNG library?  Don't give any additional arguments after the CSS selector.
* DD_roundies.addRule('.your .example img');
======================================================================================================================================================*/
var DD_roundies =
{
 ns: 'DD_roundies',
 IE6: false,
 IE7: false,
 IE8: false,
 IEversion: function()
 {
  if (document.documentMode != 8 && document.namespaces && !document.namespaces[this.ns])
  {
   this.IE6 = true;
   this.IE7 = true;
  }
  else if (document.documentMode == 8)
  {
   this.IE8 = true;
  }
 },
 querySelector: document.querySelectorAll,
 selectorsToProcess: [],
 imgSize: {},
 createVmlNameSpace: function()
 { /* enable VML */
  if (this.IE6 || this.IE7)
  {
   document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml');
  }
  if (this.IE8)
  {
   document.writeln('<?import namespace="' + this.ns + '" implementation="#default#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 */
   try
   {
    var styleSheet = style.styleSheet;
    styleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}');
    this.styleSheet = styleSheet;
   }
   catch(err) {}
  }
  else
  {
   this.styleSheet = style;
  }
 },
 /**
 * Method to use from afar - refer to it whenever.
 * Example for IE only: DD_roundies.addRule('div.boxy_box', '10px 5px');
 * Example for IE, Firefox, and WebKit: DD_roundies.addRule('div.boxy_box', '10px 5px', true);
 * @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, rad, standards)
 {
  if (typeof rad == 'undefined' || rad === null)
  {
   rad = 0;
  }
  if (rad.constructor.toString().search('Array') == -1)
  {
   rad = rad.toString().replace(/[^0-9 ]/g, '').split(' ');
  }
  for (var i=0; i<4; i++)
  {
   rad[i] = (!rad[i] && rad[i] !== 0) ? rad[Math.max((i-2), 0)] : rad[i];
  }
  if (this.styleSheet)
  {
   if (this.styleSheet.addRule)
   { /* IE */
    var selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */
    for (var i=0; i<selectors.length; i++)
    {
     this.styleSheet.addRule(selectors[i], 'behavior:expression(DD_roundies.roundify.call(this, [' + rad.join(',') + ']))'); /* seems to execute the function without adding it to the stylesheet - interesting... */
    }
   }
   else if (standards)
   {
    var moz_implementation = rad.join('px ') + 'px';
    this.styleSheet.appendChild(document.createTextNode(selector + ' {border-radius:' + moz_implementation + '; -moz-border-radius:' + moz_implementation + ';}'));
    this.styleSheet.appendChild(document.createTextNode(selector + ' {-webkit-border-top-left-radius:' + rad[0] + 'px ' + rad[0] + 'px; -webkit-border-top-right-radius:' + rad[1] + 'px ' + rad[1] + 'px; -webkit-border-bottom-right-radius:' + rad[2] + 'px ' + rad[2] + 'px; -webkit-border-bottom-left-radius:' + rad[3] + 'px ' + rad[3] + 'px;}'));
   }
  }
  else if (this.IE8)
  {
   this.selectorsToProcess.push({'selector':selector, 'radii':rad});
  }
 },
 readPropertyChanges: function(el)
 {
  switch (event.propertyName)
  {
   case 'style.border':
   case 'style.borderWidth':
   case 'style.padding':
    this.applyVML(el);
    break;
   case 'style.borderColor':
    this.vmlStrokeColor(el);
    break;
   case 'style.backgroundColor':
   case 'style.backgroundPosition':
   case 'style.backgroundRepeat':
    this.applyVML(el);
    break;
   case 'style.display':
    el.vmlBox.style.display = (el.style.display == 'none') ? 'none' : 'block';
    break;
   case 'style.filter':
    this.vmlOpacity(el);
    break;
   case 'style.zIndex':
    el.vmlBox.style.zIndex = el.style.zIndex;
    break;
  }
 },
 applyVML: function(el)
 {
  el.runtimeStyle.cssText = '';
  this.vmlFill(el);
  this.vmlStrokeColor(el);
  this.vmlStrokeWeight(el);
  this.vmlOffsets(el);
  this.vmlPath(el);
  this.nixBorder(el);
  this.vmlOpacity(el);
 },
 vmlOpacity: function(el)
 {
  if (el.currentStyle.filter.search('lpha') != -1)
  {
   var trans = el.currentStyle.filter;
   trans = parseInt(trans.substring(trans.lastIndexOf('=')+1, trans.lastIndexOf(')')), 10)/100;
   for (var v in el.vml)
   {
    el.vml[v].filler.opacity = trans;
   }
  }
 },
 vmlFill: function(el)
 {
  if (!el.currentStyle)
  {
   return;
  }
  else
  {
   var elStyle = el.currentStyle;
  }
  el.runtimeStyle.backgroundColor = '';
  el.runtimeStyle.backgroundImage = '';
  var noColor = (elStyle.backgroundColor == 'transparent');
  var noImg = true;
  if (elStyle.backgroundImage != 'none' || el.isImg)
  {
   if (!el.isImg)
   {
    el.vmlBg = elStyle.backgroundImage;
    el.vmlBg = el.vmlBg.substr(5, el.vmlBg.lastIndexOf('")')-5);
   }
   else
   {
    el.vmlBg = el.src;
   }
   var lib = this;
   if (!lib.imgSize[el.vmlBg])
   { /* determine size of loaded image */
    var img = document.createElement('img');
    img.attachEvent('onload', function()
    {
     this.width = this.offsetWidth; /* weird cache-busting requirement! */
     this.height = this.offsetHeight;
     lib.vmlOffsets(el);
    });
    img.className = lib.ns + '_sizeFinder';
    img.runtimeStyle.cssText = 'behavior:none; position:absolute; top:-10000px; left:-10000px; border:none;'; /* make sure to set behavior to none to prevent accidental matching of the helper elements! */
    img.src = el.vmlBg;
    img.removeAttribute('width');
    img.removeAttribute('height');
    document.body.insertBefore(img, document.body.firstChild);
    lib.imgSize[el.vmlBg] = img;
   }
   el.vml.image.filler.src = el.vmlBg;
   noImg = false;
  }
  el.vml.image.filled = !noImg;
  el.vml.image.fillcolor = 'none';
  el.vml.color.filled = !noColor;
  el.vml.color.fillcolor = elStyle.backgroundColor;
  el.runtimeStyle.backgroundImage = 'none';
  el.runtimeStyle.backgroundColor = 'transparent';
 },
 
 vmlStrokeColor: function(el) 
 {
  el.vml.stroke.fillcolor = el.currentStyle.borderColor;
 },
 
 vmlStrokeWeight: function(el)
 {
  var borders = ['Top', 'Right', 'Bottom', 'Left'];
  el.bW = {};
  for (var b=0; b<4; b++)
  {
   el.bW[borders[b]] = parseInt(el.currentStyle['border' + borders[b] + 'Width'], 10) || 0;
  }
 },
 vmlOffsets: function(el)
 {
  var dims = ['Left', 'Top', 'Width', 'Height'];
  for (var d=0; d<4; d++)
  {
   el.dim[dims[d]] = el['offset'+dims[d]];
  }
  var assign = function(obj, topLeft)
  {
   obj.style.left = (topLeft ? 0 : el.dim.Left) + 'px';
   obj.style.top = (topLeft ? 0 : el.dim.Top) + 'px';
   obj.style.width = el.dim.Width + 'px';
   obj.style.height = el.dim.Height + 'px';
  };
  for (var v in el.vml)
  {
   var mult = (v == 'image') ? 1 : 2;
   el.vml[v].coordsize = (el.dim.Width*mult) + ', ' + (el.dim.Height*mult);
   assign(el.vml[v], true);
  }
  assign(el.vmlBox, false);
  
  if (DD_roundies.IE8)
  {
   el.vml.stroke.style.margin = '-1px';
   if (typeof el.bW == 'undefined')
   {
    this.vmlStrokeWeight(el);
   }
   el.vml.color.style.margin = (el.bW.Top-1) + 'px ' + (el.bW.Left-1) + 'px';
  }
 },
 
 vmlPath: function(el)
 {
  var coords = function(direction, w, h, r, aL, aT, mult)
  {
   var cmd = direction ? ['m', 'qy', 'l', 'qx', 'l', 'qy', 'l', 'qx', 'l'] : ['qx', 'l', 'qy', 'l', 'qx', 'l', 'qy', 'l', 'm']; /* whoa */
   aL *= mult;
   aT *= mult;
   w *= mult;
   h *= mult;
   var R = r.slice(); /* do not affect original array */
   for (var i=0; i<4; i++)
   {
    R[i] *= mult;
    R[i] = Math.min(w/2, h/2, R[i]); /* make sure you do not get funky shapes - pick the smallest: half of the width, half of the height, or current value */
   }
   var coords = [
    cmd[0] + Math.floor(0+aL) +','+ Math.floor(R[0]+aT),
    cmd[1] + Math.floor(R[0]+aL) +','+ Math.floor(0+aT),
    cmd[2] + Math.ceil(w-R[1]+aL) +','+ Math.floor(0+aT),
    cmd[3] + Math.ceil(w+aL) +','+ Math.floor(R[1]+aT),
    cmd[4] + Math.ceil(w+aL) +','+ Math.ceil(h-R[2]+aT),
    cmd[5] + Math.ceil(w-R[2]+aL) +','+ Math.ceil(h+aT),
    cmd[6] + Math.floor(R[3]+aL) +','+ Math.ceil(h+aT),
    cmd[7] + Math.floor(0+aL) +','+ Math.ceil(h-R[3]+aT),
    cmd[8] + Math.floor(0+aL) +','+ Math.floor(R[0]+aT)
   ];
   if (!direction)
   {
    coords.reverse();
   }
   var path = coords.join('');
   return path;
  };
 
  if (typeof el.bW == 'undefined')
  {
   this.vmlStrokeWeight(el);
  }
  var bW = el.bW;
  var rad = el.DD_radii.slice();
  
  /* determine outer curves */
  var outer = coords(true, el.dim.Width, el.dim.Height, rad, 0, 0, 2);
  
  /* determine inner curves */
  rad[0] -= Math.max(bW.Left, bW.Top);
  rad[1] -= Math.max(bW.Top, bW.Right);
  rad[2] -= Math.max(bW.Right, bW.Bottom);
  rad[3] -= Math.max(bW.Bottom, bW.Left);
  for (var i=0; i<4; i++) {
   rad[i] = Math.max(rad[i], 0);
  }
  var inner = coords(false, el.dim.Width-bW.Left-bW.Right, el.dim.Height-bW.Top-bW.Bottom, rad, bW.Left, bW.Top, 2);
  var image = coords(true, el.dim.Width-bW.Left-bW.Right+1, el.dim.Height-bW.Top-bW.Bottom+1, rad, bW.Left, bW.Top, 1);
  
  /* apply huge path string */
  el.vml.color.path = inner;
  el.vml.image.path = image;
  el.vml.stroke.path = outer + inner;
  this.clipImage(el);
 },
 nixBorder: function(el)
 {
  var s = el.currentStyle;
  var sides = ['Top', 'Left', 'Right', 'Bottom'];
  for (var i=0; i<4; i++)
  {
   el.runtimeStyle['padding' + sides[i]] = (parseInt(s['padding' + sides[i]], 10) || 0) + (parseInt(s['border' + sides[i] + 'Width'], 10) || 0) + 'px';
  }
  el.runtimeStyle.border = 'none';
 },
 
 clipImage: function(el)
 {
  var lib = DD_roundies;
  if (!el.vmlBg || !lib.imgSize[el.vmlBg])
  {
   return;
  }
  var thisStyle = el.currentStyle;
  var bg = {'X':0, 'Y':0};
  var figurePercentage = function(axis, position)
  {
   var fraction = true;
   switch(position)
   {
    case 'left':
    case 'top':
     bg[axis] = 0;
     break;
    case 'center':
     bg[axis] = 0.5;
     break;
    case 'right':
    case 'bottom':
     bg[axis] = 1;
     break;
    default:
     if (position.search('%') != -1)
     {
      bg[axis] = parseInt(position, 10) * 0.01;
     }
     else 
     {
      fraction = false;
     }
   }
   var horz = (axis == 'X');
   bg[axis] = Math.ceil(fraction ? (( el.dim[horz ? 'Width' : 'Height'] - (el.bW[horz ? 'Left' : 'Top'] + el.bW[horz ? 'Right' : 'Bottom']) ) * bg[axis]) - (lib.imgSize[el.vmlBg][horz ? 'width' : 'height'] * bg[axis]) : parseInt(position, 10));
   bg[axis] += 1;
  };
  for (var b in bg)
  {
   figurePercentage(b, thisStyle['backgroundPosition'+b]);
  }
  el.vml.image.filler.position = (bg.X/(el.dim.Width-el.bW.Left-el.bW.Right+1)) + ',' + (bg.Y/(el.dim.Height-el.bW.Top-el.bW.Bottom+1));
  var bgR = thisStyle.backgroundRepeat;
  var c = {'T':1, 'R':el.dim.Width+1, 'B':el.dim.Height+1, 'L':1}; /* these are defaults for repeat of any kind */
  var altC = { 'X': {'b1': 'L', 'b2': 'R', 'd': 'Width'}, 'Y': {'b1': 'T', 'b2': 'B', 'd': 'Height'} };
  if (bgR != 'repeat')
  {
   c = {'T':(bg.Y), 'R':(bg.X+lib.imgSize[el.vmlBg].width), 'B':(bg.Y+lib.imgSize[el.vmlBg].height), 'L':(bg.X)}; /* these are defaults for no-repeat - clips down to the image location */
   if (bgR.search('repeat-') != -1) 
   { /* now let's revert to dC for repeat-x or repeat-y */
    var v = bgR.split('repeat-')[1].toUpperCase();
    c[altC[v].b1] = 1;
    c[altC[v].b2] = el.dim[altC[v].d]+1;
   }
   if (c.B > el.dim.Height)
   {
    c.B = el.dim.Height+1;
   }
  }
  el.vml.image.style.clip = 'rect('+c.T+'px '+c.R+'px '+c.B+'px '+c.L+'px)';
 },
 
 pseudoClass: function(el)
 {
  var self = this;
  setTimeout(function() { /* would not work as intended without setTimeout */
   self.applyVML(el);
  }, 1);
 },
 
 reposition: function(el)
 {
  this.vmlOffsets(el);
  this.vmlPath(el);
 },
 
 roundify: function(rad)
 {
  this.style.behavior = 'none';
  if (!this.currentStyle)
  {
   return;
  }
  else
  {
   var thisStyle = this.currentStyle;
  }
  var allowed = {BODY: false, TABLE: false, TR: false, TD: false, SELECT: false, OPTION: false, TEXTAREA: false};
  if (allowed[this.nodeName] === false)
  { /* elements not supported yet */
   return;
  }
  var self = this; /* who knows when you might need a setTimeout */
  var lib = DD_roundies;
  this.DD_radii = rad;
  this.dim = {};

  /* attach handlers */
  var handlers = {resize: 'reposition', move: 'reposition'};
  if (this.nodeName == 'A')
  {
   var moreForAs = {mouseleave: 'pseudoClass', mouseenter: 'pseudoClass', focus: 'pseudoClass', blur: 'pseudoClass'};
   for (var a in moreForAs)
   {
    handlers[a] = moreForAs[a];
   }
  }
  for (var h in handlers)
  {
   this.attachEvent('on' + h, function()
   {
    lib[handlers[h]](self);
   });
  }
  this.attachEvent('onpropertychange', function()
  {
   lib.readPropertyChanges(self);
  });
  
  /* ensure that this elent and its parent is given hasLayout (needed for accurate positioning) */
  var giveLayout = function(el)
  {
   el.style.zoom = 1;
   if (el.currentStyle.position == 'static')
   {
    el.style.position = 'relative';
   }
  };
  giveLayout(this.offsetParent);
  giveLayout(this);
  
  /* create vml elements */
  this.vmlBox = document.createElement('ignore'); /* IE8 really wants to be encased in a wrapper element for the VML to work, and I don't want to disturb getElementsByTagName('div') - open to suggestion on how to do this differently */
  this.vmlBox.runtimeStyle.cssText = 'behavior:none; position:absolute; margin:0; padding:0; border:0; background:none;'; /* super important - if something accidentally matches this (you yourseld did this once, Drew), you'll get infinitely-created elements and a frozen browser! */
  this.vmlBox.style.zIndex = thisStyle.zIndex;
  this.vml = {'color':true, 'image':true, 'stroke':true};
  for (var v in this.vml)
  {
   this.vml[v] = document.createElement(lib.ns + ':shape');
   this.vml[v].filler = document.createElement(lib.ns + ':fill');
   this.vml[v].appendChild(this.vml[v].filler);
   this.vml[v].stroked = false;
   this.vml[v].style.position = 'absolute';
   this.vml[v].style.zIndex = thisStyle.zIndex;
   this.vml[v].coordorigin = '1,1';
   this.vmlBox.appendChild(this.vml[v]);
  }
  this.vml.image.fillcolor = 'none';
  this.vml.image.filler.type = 'tile';
  this.parentNode.insertBefore(this.vmlBox, this);
  
  this.isImg = false;
  if (this.nodeName == 'IMG')
  {
   this.isImg = true;
   this.style.visibility = 'hidden';
  }
  
  setTimeout(function()
  {
   lib.applyVML(self);
  }, 1);
 }
 
};

try 
{
 document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}
DD_roundies.IEversion();
DD_roundies.createVmlNameSpace();
DD_roundies.createVmlStyleSheet();

if (DD_roundies.IE8 && document.attachEvent && DD_roundies.querySelector)
{
 document.attachEvent('onreadystatechange', function()
 {
  if (document.readyState == 'complete') 
  {
   var selectors = DD_roundies.selectorsToProcess;
   var length = selectors.length;
   var delayedCall = function(node, radii, index) 
   {
    setTimeout(function() {
     DD_roundies.roundify.call(node, radii);
    }, index*100);
   };
   for (var i=0; i<length; i++) 
   {
    var results = document.querySelectorAll(selectors[i].selector);
    var rLength = results.length;
    for (var r=0; r<rLength; r++) 
    {
     if (results[r].nodeName != 'INPUT') { /* IE8 doesn't like to do this to inputs yet */
      delayedCall(results[r], selectors[i].radii, r);
     }
    }
   }
  }
 });
}