/*!
 * jQuery corner plugin: simple corner rounding
 * Examples and documentation at: http://jquery.malsup.com/corner/
 * version 2.02 (12-NOV-2009)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */

/**
 * corner() takes a single string argument: $('#myDiv').corner("effect corners
 * width")
 * 
 * effect: name of the effect to apply, such as round, bevel, notch, bite, etc
 * (default is round). corners: one or more of: top, bottom, tr, tl, br, or bl.
 * by default, all four corners are adorned. width: width of the effect; in the
 * case of rounded corners this is the radius. specify this value using the px
 * suffix such as 10px (and yes, it must be pixels).
 * 
 * @author Dave Methvin (http://methvin.com/jquery/jq-corner.html)
 * @author Mike Alsup (http://jquery.malsup.com/corner/)
 */
;
( function( $ ) {

	var ua = navigator.userAgent;
	var moz = $.browser.mozilla && /gecko/i.test( ua );
	var moz4 = $.browser.mozilla && $.browser.version === "2.0";
	var webkit = $.browser.safari && /Safari\/[5-9]/.test( ua );

	var expr = $.browser.msie && ( function( ) {
		var div = document.createElement( 'div' );
		try {
			div.style.setExpression( 'width', '0+0' );
		}
		catch ( e ) {
			return false;
		}
		return true;
	} )( );

	function sz( el, p ) {
		return parseInt( $.css( el, p ) ) || 0;
	}
	;
	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 = $.css( node, 'backgroundColor' );
			if ( v == 'rgba(0, 0, 0, 0)' )
				continue; // webkit
			if ( v.indexOf( 'rgb' ) >= 0 ) {
				var rgb = v.match( /\d+/g );
				return '#' + hex2( rgb[ 0 ] ) + hex2( rgb[ 1 ] ) + hex2( rgb[ 2 ] );
			}
			if ( v && v != 'transparent' )
				return v;
		}
		return '#ffffff';
	}
	;

	function getWidth( fx, i, width ) {
		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;
		}
	}
	;

	$.fn.corner = function( options ) {
		// in 1.3+ we can fix mistakes with the ready state
		if ( this.length == 0 ) {
			if ( !$.isReady && this.selector ) {
				var s = this.selector, c = this.context;
				$( function( ) {
					$( s, c ).corner( options );
				} );
			}
			return this;
		}

		return this
				.each( function( index ) {
					var myoptions = $.extend( {}, $.fn.corner.defaults, options );
					var $this = $( this );

					// keep borders?
					var keep = myoptions.keepBorders;
					// strip color
					var sc = myoptions.sc;
					// corner width
					var width = parseInt( myoptions.width ); // corner width
					// fx
					var fx = myoptions.fx;
					var edges = {
						T : 0,
						B : 1
					};

					// which edges to corner
					var opts = {
						TL : myoptions.tl.corner,
						TR : myoptions.tr.corner,
						BL : myoptions.bl.corner,
						BR : myoptions.br.corner
					};
					if ( !opts.TL && !opts.TR && !opts.BL && !opts.BR )
						opts = {
							TL : 1,
							TR : 1,
							BL : 1,
							BR : 1
						};

					// support native rounding
					if ( myoptions.useNative && fx == 'round' && ( moz || webkit ) && !sc ) {
						if ( opts.TL )
							if ( moz4 ) {
								$this.css( 'border-top-left-radius', width + 'px' );
							} else {
								$this.css( moz ? '-moz-border-radius-topleft' : '-webkit-border-top-left-radius', width
										+ 'px' );
							}
						if ( opts.TR )
							if ( moz4 ) {
								$this.css( 'border-top-right-radius', width + 'px' );
							} else {
								$this.css( moz ? '-moz-border-radius-topright' : '-webkit-border-top-right-radius',
										width + 'px' );
							}
						if ( opts.BL )
							if ( moz4 ) {
								$this.css( 'border-bottom-left-radius', width + 'px' );
							} else {
								$this.css( moz ? '-moz-border-radius-bottomleft' : '-webkit-border-bottom-left-radius',
										width + 'px' );
							}
						if ( opts.BR )
							if ( moz4 ) {
								$this.css( 'border-bottom-right-radius', width + 'px' );
							} else {
								$this.css( moz ? '-moz-border-radius-bottomright'
										: '-webkit-border-bottom-right-radius', width + 'px' );
							}
						return;
					}

					// top left strip template
					var stripTL = document.createElement( 'div' );
					stripTL.style.height = '1px';
					stripTL.style.float = 'left';
					stripTL.style.backgroundColor = sc || 'transparent';
					stripTL.style.borderStyle = 'solid';
					stripTL.style.marginTop = '-1px';
					if ( myoptions.tl.color != null ) {
						stripTL.style.borderColor = myoptions.tl.color;
					} else {
						var elem = document.elementFromPoint( $this.offset( ).left, $this.offset( ).top - 1 );
						stripTL.style.borderColor = gpc( elem );
					}

					// top right strip template
					var stripTR = document.createElement( 'div' );
					stripTR.style.height = '1px';
					stripTR.style.float = 'left';
					stripTR.style.backgroundColor = sc || 'transparent';
					stripTR.style.borderStyle = 'solid';
					stripTR.style.marginLeft = stripTL.style.width;
					if ( myoptions.tr.color != null ) {
						stripTR.style.borderColor = myoptions.tr.color;
					} else {
						var elem = document.elementFromPoint( ( $this.offset( ).left + $this.width( ) + 1 ), ( $this
								.offset( ).top - 1 ) );
						stripTR.style.borderColor = gpc( elem );
					}

					// bottom left strip template
					var stripBL = document.createElement( 'div' );
					stripBL.style.height = '1px';
					stripBL.style.float = 'left';
					stripBL.style.backgroundColor = sc || 'transparent';
					stripBL.style.borderStyle = 'solid';
					stripBL.style.marginTop = '-1px';
					if ( myoptions.bl.color != null ) {
						stripBL.style.borderColor = myoptions.bl.color;
					} else {
						var elem = document.elementFromPoint( ( $this.offset( ).left ), ( $this.offset( ).top
								+ $this.height( ) + 1 ) );
						stripBL.style.borderColor = gpc( elem );
					}

					// bottom right strip template
					var stripBR = document.createElement( 'div' );
					stripBR.style.height = '1px';
					stripBR.style.float = 'left';
					stripBR.style.backgroundColor = sc || 'transparent';
					stripBR.style.borderStyle = 'solid';
					stripBR.style.marginLeft = stripBL.style.width;
					if ( myoptions.br.color != null ) {
						stripBR.style.borderColor = myoptions.br.color;
					} else {
						var elem = document.elementFromPoint( ( $this.offset( ).left + $this.width( ) + 1 ), ( $this
								.offset( ).top
								+ $this.height( ) + 1 ) );
						stripBR.style.borderColor = gpc( elem );
					}

					var pad = {
						T : parseInt( $.css( this, 'paddingTop' ) ) || 0,
						R : parseInt( $.css( this, 'paddingRight' ) ) || 0,
						B : parseInt( $.css( this, 'paddingBottom' ) ) || 0,
						L : parseInt( $.css( this, 'paddingLeft' ) ) || 0
					};

					if ( typeof this.style.zoom != undefined )
						this.style.zoom = 1; // force 'hasLayout' in IE
					if ( !keep )
						this.style.border = 'none';
					var cssHeight = $.curCSS( this, 'height' );

					for ( var j in edges ) {
						var bot = edges[ j ];
						// only add strips if needed
						if ( ( bot && ( opts.BL || opts.BR ) ) || ( !bot && ( opts.TL || opts.TR ) ) ) {
							stripTL.style.borderStyle = 'none ' + ( opts[ j + 'R' ] ? 'solid' : 'none' ) + ' none '
									+ ( opts[ j + 'L' ] ? 'solid' : 'none' );
							stripTR.style.borderStyle = 'none ' + ( opts[ j + 'R' ] ? 'solid' : 'none' ) + ' none '
									+ ( opts[ j + 'L' ] ? 'solid' : 'none' );
							stripBL.style.borderStyle = 'none ' + ( opts[ j + 'R' ] ? 'solid' : 'none' ) + ' none '
									+ ( opts[ j + 'L' ] ? 'solid' : 'none' );
							stripBR.style.borderStyle = 'none ' + ( opts[ j + 'R' ] ? 'solid' : 'none' ) + ' none '
									+ ( opts[ j + 'L' ] ? 'solid' : 'none' );

							var d = document.createElement( 'div' );
							$( d ).addClass( 'jquery-corner' );
							var ds = d.style;

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

							if ( bot && cssHeight != 'auto' ) {
								if ( $.css( this, 'position' ) == 'static' )
									this.style.position = 'relative';
								ds.position = 'absolute';
								ds.bottom = ds.left = ds.padding = ds.margin = '0';
								if ( expr )
									ds.setExpression( 'width', 'this.parentNode.offsetWidth' );
								else
									ds.width = '100%';
							} else if ( !bot && $.browser.msie ) {
								if ( $.css( this, 'position' ) == 'static' )
									this.style.position = 'relative';
								ds.position = 'absolute';
								ds.top = ds.left = ds.right = ds.padding = ds.margin = '0';

								// fix ie6 problem when blocked element has a
								// border
								// width
								if ( expr ) {
									var bw = sz( this, 'borderLeftWidth' ) + sz( this, 'borderRightWidth' );
									ds.setExpression( 'width', 'this.parentNode.offsetWidth - ' + bw + '+ "px"' );
								} else
									ds.width = '100%';
							} else {
								ds.position = 'relative';
								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, getWidth( fx, i, width ) );

								// top left side
								var e = stripTL.cloneNode( false );
								e.style.borderWidth = '0 0px 0 ' + ( opts[ j + 'L' ] ? w : 0 ) + 'px';

								// top right side
								var e2 = stripTR.cloneNode( false );
								e2.style.borderWidth = '0 ' + ( opts[ j + 'R' ] ? w : 0 ) + 'px 0 0px';

								// bottom left side
								var e3 = stripBL.cloneNode( false );
								e3.style.borderWidth = '0 0px 0 ' + ( opts[ j + 'L' ] ? w : 0 ) + 'px';

								// bottom right side
								var e4 = stripBR.cloneNode( false );
								e4.style.borderWidth = '0 ' + ( opts[ j + 'R' ] ? w : 0 ) + 'px 0 0px';

								// parent
								var eparent = document.createElement( 'div' );
								eparent.style.height = '1px';

								// only add strips if needed
								if ( !bot ) {
									eparent.appendChild( e2 );
									eparent.appendChild( e );
								}
								if ( bot ) {
									eparent.appendChild( e4 );
									eparent.appendChild( e3 );
								}

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

	$.fn.uncorner = function( ) {
		if ( moz || webkit )
			this.css( moz ? '-moz-border-radius' : '-webkit-border-radius', 0 );
		$( 'div.jquery-corner', this ).remove( );
		return this;
	};

	// expose options
	$.fn.corner.defaults = {
		useNative : true, // true if plugin should attempt to use native
		// browser support for border radius rounding
		metaAttr : 'data-corner', // name of meta attribute to use for options
		tl : {
			corner : true,
			color : null
		},
		tr : {
			corner : true,
			color : null
		},
		bl : {
			corner : true,
			color : null
		},
		br : {
			corner : true,
			color : null
		},
		width : '10px',
		keepBorders : false,
		fx : 'round',
		sc : null
	};

} )( jQuery );

