/*

- Make better for straight corners
- Fix slider/input interaction

- Use color wheel? http://acko.net/dev/farbtastic

*/
$(function() {

	document.converter.onsubmit = function() { 
		$('#custom_corners input').each(function() {
			var t = $(this);
			t.parent().find('div').slider('value',t.val());
		});
		setSlider();

		return false;
	};
// 	$('#convert').click(convert);
	
	$('#rad_slider').slider({
		range: "min",
		max: 50,
		value: 10,
		slide: function() {
			convert();
			document.converter.c_opt[0].checked = true;
		},
		change: convert
	});
	
	var setSlider = function() {
		document.converter.c_opt[1].checked = true;
// 		var t = $(this);
// 		t.parent().find('input').change();
		convert();
		
	}

	
	$('#rad_slider_tl,#rad_slider_tr,#rad_slider_br,#rad_slider_bl').slider({
		range: "min",
		max: 50,
		value: 10,
		slide: setSlider
	});
	
	$('#custom_corners input').change(function() {
		var t = $(this);
		t.parent().find('div').slider('value',t.val());
		setSlider();
// 		opera.postError('input changed: ' + t.val());
	});
	
	$('label input').change(convert);

	
	convert();
});

function convert() {
	var f = document.converter;
	var note = '';
	
	// var radius = f.radius.value;
	var radius = $('#rad_slider').slider('value');
// 	opera.postError('r-tl: ' + $('#rad_slider_tl').slider('value'));

	var width = f.width.value-0;
	var bg_color = f.bg_color.value;
	var border_color = f.border_color.value;
	var under_color = f.under_color.value;
	

// 	var corners = [$('#rad_slider_tl').slider('value')-0,$('#rad_slider_tr').slider('value')-0,
// 		$('#rad_slider_br').slider('value')-0,$('#rad_slider_bl').slider('value')-0];

	var s_start = '<svg xmlns="http://www.w3.org/2000/svg">'
	var s_end = '<\/svg>';
	
	var c_all = f.c_opt[0].checked;
	

	f.radius.value = radius;
	
	if(!c_all) {
		f.topleft.value = $('#rad_slider_tl').slider('value');
		f.topright.value = $('#rad_slider_tr').slider('value');
		f.botright.value = $('#rad_slider_br').slider('value');
		f.botleft.value = $('#rad_slider_bl').slider('value');
	}
	
	var c_names = ['top-left','top-right','bottom-right','bottom-left'];
	var corners = [f.topleft.value-0,f.topright.value-0,f.botright.value-0,f.botleft.value-0];
	
	var alt_corners = false;
	var rad_total = 0;
	var webkit_css = '';
	for(var i=0;i<corners.length;i++) {

		rad_total += (corners[i]);
		
		if(corners[i] != corners[0]) {
			alt_corners = true;
			webkit_css += ("-webkit-border-"+c_names[i]+"-radius: " + corners[i] + "px;\n");
		}
	}
	
	var css = 
		(width?"border: " + width + "px solid " + border_color + ";\n":"")
		+ "background-color: " + bg_color + ";\n"
	
	if(alt_corners) { 
		var c_rad = corners;
		var svg;

		if(rad_total === 0) {
			//no rounded corners
			
			return false;
		}


		var mkRect = function(id,x,y,w,h,f,r,tl) {
			return '<rect' 
				+ (id?' id="' + id + '"':'')
				+ (x?' x="' + x + '"':'')
				+ (y?' y="' + y + '"':'')
				+ (w?' width="' + w + '"':'')
				+ (h?' height="' + h + '"':'')
				+ (f?' fill="' + f + '"':'')
				+ (r?' rx="' + r + '"':'')
				+ (tl?' transform="translate(' + tl + ')"':'')
				+ '/>';
		};
		
		var isSame = function() {
			var a = arguments;
			var f = a[0];
// 			opera.postError('is');
			for(var i=0; i<a.length; i++)  {
				if(a[i] != f) return false;
			}
			return true;
		}
		
		var is0 = function() {
			var a = arguments;
			for(var i=0; i<a.length; i++)  {
				if(a[i] !== 0) return false;
			}
			return true;
		}
		
		var mkCover = function(type,size) {
			var t = type;
			var s = size;
			var c = bg_color;
			var r;
			switch ( type ) {
				case 'tl':
					r = mkRect(0,0,0,s,s,bg_color);
					break;
				case 'tr':
					r = mkRect(0,'100%',0,s,s,bg_color,0,'-' + s);
					break;
				case 'br':
					r = mkRect(0,'100%','100%',s,s,bg_color,0,'-' + s + ',-' + s);
					break;					
				case 'bl':
					r = mkRect(0,0,'100%',s,s,bg_color,0,'0,-' + s);
					break;
				
				case 't':
					r = mkRect(0,0,0,'100%',s,bg_color);
					break;
				case 'r':
					r = mkRect(0,'100%',0,s,'100%',bg_color,0,'-' + s);
					break;
				case 'b':
					r = mkRect(0,0,'100%','100%',s,bg_color,0,'0,-' + s);
					break;
				case 'l':
					r = mkRect(0,0,0,s,'100%',bg_color);
					break;
			}
			return r;
		}
	
	
		if(!width) {
		
			// Different corners, no border
				
			var cover_rect = '';

			// One straight corner
			if(c_rad[0] == 0 && isSame(c_rad[1],c_rad[2],c_rad[3])) {
				cover_rect = mkCover('tl',c_rad[1]);
				radius = c_rad[1];
			} else if(c_rad[1] == 0 && isSame(c_rad[0],c_rad[2],c_rad[3])) {
				cover_rect = mkCover('tr',c_rad[0]);
				radius = c_rad[0];
			} else if(c_rad[2] == 0 && isSame(c_rad[0],c_rad[1],c_rad[3])) {
				cover_rect = mkCover('br',c_rad[0]);
				radius = c_rad[0];
			} else if(c_rad[3] == 0 && isSame(c_rad[0],c_rad[1],c_rad[2])) {
				cover_rect = mkCover('bl',c_rad[0]);
				radius = c_rad[0];
			}

			// Two straight corners
			if(is0(c_rad[0],c_rad[1]) && isSame(c_rad[2],c_rad[3])) {
				cover_rect = mkCover('t',c_rad[2]);
				radius = c_rad[2];
			} else if(is0(c_rad[1],c_rad[2]) && isSame(c_rad[0],c_rad[3])) {
				cover_rect = mkCover('r',c_rad[0]);
				radius = c_rad[0];
			} else if(is0(c_rad[2],c_rad[3]) && isSame(c_rad[0],c_rad[1])) {
				cover_rect = mkCover('b',c_rad[0]);
				radius = c_rad[0];
			} else if(is0(c_rad[3],c_rad[0]) && isSame(c_rad[1],c_rad[2])) {
				cover_rect = mkCover('l',c_rad[1]);
				radius = c_rad[1];
			}
			
			// Two straight opposing corners
			if(is0(c_rad[0],c_rad[2]) && isSame(c_rad[1],c_rad[3])) {
				cover_rect = mkCover('tl',c_rad[1])	+ mkCover('br',c_rad[1]);
				radius = c_rad[1];
			} else if(is0(c_rad[1],c_rad[3]) && isSame(c_rad[0],c_rad[2])) {
				cover_rect = mkCover('tr',c_rad[0])	+ mkCover('bl',c_rad[0]);
				radius = c_rad[0];
			}
			
			// Three straight corners
			if(isSame(c_rad[0]) && is0(c_rad[1],c_rad[2],c_rad[3])) {
				cover_rect = mkCover('r',c_rad[1]) + mkCover('bl',c_rad[1]);
				radius = c_rad[0];
			} else if(isSame(c_rad[1]) && is0(c_rad[0],c_rad[2],c_rad[3])) {
				cover_rect = mkCover('b',c_rad[0]) + mkCover('tl',c_rad[0]);
				radius = c_rad[1];
			} else if(isSame(c_rad[2]) && is0(c_rad[0],c_rad[1],c_rad[3])) {
				cover_rect = mkCover('l',c_rad[0]) + mkCover('tr',c_rad[0]);
				radius = c_rad[2];
			} else if(isSame(c_rad[3]) && is0(c_rad[0],c_rad[1],c_rad[2])) {
				cover_rect = mkCover('tl',c_rad[0]) + mkCover('r',c_rad[0]);
				radius = c_rad[3];
			}

			if(cover_rect) {
				svg = s_start 
					+ (under_color?('<rect fill="' + under_color + '" width="100%" height="100%"/>'):'')
					+ '<rect fill="' + bg_color + '" rx="' + radius + '" width="100%" height="100%"/>'
					+ cover_rect
					+ s_end;
			}
		}
	
		// Different corners, with border
		if(!svg) {
		
			var mkClip = function(id,x,y,w,h) {
				return '<clipPath id="' + id + '"><rect x="' + x + '" y="' + y + '" width="' + w + '" height="' + h + '"\/><\/clipPath>';
			}
		
			var getSize = function(a,b) {
				// Voodoo to prevent bugs. Really!
				return Math.min(90,(100 - a/4) - (b - a)) + '%';
			}
			
			var hwidth = width/2;
			var tl_w = getSize(c_rad[0],c_rad[1]); 
			var tl_h = getSize(c_rad[0],c_rad[3]); 
			var tr_h = getSize(c_rad[1],c_rad[2]); 		
			var bl_w = getSize(c_rad[3],c_rad[2]); 
	
			
			svg = 
	
			'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'
			+ '<style type="text/css">rect {'
			+ 'fill: ' + bg_color + ';'
			+ 'stroke: ' + border_color + ';'
			+ 'stroke-width: ' + width + 'px;'
			+ '}<\/style>'
			
			+ '<defs>'
			+ mkRect("a",hwidth,hwidth,tl_w,tl_h,0,c_rad[0])
			+ mkRect("d",hwidth,"-100%",bl_w,'100%',0,c_rad[3])
			+ mkClip('bl',0,"-50%","50%","100%")
			+ mkRect("b","-100%",hwidth,"100%",tr_h,0,c_rad[1])
			+ mkClip('tr',"-50%",0,"100%","50%")
			+ mkRect("c","-100%","-100%","100%","100%",0,c_rad[2])
			+ mkClip('br',"-50%","-50%","100%","100%")
			+ '<\/defs>'
	
			+ (under_color?('<rect style="fill:' + under_color + ';stroke-width:0" width="100%" height="100%"/>'):'')
			+ '<use xlink:href="#a"/>'
			+ '<use xlink:href="#d" y="100%" transform="translate(0,-' + hwidth + ')" clip-path="url(#bl)"/>'
			+ '<use xlink:href="#b" x="100%" transform="translate(-' + hwidth + ',0)" clip-path="url(#tr)"/>'
			+ '<use xlink:href="#c" x="100%" y="100%" transform="translate(-' + hwidth + ',-' + hwidth + ')" clip-path="url(#br)"/>'
			+ '<\/svg>';
		}
	

		//Make CSS
		css += "border-radius: " + c_rad.join('px ') + "px;\n"
		+ "-moz-border-radius: " + c_rad.join('px ') + "px;\n"
		+ webkit_css
		
		
	} else if(!width) { //No border
		
		var svg = s_start 
			+ (under_color?('<rect fill="' + under_color + '" width="100%" height="100%"/>'):'')
			+ '<rect fill="' + bg_color + '" rx="' + radius + '" width="100%" height="100%"/>'
			+ s_end;
			
		//Make CSS
		css += "border-radius: " + radius + "px;\n"
		+ "-moz-border-radius: " + radius + "px;\n"
		+ "-webkit-border-radius: " + radius + "px;\n";
		
	} else { //simple corners
		//Make SVG
		var radii = 'rx="' + radius;
		
		var box_start = '<rect width="100%" height="100%" ';
		var mask = '<mask id="m">'
			+ box_start + radii + '" fill="#fff"/>'
			+ '<\/mask>';
		
		var box = box_start 
			+ 'stroke="' + border_color
			+ '" fill="' + bg_color
			+ '" stroke-width="' + (width*2)
			+ '" mask="url(#m)" ' + radii + '"/>';
		
		var svg = s_start + mask + box + s_end;
		
		//Make CSS
		css += "border-radius: " + radius + "px;\n"
		+ "-moz-border-radius: " + radius + "px;\n"
		+ "-webkit-border-radius: " + radius + "px;\n";


	}
	
	var img = 'data:image/svg+xml;charset=utf-8;base64,' + base64encode(svg);
	

	if(under_color && !width) {
		//Can combine all the CSS, no hacks
		note = "The CSS output can be safely used to work in all browsers but IE (provided you use a solid color behind this box)";
		
		css += "background: " + bg_color + " url(" + img + ");\n";
	} else if(!width) {
		note = "Specify a background color to include compatibility for Opera";
	} else {
		note = "Including a border means you will have to use a CSS/JS/server hack to send the SVG CSS to Opera";
	}
	
	
	$('#svg_output').val(svg);
	
	$('#css_output').val(css);
	$('#css_svg_output').val("background-image: url(" + img + ");");

	var testarea = $('#testarea');
	
	if(window.opera) {
		testarea.css('background-image','url(' +img + ')');
	} else {
		css_style = css.replace(/\n/g,'',css);
		testarea.attr('style',css_style);
	}
	

	if(note) $('#notes').html('<b>Note:</b> ' + note);
}

//Source: http://simonwillison.net/2003/Aug/11/selfContained/
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

function base64encode(str) {
    var out; var i; var len;
    var c1; var c2; var c3;
    var len = str.length;
    var i = 0;
    out = "";
    while(i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if(i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}
