

var targetWPx = 300; // -1 means that marginf0 will not be altered
var marginf0 = 1.0 / 5.0;
var marginf1 = 1.0;
var rn = 8;
// array of rn arrays, each value is a radius for the n pts
var rfs;
// array of rn fillStyle strings
var rstyles0;
var rstyles1;
var rstyleCutxf = 1 / 8.0;

var minr = 2.0;
var maxr = 90.0;


var fps = 24;



function init() {
	
	rfs = new Array(rn);
	for (var i = 0; i < rn; ++i) {
		rfs[i] = new Array(ptn);
	}
	rstyles0 = new Array(rn);
	// initial rstyles; used if no overwrite
	for (var ri = 0; ri < rn; ++ri) {
		var f = 0.5 + 0.5 * (rn - ri) / (1.0 * rn);
		var r = Math.floor(255 * f);
		var g = 0;
		var b = 0;
		rstyles0[ri] = "rgba(" + r + "," + g + "," + b + ",255)";
	}
	rstyles1 = new Array(rn);
	// initial rstyles; used if no overwrite
	for (var ri = 0; ri < rn; ++ri) {
		var f = 0.5 + 0.5 * (rn - ri) / (1.0 * rn);
		var r = Math.floor(255 * f);
		var g = Math.floor(255 * f);
		var b = Math.floor(255 * f / 4);
		rstyles1[ri] = "rgba(" + r + "," + g + "," + b + ",255)";
	}
	
	
	step();
	
	
	// var ctx = thesurface.getContext("2d");

	resize();
	
}
function resize() {

	var tw = $("#thesurfaceContainer").width();
	var th = $("#thesurfaceContainer").height();
	
	var thesurface = document.getElementById("thesurface");
	thesurface.width = tw;
	thesurface.height = th;
	
	if (0 < targetWPx) {
		marginf0 = (tw - targetWPx) / (2.0 * tw);
		//alert(marginf);
	}

//	$("#thesurface").width($("#thesurfaceContainer").width());
//	$("#thesurface").height($("#thesurfaceContainer").height());
	
	paint();
}



//var temprfs = new Array(ptn);

function paint() {
	
	var thesurface = document.getElementById("thesurface");
	var ctx = thesurface.getContext("2d");
	var w = thesurface.width;
	var h = thesurface.height;
	
	var ar = 1.0; // w/h
	// FIXME: should be uwf0, uwf1
	var uw = w - 2 * marginf0 * marginf1 * w;
	//var uw = Math.min(w - 2 * margin, (h - 2 * margin) * ar);
	var uh = uw / ar;
	//alert(uw);
	
	ctx.save();
	
		ctx.clearRect(0, 0, w, h);
	
		ctx.translate((w - uw) / 2, (h - uh) / 2);
		
		ctx.fillStyle = "rgba(255, 255, 255, 255)";
		ctx.fillRect(0, 0, w, h);
		
//		for (var i = 0; i < ptn; ++i) {
//			temprfs[i] = 1.0;
//		}
		for (var ri = 0; ri < rn; ++ri) {
			
			ctx.fillStyle = rstyles0[ri];
//			ctx.beginPath();
			for (var i = 0; i < ptn; ++i) {
				var pt = pts[i];
				var cxf = pt[0];
				if (rstyleCutxf <= cxf) {
					var cyf = pt[1];
//					var rf = (temprfs[i] *= rfs[ri][i]);
	//				alert(rf);
					var r = minr + (maxr - minr) * rfs[ri][i];
					ctx.beginPath();
					addEllipse(ctx, uw * cxf - r, uh * cyf - r, 2 * r, 2 * r);
					ctx.fill();
				}
			}
//			ctx.fill();
			
			ctx.fillStyle = rstyles1[ri];
//			ctx.beginPath();
			for (var i = 0; i < ptn; ++i) {
				var pt = pts[i];
				var cxf = pt[0];
				if (cxf < rstyleCutxf) {
					var cyf = pt[1];
//					var rf = (temprfs[i] *= rfs[ri][i]);
	//				alert(rf);
					var r = minr + (maxr - minr) * rfs[ri][i];
					ctx.beginPath();
					addEllipse(ctx, uw * cxf - r, uh * cyf - r, 2 * r, 2 * r);
					ctx.fill();
				}
			}
//			ctx.fill();
		}
		
		/*
		var n = pts.length;
		//alert(n);
		ctx.fillStyle = "rgba(255, 0, 0, 255)";
		for (var i = 0; i < n; ++i) {
			var pt = pts[i];
			var cx = uw * pt[0];
			var cy = uh * pt[1];
	//		alert(cx + ", " + cy);
			var r = 14;
			ellipse(ctx, cx - r, cy - r, 2 * r, 2 * r);
			ctx.fill();
			//alert((cx - 4) + ", " + (cy - r) + ", " + (2 * r) + ", " + (2 * r));
	//		ctx.fillRect(cx - r, cy - r, 2 * r, 2 * r);
	//		ctx.fillRect(10, 10, 100, 100);
			
		}
		ctx.fillStyle = "rgba(255, 255, 255, 255)";
		for (var i = 0; i < n; ++i) {
			var pt = pts[i];
			var cx = uw * pt[0];
			var cy = uh * pt[1];
	//		alert(cx + ", " + cy);
			var r = 9;
			ellipse(ctx, cx - r, cy - r, 2 * r, 2 * r);
			ctx.fill();
			//alert((cx - 4) + ", " + (cy - r) + ", " + (2 * r) + ", " + (2 * r));
	//		ctx.fillRect(cx - r, cy - r, 2 * r, 2 * r);
	//		ctx.fillRect(10, 10, 100, 100);
			
		}
	*/
		
	ctx.restore();
}


// on step, adjust rs, each r on [0, 1]
// rs have a fixed size blended in by proximity to mouse

var lastStepTime = 0;
function step() {
	var stepTime = new Date().getTime();
	if (0 != lastStepTime) {
		adv(fps * (stepTime - lastStepTime) / 1000.0);
	}
	else {
		adv(0);
	}
	lastStepTime = stepTime;
	
	paint();
}

var frame = 0.0;
function adv(advFrames) {
	frame += advFrames;
	
	// set the rns
	for (var ri = 0; ri < rn; ++ri) {
		for (var i = 0; i < ptn; ++i) {
			var pt = pts[i];
			var cxf = pt[0];
			var cyf = pt[1];
			
			var rf = 0.5 + 0.25 * Math.sin(2 * Math.PI * cxf + (frame) * (1.0 + ri)/ (40.0))
				+ 0.25 * Math.cos(2 * Math.PI * cyf + (frame) * (1.0 + ri) / (40.0));
//			alert(2 * Math.PI * cxf);
			rfs[ri][i] = rf;
			if (0 < ri) {
				// Accumulate product
				rfs[ri][i] *= rfs[ri - 1][i];
			}
		}
	}
	
	// set the styles
	// FIXME
	
	
	// TODO: use a cubic 1D bezier here, for smooth transitions
	marginf1 = 1 + 0.025 * Math.sin(frame / 30.0); //1/(24 + (0 < f ? (6 * f) : (12 * f)));
}


function addEllipse(ctx, x, y, w, h) {
	  var kappa = .5522848;
	      ox = (w / 2) * kappa, // control point offset horizontal
	      oy = (h / 2) * kappa, // control point offset vertical
	      xe = x + w,           // x-end
	      ye = y + h,           // y-end
	      xm = x + w / 2,       // x-middle
	      ym = y + h / 2;       // y-middle

	  ctx.moveTo(x, ym);
	  ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
	  ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
	  ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
	  ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
	  ctx.closePath();
	}



/* ***** ***** ***** ***** ***** */


$(window).bind("load", init);
$(window).bind("resize", resize);

var riv = setInterval(step, 1000.0 / fps);


