/**
* Cornerz 0.6 - Bullet Proof Corners
* Jonah Fox (jonah@parkerfox.co.uk) 2008
* 
* Usage: $('.myclass').curve(options)
* options is a hash with the following parameters. Bracketed is the default
*   radius (10)
*   borderWidth (read from BorderTopWidth or 0)
*   background ("white"). Note that this is not calculated from the HTML as it is expensive
*   borderColor (read from BorderTopColor)
*   corners ("tl br tr bl"). Specify which borders
*   fixIE ("padding") - attmepts to fix IE by incrementing the property by 1 if the outer width/height is odd.

CHANGELIST from  v0.4

0.5 - Now attempts to fix the odd dimension problem in IE 
0.6 - Added semicolons for packing and fixed a problem with odd border width's in IE

*/
    
(function($){

  if($.browser.msie && document.namespaces["v"] == null) {
   document.namespaces.add("v", "urn:schemas-microsoft-com:vml", "#default#VML");
  }

  // chicken code
  // if(!document.documentMode || document.documentMode<8) { 
  //   document.createStyleSheet().addRule('v\\:*', "behavior: url (#default#VML);"); 
  // } 
  // if(document.documentMode && document.documentMode>=8) { 
  //     document.writeln('<?import namespace="v" implementation="#default#VML" ?>'); 
  // }

  $.fn.cornerz = function(options){
    
   function cssCorners(elem, corners, r) {
		
		var radius = r + 'px';
		
		$.each(corners.split(' '), function() {
			if(this == 'tl') 
			    elem.css({
					'-moz-border-radius-topleft'		: radius,
					'-webkit-border-top-left-radius'	: radius,
					'border-top-left-radius'			: radius
				});
		    else if(this == 'tr')
			    elem.css({
					'-moz-border-radius-topright'		: radius,
					'-webkit-border-top-right-radius'	: radius,
					'border-top-right-radius'			: radius
				});
		    else if(this == 'bl')
			    elem.css({
					'-moz-border-radius-bottomleft'		: radius,
					'-webkit-border-bottom-left-radius'	: radius,
					'border-bottom-left-radius'			: radius
				});
			else if(this == 'br')
			    elem.css({
					'-moz-border-radius-bottomright'	: radius,
					'-webkit-border-bottom-right-radius': radius,
					'border-bottom-right-radius'		: radius
				});
		});
	}

	function vmlCurve(r,b,c,m,ml,mt, right_fix) {
        var l = m-ml-right_fix;
        var t = m-mt;
        return "<v:arc filled='False' strokeweight='"+b+"px' strokecolor='"+c+"' startangle='0' endangle='361' style=' top:" + t +"px;left: "+ l + "px;width:" + r+ "px; height:" + r+ "px' />";
    };

    function vmlCurve2( r, b, c, m, ml, mt, right_fix ){
        var l = m - ml + (right_fix ? -1 : 0);
        var t = m - mt;

        var arc = $('<v:arc/>').attr({filled: 'False', strokeweight: b, strokecolor:c, startangle: 0, endangle: 361}).css({top: t, left: l, width: r, height: r});
        return arc;
    };

    function vmlCorners2( corners, r, border_width, border_color, bg_color, width){
      var h = $("<div></div>").css({'text-align': 'left'}).attr('id','vml');
      $.each($.trim(corners).split(" "), function(){
        var css     = {};
        var is_top  = !!(this == "tl" || this == "tr");
        var is_left = !!(this == "tl" || this == "bl");
        var mt      = (is_top ? 1 : r+1);
        var ml      = (is_left ? 1 : r);

        css[(is_top ? 'top' : 'bottom')]  = -1 - border_width;
        css[(is_left ? 'left' : 'right')] = -1 - border_width;
        
        var curve  = vmlCurve2( r*3 , r+border_width, bg_color, -r/2, ml, mt, !is_left );
        var group = $('<v:group></v:group>').css({width: 1000, height: 1000, position:'absolute'}).attr('coordsize','1000,1000');
        var mdiv = $('<div></div>').css( $.extend(css,{position: 'absolute', overflow: 'hidden', width: r, height: r}) ).append(
                        (border_width > 0 ? group.append(curve).append( vmlCurve2( r*2 - border_width, border_width, border_color, Math.floor(border_width/2 + 0.5), ml, mt, !is_left)) : group.append(curve) ));
                       //(bw > 0 ? group.append(curve).append( vmlCurve2( r*2-bw, bw, bc, Math.floor(bw/2 + 0.5), ml, mt, !is_left)) : group.append(curve) ));

        h = h.append( mdiv ); 
      });
      
      return h;
    };

    function vmlCorners(corners, r, bw, bc, bg, w) {

      var h ="<div style='text-align:left;' id='vml'>";
      $.each($.trim(corners).split(" "), function() {
        var css,ml=1,mt=1,right_fix=0;
        if(this.charAt(0)=="t") {
          css="top:-"+bw+"px;";
        }
        else {
          css= "bottom:-"+bw+"px;";
          mt=r+1;
        }
        if(this.charAt(1)=="l")
          css+="left:-"+bw+"px;";
        else {
          css +="right:-"+(bw)+"px; "; // odd width gives wrong margin?
           ml=r;
           right_fix = 1;
        }

        h+="<div style='"+css+"; position: absolute; overflow:hidden; width:"+ r +"px; height: " + r + "px;'>";
        h+= "<v:group  style='width:1000px;height:1000px;position:absolute;' coordsize='1000,1000' >";
        h+= vmlCurve(r*3,r+bw,bg, -r/2,ml,mt,right_fix); 
        if(bw>0)
          h+= vmlCurve(r*2-bw,bw,bc, Math.floor(bw/2+0.5),ml,mt,right_fix);
        h+="</v:group>";
        h+= "</div>"; 
      });
      h += "</div>";
      
      return h;
    };

    var settings = {
      corners : "tl tr bl br",
      radius : 10,
      background: "white",
      borderWidth: 0,
      fixIE: true };              
    $.extend(settings, options || {});
    
    var incrementProperty = function(elem, prop, x) {
      var y = parseInt(elem.css(prop), 10) || 0 ;
      elem.css(prop, x+y);
    };
    
    return this.each(function() {
	
	  var $$ = $(this);	
      var r = settings.radius*1.0;
      var bw = (settings.borderWidth || parseInt($$.css("borderTopWidth"), 10) || 0) * 1.0;
      //var bw = 0;
      var bg = settings.background;
      var bc = settings.borderColor;
      bc = bc || ( bw > 0 ? $$.css("borderTopColor") : bg);

      var cs = settings.corners;  

	  //$$.css({ overflow : ' visible'});

	  // Remove old-corners (if exists)
	  $('.cornerz', $$).remove();
	
      if($.browser.msie) { 
        try {
            h = vmlCorners( cs, r, bw, bc, bg, $(this).width() );
            this.insertAdjacentHTML('beforeEnd', h);
        } catch(e){ 
            h = vmlCorners2( cs, r, bw, bc, bg, $(this).width() );     
            $$.append(h);

            // Hack for IE8. VML can't be created on the DOM, so
            // we will be forcing
            $('#vml',$$).get(0).innerHTML = $('#vml',$$).get(0).innerHTML;
        }
      } else { 
		cssCorners($$, cs, r);
	 }
				                  
      if(this.style.position != "absolute")
        this.style.position = "relative";
     
       this.style.zoom = 1; // give it a layout in IE
      
       if($.browser.msie && settings.fixIE) {
          var ow = $$.outerWidth();
          var oh = $$.outerHeight();
          
          if(ow%2 == 1) {
            incrementProperty($$, "padding-right", 1);
            incrementProperty($$, "margin-right", 1);
          }

          if(oh%2 == 1) { 
            incrementProperty($$, "padding-bottom", 1);
            incrementProperty($$, "margin-bottom", 1);
          }
        }
          
      }
      
    );
 
  };
})(jQuery);

