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

/**
 * Class takes two argument: element selector and round type. ex: new
 * MooCorner('mySelector', "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). From:
 * 
 * @author Dave Methvin (http://methvin.com/jquery/jq-corner.html)
 * @author Mike Alsup (http://jquery.malsup.com/corner/)
 * 
 * Moo-porting:
 * @author Christian Strappazzon (http://lab.openmindonline.it/)
 */
var MooCorner = new Class(
		{

			Implements : [ Options, Events ],

			options : {
				moz : Browser.Engine.gecko,
				webkit : Browser.Engine.webkit,
				expr : Browser.Engine.trident && (function() {
					var div = document.createElement('div');
					try {
						div.style.setExpression('width', '0+0');
					} catch (e) {
						return false;
					}
					return true;
				})(),
				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
			},

			initialize : function(elem, options) {

				this.setOptions(options);

				$$(elem).each(function(el) {
					this.corner(el, options);
				}, this);
			},

			sz : function(el, p) {
				return parseInt($.css(el, p)) || 0;
			},

			hex2 : function(s) {
				var s = parseInt(s).toString(16);
				return (s.length < 2) ? '0' + s : s;
			},

			gpc : function(node) {
				for (; node && node.nodeName.toLowerCase() != 'html'; node = node.parentNode) {
					var v = $$(node).getStyle('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';
			},

			getWidth : function(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;
				}
			},

			corner : function(elem, options) {
				var mooEl = $$(elem)[0];
				var o = (options || this.options.metaAttr || '').toLowerCase();
				var keep = /keep/.test(o);
				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|left/.test(o),
				TR : /top|tr|right/.test(o),
				BL : /bottom|bl|left/.test(o),
				BR : /bottom|br|right/.test(o)
			};
			if (!opts.TL && !opts.TR && !opts.BL && !opts.BR)
				opts = {
					TL : 1,
					TR : 1,
					BL : 1,
					BR : 1
				};

			if (this.options.useNative && fx == 'round'
					&& (this.options.moz || this.options.webkit) && !cc && !sc) {
				if (opts.TL)
					mooEl.setStyle(
							this.options.moz ? '-moz-border-radius-topleft'
									: '-webkit-border-top-left-radius',
							width + 'px');
				if (opts.TR)
					mooEl.setStyle(
							this.options.moz ? '-moz-border-radius-topright'
									: '-webkit-border-top-right-radius',
							width + 'px');
				if (opts.BL)
					mooEl.setStyle(
							this.options.moz ? '-moz-border-radius-bottomleft'
									: '-webkit-border-bottom-left-radius',
							width + 'px');
				if (opts.BR)
					mooEl.setStyle(
							this.options.moz ? '-moz-border-radius-bottomright'
									: '-webkit-border-bottom-right-radius',
							width + 'px');
				return;
			}

			var strip = document.createElement('div');
			strip.style.overflow = 'hidden';
			strip.style.height = '1px';
			strip.style.backgroundColor = sc || 'transparent';
			strip.style.borderStyle = 'solid';

			var pad = {
				T : parseInt(mooEl.getStyle('padding-top')) || 0,
				R : parseInt(mooEl.getStyle('padding-right')) || 0,
				B : parseInt(mooEl.getStyle('padding-bottom')) || 0,
				L : parseInt(mooEl.getStyle('padding-left')) || 0
			};

			if (typeof mooEl.getStyle('zoom') != undefined)
				mooEl.setStyle('zoom', 1); // force 'hasLayout' in IE
			if (!keep)
				mooEl.setStyle('border', 'none');
			strip.style.borderColor = cc || this.gpc(mooEl.parentNode);
			var cssHeight = mooEl.getStyle('height');

			for ( var j in edges) {
				var bot = edges[j];

				// only add stips if needed
				if ((bot && (opts.BL || opts.BR))
						|| (!bot && (opts.TL || opts.TR))) {

					strip.style.borderStyle = 'none '
							+ (opts[j + 'R'] ? 'solid' : 'none') + ' none '
							+ (opts[j + 'L'] ? 'solid' : 'none');
					var d = new Element('div').addClass('jquery-corner');

					bot ? mooEl.grab(d) : mooEl.grab(d, 'top');

					if (bot && cssHeight != 'auto') {

						if (mooEl.getStyle('position') == 'static')
							mooEl.setStyle('position', 'relative');
						d.setStyle('position', 'absolute');
						d.setStyles( {
							'bottom' : 0,
							'left' : 0,
							'padding' : 0,
							'margin' : 0
						});
						if (this.options.expr)
							d.setStyle('width', mooEl.getParent().getStyle(
									'width'));
						else
							d.setStyle('width', '100%');
					} else if (!bot && Browser.Engine.trident) {
						if (mooEl.getStyle('position') == 'static')
							mooEl.setStyle('position', 'relative');
						d.setStyle('position', 'absolute');
						d.setStyles( {
							'top' : 0,
							'left' : 0,
							'right' : 0,
							'padding' : 0,
							'margin' : 0
						});

						// fix ie6 problem when blocked element has a border
						// width
						if (this.options.expr) {
							var bw = sz(mooEl, 'borderLeftWidth')
									+ sz(mooEl, 'borderRightWidth');
							d.setStyle('witdh', parseInt(mooEl.getParent()
									.getWidth())
									+ bw + 'px');
						} else
							d.setStyle('width', '100%');
					} else {
						d.setStyle('position', 'relative');
						d.setStyle('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, this.getWidth(fx, i, width));
						var e = strip.cloneNode(false);
						e.style.borderWidth = '0 ' + (opts[j + 'R'] ? w : 0)
								+ 'px 0 ' + (opts[j + 'L'] ? w : 0) + 'px';
						bot ? d.grab(e) : d.grab(e, 'top');
					}
				}
			}

		}

		});

/**
 * TODO
 * 
 * Bug: objects[i] is undefined for (var i = 0, l = objects.length; i <... i++)
 * objects[i].implement(properties);\n mootools...ore-nc.js (line 82)
 * 
 */
//Native.implement( [ Element, Document ], {
//	corner : function(style) {
//		new MooCorner(this, style);
//		return this;
//	}
//});
//
//Native.implement(Elements, {
//	corner : function(style) {
//		this.each(function(el) {
//			el.corner(style);
//		});
//		return this;
//	}
//});

