// Contributors 
// Ilkka Huotari at http://www.editsite.net
// Mathieu 'p01' HENRI at http://www.p01.org/
// http://seky.nahory.net/2005/04/rounded-corners/
// Steven Wittens at http://www.acko.net/anti-aliased-nifty-corners
// Original Nifty Corners by Alessandro Fulciniti at http://pro.html.it/esempio/nifty/
// Re-worked by Matt Casey : source23.com

Math.sqr = function (x) {
	return x*x;
};

function Blend(a, b, alpha) {

	var ca = Array(
		parseInt('0x' + a.substring(1, 3)), 
		parseInt('0x' + a.substring(3, 5)), 
		parseInt('0x' + a.substring(5, 7))
	);
	var cb = Array(
		parseInt('0x' + b.substring(1, 3)), 
		parseInt('0x' + b.substring(3, 5)), 
		parseInt('0x' + b.substring(5, 7))
	);
	return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)
						 + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)
						 + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);

	return '#' + ('0'+Math.round(ca[0] + (cb[0] - ca[0])*alpha).toString(16)).slice(-2).toString(16)
						 + ('0'+Math.round(ca[1] + (cb[1] - ca[1])*alpha).toString(16)).slice(-2).toString(16)
						 + ('0'+Math.round(ca[2] + (cb[2] - ca[2])*alpha).toString(16)).slice(-2).toString(16);
}

function AddRounded(el, bgColor, fgColor, sizex, sizey, topLeft, topRight, botRight, botLeft) {
	//dbg.h('AddRounded([' +el.id+ '] bgColor[' +bgColor+ '] fgColor[' +fgColor+ '] sizex[' +sizex+ '] sizey[' +sizey+ '] top[' +top+ '])');
	if (!sizex && !sizey) return;
	var i, j;
	//container for corners
	var oTop = document.createElement("div"); //top
	var oBot	= document.createElement("div"); //bot
	oTop.style.backgroundColor = bgColor;
	oBot.style.backgroundColor = bgColor;
	var lastarc = 0;

	for (i = 1; i <= sizey; i++) {
		var coverage, arc2, arc3;
		// Find intersection of arc with bottom of pixel row
		arc = Math.sqrt(1.0 - Math.sqr(1.0 - i / sizey)) * sizex;
		// Calculate how many pixels are bg, fg and blended.
		var n_bg 	= sizex - Math.ceil(arc);
		var n_fg 		= Math.floor(lastarc);
		var n_aa 	= sizex - n_bg - n_fg;
		// Create pixel row wrapper
		var oInnerTop 	= document.createElement("div");
		var oInnerBot 	= document.createElement("div");
		var oOuterTop 	= oTop; //create a fresh outer.
		var oOuterBot 	= oBot; //create a fresh outer.
		//top margins	
		oInnerTop.style.margin = "0px 0px 0px 0px"; //default
		if(topLeft) 		oInnerTop.style.marginLeft 		= n_bg + "px";
		if(topRight) 	oInnerTop.style.marginRight 	= n_bg + "px";
		//bottom margins
		oInnerBot.style.margin = "0px 0px 0px 0px"; //default
		if(botLeft) 		oInnerBot.style.marginLeft 		= n_bg + "px";
		if(botRight) 	oInnerBot.style.marginRight 		= n_bg + "px";
	
		oInnerTop.style.height			='1px';
		oInnerTop.style.overflow		='hidden';
		oInnerBot.style.height			='1px';
		oInnerBot.style.overflow		='hidden';

		// Make a wrapper per anti-aliased pixel (at least one)
		for (j = 1; j <= n_aa; j++) {
			// Calculate coverage per pixel
			// (approximates circle by a line within the pixel)
			if (j == 1) {
				if (j == n_aa) {
					// Single pixel
					coverage = ((arc + lastarc) * .5) - n_fg;
				}
				else {
					// First in a run
					arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
					coverage = (arc2 - (sizey - i)) * (arc - n_fg - n_aa + 1) * .5;
					// Coverage is incorrect. Why?
					coverage = 0;
				}
			} else if (j == n_aa) {
				// Last in a run
				arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
				coverage = 1.0 - (1.0 - (arc2 - (sizey - i))) * (1.0 - (lastarc - n_fg)) * .5;
			} else {
				// Middle of a run
				arc3 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j) / sizex)) * sizey;
				arc2 = Math.sqrt(1.0 - Math.sqr((sizex - n_bg - j + 1) / sizex)) * sizey;
				coverage = ((arc2 + arc3) * .5) - (sizey - i);
			}//if
			
			oInnerTop.style.backgroundColor = Blend(bgColor, fgColor, coverage);
			oInnerBot.style.backgroundColor 	= Blend(bgColor, fgColor, coverage);
			//append inner div to outer
			if(topRight || topLeft) 	oOuterTop.appendChild(oInnerTop);
			if(botLeft || botRight) 	oOuterBot.insertBefore(oInnerBot, oOuterBot.firstChild);
			//set current inner to be new outer
			oOuterTop = oInnerTop;
			oOuterBot = oInnerBot;
			//make fresh inners
			var oInnerTop 						= document.createElement("div");
			oInnerTop.style.height			='1px';
			oInnerTop.style.overflow		='hidden';
			var oInnerBot 						= document.createElement("div");
			oInnerBot.style.height			='1px';
			oInnerBot.style.overflow		='hidden';

			//top margins	
			oInnerTop.style.margin = "0px 0px 0px 0px"; //default
			if(topLeft) 		oInnerTop.style.marginLeft 		= "1px";
			if(topRight) 	oInnerTop.style.marginRight 	= "1px";
			//bottom margins
			oInnerBot.style.margin = "0px 0px 0px 0px"; //default
			if(botLeft) 		oInnerBot.style.marginLeft 		= "1px";
			if(botRight) 	oInnerBot.style.marginRight 		= "1px";

		}//for
		oInnerTop.style.backgroundColor = fgColor;
		oInnerBot.style.backgroundColor 	= fgColor;
		if(topRight || topLeft) 	oOuterTop.appendChild(oInnerTop);
		if(botRight || botLeft) 	oOuterBot.insertBefore(oInnerBot, oOuterBot.firstChild);
		lastarc = arc;
	}//for

	oTop.className = 'rx';
	oBot.className = 'ry';

	//attach containers to element
	if(topLeft || topRight) el.insertBefore(oTop, el.firstChild);
	if(botRight || botLeft) el.appendChild(oBot);
}


function get_current_style(element,property,not_accepted)
{
	var ee,i,val,apr;
	try
	{
		var cs=document.defaultView.getComputedStyle(element,'');
		val=cs.getPropertyValue(property);
	}
	catch(ee)
	{
		if(element.currentStyle)
		{
			apr=property.split("-");
			for(i=1;i<apr.length;i++) apr[i]=apr[i].toUpperCase();
			apr=apr.join("");
			val=element.currentStyle.getAttribute(apr);
	 }
	}
	if((val.indexOf("rgba") > -1 || val==not_accepted) && element.parentNode)
	{
	 if(element.parentNode != document) 
		 val=get_current_style(element.parentNode,property,not_accepted);
	 else
		 val = '#FFFFFF';
	}
	if (val.indexOf("rgb") > -1 && val.indexOf("rgba") == -1)
		val = rgb2hex(val);
	if (val.length == 4)
		val = '#'+val.substring(1,1)+val.substring(1,1)+val.substring(2,1)+val.substring(2,1)+val.substring(3,1)+val.substring(3,1);
	return val;
}

function rgb2hex(value)
{
	var x = 255;
	var hex = '';
	var i;
	var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
	var array=regexp.exec(value);
	for(i=1;i<4;i++) hex += ('0'+parseInt(array[i]).toString(16)).slice(-2);
	return '#'+hex;
}
