/*
 * jQuery corner plugin
 *
 * version 1.7 (1/26/2007)
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

/**
 * The corner() method provides a simple way of styling DOM elements.
 *
 * corner() takes a single string argument:  $().corner("effect corners width")
 *
 *   effect:  The name of the effect to apply, such as round or bevel.
 *            If you don't specify an effect, rounding is used.
 *           
 *   corners: The corners can be one or more of top, bottom, tr, tl, br, or bl.
 *            By default, all four corners are adorned.
 *
 *   width:   The width specifies the width of the effect; in the case of rounded corners this
 *            will be the radius of the width.
 *            Specify this value using the px suffix such as 10px, and yes it must be pixels.
 *
 * For more details see: http://methvin.com/jquery/jq-corner.html
 * For a full demo see:  http://malsup.com/jquery/corner/
 *
 * @example $('.adorn').corner();
 *  Create round, 10px corners
 *
 * $('.adorn').corner("25px");
 *  Create round, 25px corners
 *
 *  $('.adorn').corner("notch bottom");
 *  Create notched, 10px corners on bottom only
 *
 * $('.adorn').corner("tr dog 25px");
 *  Create dogeared, 25px corner on the top-right corner only
 *
 *  $('.adorn').corner("round 8px").parent().css('padding', '4px').corner("round 10px");
 *  Create a rounded border effect by styling both the element and its parent
 *
 * @name corner
 * @type jQuery
 * @param String options Options which control the corner style
 * @cat Plugins/Corner
 * @return jQuery
 * @author Dave Methvin ("dave.methvin@gmail.com")
 * @author Mike Alsup ("malsup@gmail.com")
 *<p><br /><b><h3>Tips and Tricks</h3></b>
 *
 *As you apply these corner styles to your own pages, here are some tips (pitfalls?) to keep in mind:
 *
 * <br /><b>Use pixel units for borders and padding in your styles</b>. The code needs to position elements at the top and bottom of the adorned element, and to do this it wants to see pixel measurements. Measurements other than padding and borders can be in any units you want.
 * <br /><b>Remember, it's inserting new elements.</b> If you have css rules or jQuery selectors that depend on, for example, finding the first element in a div that you are rounding, they could be affected by the newly inserted elements. Use a DOM inspector if you think this is happening and adjust your selectors accordingly.
 * <br /><b>Define an explicit background color in a parent element.</b> Safari requires that an ancestor of the element being adorned has a background color set. Just set the body to "background: #fff" if you don't need some other color.
 * <br /><b>Don't use a background image in the parent.</b> The adorned element effect sets pixels on the corners to the same color as the parent element. Those pixels are not transparent and will not show any background image that is used in the parent element.
 * <br /><b>Make the corner height smaller than the top/bottom padding.</b> If the height of the corner effect is larger than the padding, the div's height will increase. You can either accept that or adjust the height/padding appropriately.
 * <br /><b>Minimize height and number of adorned divs for best performance.</b> Each pixel of additional height requires an element to be dynamically created and inserted into the document, plus two more to wrap the top and bottom groups. So, an effect that is 8 pixels high on both the top and the bottom inserts 18 elements into the document for each element on the page that is adorned.
 * <br /><b>The "sharp" corner style is very sharp!</b> Come to think of it, so are the "sculpt" and "cool" styles. Like all sharp pointy things, keep them out of reach of children. If you use are viewing a web page on a mobile device that uses those styles, do not run. You may fall and put your eye out. I will not be responsible for injuries due to the sharpness of your corners.
 * <br /><b>List of keys</b><br />
 * <b >cc:</b> Conner color<br />
 * <b >sc:</b> Strip conner color<br />
 * <b >Keep:</b> Keep borders<br />
 * <b >Width:</b> Conner width or radius<br /><br />
 * <b>List of suported Conner Styles</b>
 *  <ul>
 *    <li>round</li>
 *    <li>bevel</li>
 *    <li>notch</li>
 *    <li>bite</li>
 *    <li>cool</li>
 *    <li>sharp</li>
 *    <li>slide</li>
 *    <li>jut</li>
 *    <li>curl</li>
 *    <li>tear</li>
 *    <li>fray</li>
 *    <li>wicked</li>
 *    <li>sculpt</li>
 *    <li>long</li>
 *    <li>dog</li>
 *    <li>dog2</li>
 *    <li>dog3</li>
 *    <li>dogfold</li>
 *    <li>bevelfold</li>
 *  </ul>
 *
 *<p />
 */
jQuery.fn.corner = function(o) {
    function hex2(s) {
        var s = parseInt(s).toString(16);
        return ( s.length < 2 ) ? '0'+s : s;
    };
    function gpc(node) {
        for ( ; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode  ) {
            var v = jQuery.css(node,'backgroundColor');
            if ( v.indexOf('rgb') >= 0 ) {
                rgb = v.match(/\d+/g);
                return '#'+ hex2(rgb[0]) + hex2(rgb[1]) + hex2(rgb[2]);
            }
            if ( v && v != 'transparent' )
                return v;
        }
        return '#ffffff';
    };
    function getW(i) {
        switch(fx) {
        case 'round':  return Math.round(width*(1-Math.cos(Math.asin(i/width))));
        case 'cool':   return Math.round(width*(1+Math.cos(Math.asin(i/width))));
        case 'sharp':  return Math.round(width*(1-Math.cos(Math.acos(i/width))));
        case 'bite':   return Math.round(width*(Math.cos(Math.asin((width-i-1)/width))));
        case 'slide':  return Math.round(width*(Math.atan2(i,width/i)));
        case 'jut':    return Math.round(width*(Math.atan2(width,(width-i-1))));
        case 'curl':   return Math.round(width*(Math.atan(i)));
        case 'tear':   return Math.round(width*(Math.cos(i)));
        case 'wicked': return Math.round(width*(Math.tan(i)));
        case 'long':   return Math.round(width*(Math.sqrt(i)));
        case 'sculpt': return Math.round(width*(Math.log((width-i-1),width)));
        case 'dog':    return (i&1) ? (i+1) : width;
        case 'dog2':   return (i&2) ? (i+1) : width;
        case 'dog3':   return (i&3) ? (i+1) : width;
        case 'fray':   return (i%2)*width;
        case 'notch':  return width;
        case 'bevel':  return i+1;
        }
    };
    o = (o||"").toLowerCase();
    var keep = /keep/.test(o);                       // keep borders?
    var cc = ((o.match(/cc:(#[0-9a-f]+)/)||[])[1]);  // corner color
    var sc = ((o.match(/sc:(#[0-9a-f]+)/)||[])[1]);  // strip color
    var width = parseInt((o.match(/(\d+)px/)||[])[1]) || 10; // corner width
    var re = /round|bevel|notch|bite|cool|sharp|slide|jut|curl|tear|fray|wicked|sculpt|long|dog3|dog2|dog/;
    var fx = ((o.match(re)||['round'])[0]);
    var edges = { T:0, B:1 };
    var opts = {
        TL:  /top|tl/.test(o),       TR:  /top|tr/.test(o),
        BL:  /bottom|bl/.test(o),    BR:  /bottom|br/.test(o)
    };
    if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
        opts = { TL:1, TR:1, BL:1, BR:1 };
    var strip = document.createElement('div');
    strip.style.overflow = 'hidden';
    strip.style.height = '1px';
    strip.style.backgroundColor = sc || 'transparent';
    strip.style.borderStyle = 'solid';
    return this.each(function(index){
        var pad = {
            T: parseInt(jQuery.css(this,'paddingTop'))||0,     R: parseInt(jQuery.css(this,'paddingRight'))||0,
            B: parseInt(jQuery.css(this,'paddingBottom'))||0,  L: parseInt(jQuery.css(this,'paddingLeft'))||0
        };

        if (jQuery.browser.msie) this.style.zoom = 1; // force 'hasLayout' in IE
        if (!keep) this.style.border = 'none';
        strip.style.borderColor = cc || gpc(this.parentNode);
        var cssHeight = jQuery.curCSS(this, 'height');

        for (var j in edges) {
            var bot = edges[j];
            strip.style.borderStyle = 'none '+(opts[j+'R']?'solid':'none')+' none '+(opts[j+'L']?'solid':'none');
            var d = document.createElement('div');
            var ds = d.style;

            bot ? this.appendChild(d) : this.insertBefore(d, this.firstChild);

            if (bot && cssHeight != 'auto') {
                if (jQuery.css(this,'position') == 'static')
                    this.style.position = 'relative';
                ds.position = 'absolute';
                ds.bottom = ds.left = ds.padding = ds.margin = '0';
                if (jQuery.browser.msie)
                    ds.setExpression('width', 'this.parentNode.offsetWidth');
                else
                    ds.width = '100%';
            }
            else {
                ds.margin = !bot ? '-'+pad.T+'px -'+pad.R+'px '+(pad.T-width)+'px -'+pad.L+'px' :
                                    (pad.B-width)+'px -'+pad.R+'px -'+pad.B+'px -'+pad.L+'px';
            }

            for (var i=0; i < width; i++) {
                var w = Math.max(0,getW(i));
                var e = strip.cloneNode(false);
                e.style.borderWidth = '0 '+(opts[j+'R']?w:0)+'px 0 '+(opts[j+'L']?w:0)+'px';
                bot ? d.appendChild(e) : d.insertBefore(e, d.firstChild);
            }
        }
    });
};




