/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.lfx.rounded");

dojo.require("dojo.lang.common");
dojo.require("dojo.html.common");
dojo.require("dojo.html.style");
dojo.require("dojo.html.display");
dojo.require("dojo.html.layout");

/*	Port of curvyCorners, by Cameron Cooke and Tim Hutchison.
 *	Original port done by Brian Lucas.
 *	Refactor and function by trt.
 */
dojo.lfx.rounded = function(/* object */settings /* ... */){
	//	summary
	//	Creates a set of rounded corners based on settings.
	var options={
		validTags:settings.validTags || ["div"],					//	tags we can apply this to
		autoPad:settings.autoPad!=null ? settings.autoPad : true,		//	automatically pad
		antiAlias:settings.antiAlias!=null ? settings.antiAlias : true,	//	anti-alias corners
		radii:{ 	//	corner radii
			tl:(settings.tl && settings.tl.radius!=null) ? settings.tl.radius:5,
			tr:(settings.tr && settings.tr.radius!=null) ? settings.tr.radius:5,
			bl:(settings.bl && settings.bl.radius!=null) ? settings.bl.radius:5,
			br:(settings.br && settings.br.radius!=null) ? settings.br.radius:5
		}
	};

	//	get the node list to operate on.
	var nodes;
	if(typeof(arguments[1]) == "string"){
		//	a CSS classname was passed, grab a node list.
		nodes=dojo.html.getElementsByClass(arguments[1]);
	} else if(dojo.lang.isArrayLike(arguments[1])){
		//	we assume that the second argument is an array of nodes to apply this to.
		nodes=arguments[1];
		for(var i=0; i<nodes.length; i++){ nodes[i]=dojo.byId(nodes[i]); }
	}
	if(nodes.length == 0) return;	//	don't bother.

	////////////////////////////////////////////////////////////////////
	for(var i=0; i<nodes.length; i++){
		dojo.lfx.rounded.applyCorners(options, nodes[i]);
	}
};

//	can call this directly if one wants.
dojo.lfx.rounded.applyCorners = function(/* object */options, /* HTMLElement */node){
	//	summary
	//	Rounds corners based on options to passed node.
	var top = null;
	var bottom = null;
	var contentNode = null;
	var fns=dojo.lfx.rounded._fns;

	//	node details
	var width = node.offsetWidth;
	var height = node.offsetHeight;
	var borderWidth = parseInt(dojo.html.getComputedStyle(node, "border-top-width"));
	var borderColor = dojo.html.getComputedStyle(node, "border-top-color");
	var color = dojo.html.getComputedStyle(node, "background-color");
	var bgImage = dojo.html.getComputedStyle(node, "background-image");
	var position = dojo.html.getComputedStyle(node, "position");
	var padding = parseInt(dojo.html.getComputedStyle(node, "padding-top"));

	//	formatting details
	//	TODO: use Dojo equivilents for these if exists.
	var format={
		height : height,
		width : width,
		borderWidth : borderWidth,
		color : fns.getRGB(color),
		padding : padding,
		borderColor : fns.getRGB(borderColor),
		borderString : borderWidth + "px" + " solid " + fns.getRGB(borderColor),
		bgImage : ((bgImage != "none")? bgImage : ""),
		content : node.innerHTML
	};

	if(!dojo.html.isPositionAbsolute(node)){ node.style.position="relative"; }
	node.style.padding="0px";
	if(dojo.render.html.ie && width=="auto" && height=="auto"){ node.style.width="100%"; }
	if(options.autoPad && format.padding>0){
		node.innerHTML="";
	}

	var topHeight=Math.max(options.radii.tl, options.radii.tr);
	var bottomHeight=Math.max(options.radii.bl, options.radii.br);

	//	build the containers.
	if(options.radii.tl || options.radii.tr){
		top = document.createElement("div");
		top.style.width="100%";
		top.style.fontSize="1px";
		top.style.overflow="hidden";
		top.style.position="absolute";
		top.style.paddingLeft=format.borderWidth+"px";
		top.style.paddingRight=format.borderWidth+"px";
		top.style.height=topHeight+"px";
		top.style.top=(0-topHeight)+"px";
		top.style.left=(0-format.borderWidth)+"px";
		node.appendChild(top);
	}
	if(options.radii.bl || options.radii.br){	//	bottom
		bottom = document.createElement("div");
		bottom.style.width="100%";
		bottom.style.fontSize="1px";
		bottom.style.overflow="hidden";
		bottom.style.position="absolute";
		bottom.style.paddingLeft=format.borderWidth+"px";
		bottom.style.paddingRight=format.borderWidth+"px";
		bottom.style.height=bottomHeight+"px";
		bottom.style.bottom=(0-bottomHeight)+"px";
		bottom.style.left=(0-format.borderWidth)+"px";
		node.appendChild(bottom);
	}

	//	turn off the borders
	if(top){ node.style.borderTopWidth = "0px"; }
	if(bottom){ node.style.borderBottomWidth = "0px"; }

	//	do the corners
	var corners = ["tr", "tl", "br", "bl"];
	for(var i=0; i<corners.length; i++){
		var cc=corners[i];
		if(options.radii[cc]==0){
			//	fill up the space with a div.
			if((cc.charAt(0)=="t"&&top) || (cc.charAt(0)=="b"&&bottom)){
				var corner=document.createElement("div");
				corner.style.position="relative";
				corner.style.fontSize="1px;";
				corner.style.overflow="hidden";
				if(format.bgImage==""){
					corner.style.backgroundColor=format.color;
				} else {
					corner.style.backgroundImage=format.bgImage;
				}
				switch(cc){
					case "tl":{
						corner.style.height=topHeight-format.borderWidth+"px";
						corner.style.marginRight=options.radii[cc]-(format.borderWidth*2)+"px";
						corner.style.borderLeft=format.borderString;
						corner.style.borderTop=format.borderString;
						corner.style.left=-format.borderWidth+"px";
						break;
					}
					case "tr":{
						corner.style.height=topHeight-format.borderWidth+"px";
						corner.style.marginLeft=options.radii[cc]-(format.borderWidth*2)+"px";
						corner.style.borderRight=format.borderString;
						corner.style.borderTop=format.borderString;
						corner.style.backgroundPosition="-"+(topHeight-format.borderWidth)+"px 0px";
						corner.style.left=format.borderWidth+"px";
						break;
					}
					case "bl":{
						corner.style.height=bottomHeight-format.borderWidth+"px";
						corner.style.marginRight=options.radii[cc]-(format.borderWidth*2)+"px";
						corner.style.borderLeft=format.borderString;
						corner.style.borderBottom=format.borderString;
						corner.style.left=format.borderWidth+"px";
						corner.style.backgroundPosition="-"+format.borderWidth+"px -"+(format.height+(bottomHeight+format.borderWidth))+"px";
						break;
					}
					case "br":{
						corner.style.height=bottomHeight-format.borderWidth+"px";
						corner.style.marginLeft=options.radii[cc]-(format.borderWidth*2)+"px";
						corner.style.borderRight=format.borderString;
						corner.style.borderBottom=format.borderString;
						corner.style.left=format.borderWidth+"px";
						corner.style.backgroundPosition="-"+(bottomHeight+format.borderWidth)+"px -"+(format.height+(bottomHeight+format.borderWidth))+"px";
						break;
					}
				}
			}
		} else {
			//	NB: this version will not do the caching they built into the
			//		current version of curvyCorners.
			var corner=document.createElement("div");
			corner.style.height=options.radii[cc]+"px";
			corner.style.width=options.radii[cc]+"px";
			corner.style.position="absolute";
			corner.style.fontSize="1px";
			corner.style.overflow="hidden";

			var borderRadius=Math.floor(options.radii[cc] - format.borderWidth);
			for(var x=0, j=options.radii[cc]; x<j; x++){
				//	figure out y coords
				var y1=Math.floor(Math.sqrt(Math.pow(borderRadius,2)-Math.pow((x+1),2)))-1;
				if((x+1) >= borderRadius){ var y1=-1; }
				var y2=Math.ceil(Math.sqrt(Math.pow(borderRadius,2)-Math.pow(x,2)));
				if(x >= borderRadius){ y2=-1; }
				var y3=Math.floor(Math.sqrt(Math.pow(j,2)-Math.pow((x+1),2)))-1;
				if((x+1) >= j){ y3=-1; }
				var y4=Math.ceil(Math.sqrt(Math.pow(j, 2)-Math.pow(x, 2)));
				if(x >= j){ y4=-1; }

				//	start drawing
				if(y1 > -1){
					fns.draw(x, 0, format.color, 100, (y1+1), corner, -1, j, topHeight, format);
				}

				// cycle the y-axis
				for(var y=(y1+1); y<y2; y++){
					if(options.antiAlias){
						if(format.bgImage != ""){
							var fract=fns.fraction(x, y, borderRadius)*100;
							if(fract < 30){
								fns.draw(x, y, format.borderColor, 100, 1, corner, 0, options.radii[cc], topHeight, format);
							} else {
								fns.draw(x, y, format.borderColor, 100, 1, corner, -1, options.radii[cc], topHeight, format);
							}
						} else {
							var clr=fns.blend(format.color, format.borderColor, fns.fraction(x, y, borderRadius));
							fns.draw(x, y, clr, 100, 1, corner, 0, options.radii[cc], topHeight, format);
						}
					}
				}

				//	bar for the border
				if(options.antiAlias){
					if(y3 >= y2){
						if(y2 == -1){ y2 = 0; }
						fns.draw(x, y2, format.borderColor, 100, (y3-y2+1), corner, 0, 0, topHeight, format)
					} else {
						if(y3 >= y1){
							fns.draw(x, (y1+1), format.borderColor, 100, (y3-y1), corner, 0, 0, topHeight, format);
						}
					}
					for(var y=(y3+1); y<y4; y++){
						fns.draw(x, y, format.borderColor, (fns.fraction(x, y, j)*100), 1, corner, (format.borderWidth>0 ? 0:-1), options.radii[cc], topHeight, format);
					}
				} else {
					y3=y1;
				}
			}

			//	reposition pixels if not the bottom right.
			if(cc != "br"){
				for(var t=0, k=corner.childNodes.length; t<k; t++){
					var bar=corner.childNodes[t];
					var barTop = parseInt(dojo.html.getComputedStyle(bar, "top"));
					var barLeft = parseInt(dojo.html.getComputedStyle(bar, "left"));
					var barHeight = parseInt(dojo.html.getComputedStyle(bar, "height"));

					//	reposition.
					if(cc.charAt(1)=="l"){
						bar.style.left = (options.radii[cc]-barLeft-1)+"px";
					}
					if(cc=="tr"){
						bar.style.top = (options.radii[cc]-barHeight-barTop)+"px";
						bar.style.backgroundPosition="-"+Math.abs((format.width-options.radii[cc]+format.borderWidth)+barLeft)
							+"px -"+Math.abs(options.radii[cc]-barHeight-barTop-format.borderWidth)+"px";
					} else if (cc=="tl"){
						bar.style.top = (options.radii[cc]-barHeight-barTop)+"px";
						bar.style.backgroundPosition="-"+Math.abs((options.radii[cc]-barLeft-1)-format.borderWidth)
							+"px -"+Math.abs(options.radii[cc]-barHeight-barTop-format.borderWidth)+"px";
					} else {
						bar.style.backgroundPosition="-"+Math.abs((options.radii[cc]+barLeft)+format.borderWidth)
							+"px -"+Math.abs((format.height+options.radii[cc]+barTop)-format.borderWidth)+"px";
					}
				}
			}
		}

		if(corner){
			//	position the container.
			var psn=[];
			if(cc.charAt(0)=="t"){ psn.push("top"); }
			else { psn.push("bottom"); }
			if(cc.charAt(1)=="l"){ psn.push("left"); }
			else { psn.push("right"); }

			if(corner.style.position=="absolute"){
				for(var z=0; z<psn.length; z++){ corner.style[psn[z]]="0px"; }
			}

			if(psn[0]=="top"){
				if(top){ top.appendChild(corner); }
			} else {
				if(bottom){ bottom.appendChild(corner); }
			}
		}
	}

	//	draw fillers.
	var diff={
		t: Math.abs(options.radii.tl - options.radii.tr),
		b: Math.abs(options.radii.bl - options.radii.br)
	};
	for(var z in diff){
		var smaller=(options.radii[z+"l"]<options.radii[z+"r"] ? z+"l":z+"r");
		var filler=document.createElement("div");
		filler.style.height=diff[z]+"px";
		filler.style.width=options.radii[smaller]+"px";
		filler.style.position="absolute";
		filler.style.fontSize="1px";
		filler.style.overflow="hidden";
		filler.style.backgroundColor=format.color;
		switch(smaller){
			case "tl":{
				filler.style.bottom="0px";
				filler.style.left="0px";
				filler.style.borderLeft=format.borderString;
				top.appendChild(filler);
				break;
			}
			case "tr":{
				filler.style.bottom="0px";
				filler.style.right="0px";
				filler.style.borderRight=format.borderString;
				top.appendChild(filler);
				break;
			}
			case "bl":{
				filler.style.top="0px";
				filler.style.left="0px";
				filler.style.borderLeft=format.borderString;
				bottom.appendChild(filler);
				break;
			}
			case "br":{
				filler.style.top="0px";
				filler.style.right="0px";
				filler.style.borderRight=format.borderString;
				bottom.appendChild(filler);
				break;
			}
		}

		var fillBar=document.createElement("div");
		fillBar.style.position="relative";
		fillBar.style.fontSize="1px";
		fillBar.style.overflow="hidden";
		fillBar.style.backgroundColor=format.color;
		fillBar.style.backgroundImage=format.bgImage;
		if(z=="t"){
			if(top){
				if(options.radii.tl && options.radii.tr){
					fillBar.style.height=(topHeight-format.borderWidth) + "px";
					fillBar.style.marginLeft=(options.radii.tl-format.borderWidth)+"px";
					fillBar.style.marginRight=(options.radii.tr-format.borderWidth)+"px";
					fillBar.style.borderTop=format.borderString;
					if(format.bgImage!=""){
						fillBar.style.backgroundPosition="-"+(topHeight+format.borderWidth)+"px 0px";
					}
				}
				top.appendChild(fillBar);
			}
		} else {
			if(bottom){
				if(options.radii.bl && options.radii.br){
					fillBar.style.height=(bottomHeight-format.borderWidth) + "px";
					fillBar.style.marginLeft=(options.radii.bl-format.borderWidth)+"px";
					fillBar.style.marginRight=(options.radii.br-format.borderWidth)+"px";
					fillBar.style.borderBottom=format.borderString;
					if(format.bgImage!=""){
						fillBar.style.backgroundPosition="-"+(bottomHeight+format.borderWidth)+"px -"
							+ (format.height + (topHeight+format.borderWidth))+"px";
					}
				}
				bottom.appendChild(fillBar);
			}
		}
	}

	//	finally, set up the padding.
	if(options.autoPad && format.padding>0){
		var content=document.createElement("div");
		content.style.position="relative";
		content.innerHTML=format.content;
		content.className="autoPadDiv";
		if(topHeight < format.padding){
			content.style.paddingTop = Math.abs(topHeight-format.padding)+"px";
		}
		if(bottomHeight < format.padding){
			content.style.paddingBottom = Math.abs(bottomHeight-format.padding)+"px";
		}
		content.style.paddingLeft=format.padding+"px";
		content.style.paddingRight=format.padding+"px";
		node.appendChild(content);
	}
};

var count=0;

//	helper methods.
dojo.lfx.rounded._fns={
	blend:function(clr1, clr2, frac){
		var c1={
			r:parseInt(clr1.substr(1,2),16),
			g:parseInt(clr1.substr(3,2),16),
			b:parseInt(clr1.substr(5,2),16)
		};
		var c2={
			r:parseInt(clr2.substr(1,2),16),
			g:parseInt(clr2.substr(3,2),16),
			b:parseInt(clr2.substr(5,2),16)
		};
		if(frac>1||frac<0){ frac=1; }
		var ret=[
			Math.min(Math.max(Math.round((c1.r*frac)+(c2.r*(1-frac))),0),255),
			Math.min(Math.max(Math.round((c1.g*frac)+(c2.g*(1-frac))),0),255),
			Math.min(Math.max(Math.round((c1.b*frac)+(c2.b*(1-frac))),0),255)
		];
		for(var i=0; i<ret.length; i++){
			var n=ret[i].toString(16);
			if(n.length<2){ n="0"+n; }
			ret[i]=n;
		}
		return "#"+ret.join("");
	},
	fraction:function(x, y, r){
		var frac=0;
		var xval=[];
		var yval=[];
		var point=0;
		var whatsides="";

		var intersect=Math.sqrt((Math.pow(r,2)-Math.pow(x,2)));
		if(intersect >=y && intersect < (y+1)){
			whatsides="Left";
			xval[point]=0;
			yval[point++]=intersect-y;
		}

		intersect=Math.sqrt((Math.pow(r,2)-Math.pow(y+1,2)));
		if(intersect >=x && intersect < (x+1)){
			whatsides += "Top";
			xval[point]=intersect-x;
			yval[point++]=1;
		}

		intersect=Math.sqrt((Math.pow(r,2)-Math.pow(x+1,2)));
		if(intersect >= y && intersect < (y+1)){
			whatsides += "Right";
			xval[point]=1;
			yval[point++] = intersect-y;
		}

		intersect=Math.sqrt((Math.pow(r,2)-Math.pow(y,2)));
		if(intersect >=x && intersect < (x+1)){
			whatsides += "Bottom";
			xval[point]=intersect-x;
			yval[point]=1;
		}

		switch(whatsides){
			case "LeftRight":
				return Math.min(yval[0],yval[1]) + ((Math.max(yval[0],yval[1])-Math.min(yval[0],yval[1]))/2);
			case "TopRight":
				return 1-(((1-xval[0])*(1-yval[1]))/2);
			case "TopBottom":
				return Math.min(xval[0],xval[1]) + ((Math.max(xval[0],xval[1])-Math.min(xval[0],xval[1]))/2);
			case "LeftBottom":
				return (yval[0]*xval[1])/2;
			default: return 1;
		}
	},
	draw:function(x, y, color, opac, height, corner, image, radius, top, format){
		var px=document.createElement("div");
		px.style.height=height+"px"
		px.style.width="1px";
		px.style.position="absolute";
		px.style.fontSize="1px";
		px.style.overflow="hidden";
		if(image==-1 && format.bgImage!=""){
			px.style.backgroundImage=format.bgImage;
			px.style.backgroundPosition="-"+(format.width-(radius-x)+format.borderWidth)
				+"px -"+((format.height+top+y)-format.borderWidth)+"px";
		} else {
			px.style.backgroundColor=color;
		}
		if(opac!=100){ dojo.html.setOpacity(px, (opac/100)); }
		px.style.top=y+"px";
		px.style.left=x+"px";
		corner.appendChild(px);
	},
	getRGB:function(clr){
		var ret="#ffffff";
		if(clr!="" && clr!="transparent"){
			if(clr.substr(0,3)=="rgb"){
				var t=clr.substring(4, clr.indexOf(")"));
				t=t.split(",");
				for(var i=0; i<t.length; i++){
					var n=parseInt(t[i]).toString(16);
					if(n.length<2){ n = "0"+n; }
					t[i]=n;
				}
				ret = "#"+t.join("");
			}
			else if(clr.length==4){
				ret = "#"+clr.substring(1,2)+clr.substring(1,2)
					+ clr.substring(2,3)+clr.substring(2,3)
					+ clr.substring(3,4)+clr.substring(3,4);
			}
			else {
				ret = clr;
			}
		}
		return ret;
	}
};
