////============================================
//// expo18.js, 05/14/09, by ralph abraham
//// sierpinski gasket

//// GLOBAL VARS
	
	// hardwired init points, world coords
	var u0 = 0.5; // init u, start trajectory
	var v0 = 0.5; // init v 
	var u1 = 0.5; // init u, first target
	var v1 = 0.25; // init v 
	var u2 = 0.25; // init u, second target
	var v2 = 0.75; // init v 
	var u3 = 0.75; // init u, third target
	var v3 = 0.75; // init v 
	var u = [0, u1, u2, u3]; // so we can choose them at random
	var v = [0, v1, v2, v3];
	
	// hardwired init points, screen coords
	var x0 = screenx(u0);
	var y0 = screeny(v0);
	var x1 = screenx(u1);
	var y1 = screeny(v1);
	var x2 = screenx(u2);
	var y2 = screeny(v2);
	var x3 = screenx(u3);
	var y3 = screeny(v3);
	
	// to setup 2D world coords (u, v) ranges
	// init values determined by canvas size
	var wumax = 1.0; // worldu max
	var wumin = 0; // worldu min
	var wvmax = 1.0; // worldv max
	var wvmin = 0; // worldv min
	// and screen coords (x, y) ranges
	var sxmax = 320; // screenx max, use width of canvas from HTML page
	var sxmin = 0; // screenx min
	var symax = 280; // screeny max, use height of canvas from HTML page
	var symin = 0; // screeny min
	
	// color spectrum 03 as an array of strings
	var a = new Array();
	a[0] = "red";
	a[1] = "#FF8000";
	a[2] = "yellow";
	a[3] = "#80FF00";
	a[4] = "lime";
	a[5] = "#00FF80";
	a[6] = "cyan";
	a[7] = "#0080FF";
	a[8] = "blue";
	a[9] = "#8000FF";
	a[10] = "magenta";
	a[11] = "#FF0080";
	a[12] = "white"; // for overscale
	a[13] = "white";
	a[14] = "white";
	mycolor = ["black", "red", "green", "blue"]; // so we can choose color

//// MATH FUNCS 

	// map screen to world coords, x --> u
	function worldu(sx) {
		var temp =  ( sx - sxmin ) / ( sxmax - sxmin );
		return wumin + ( wumax - wumin ) * temp;
	};

	// map screen to world coords, y --> v
	function worldv(sy) {
		var temp =  ( sy - symin ) / ( symax - symin );
		return wvmax - ( wvmax - wvmin ) * temp;
	};
	
	//// MATH FUNCS world (u, v) --> screen (x, y)

	function screenx(wu) {
		return 320 * wu;
	};
	
	function screeny(wv) {
		return 280 - 280 * wv;
	};

	// euclidean plane distance for world coords
	function dist(u1, v1, u2, v2) {
		var du2 = (u1 - u2) * (u1 - u2);
		var dv2 = (v1 - v2) * (v1 - v2);
		return Math.sqrt(du2 + dv2);
	};

//// this generates a random selection from {1,2,3}
	
	function rollem() {
		var r1 = Math.random(); // random float in [0, 1]
		return Math.ceil(3 * r1); /// random int
	};

//// here is the map system
	function affu(u,f) {
		if (f == 1){
			return 0.5 * (u + u1);
			}
		else if (f == 2) {
			return 0.5 * (u + u2);
		}
		else if (f == 3) {
			return 0.5 * (u + u3);
		}
		else {
			return 0;
		}
	};

	function affv(v,f) {
		if (f == 1){
			return 0.5 * (v + v1);
			}
		else if (f == 2) {
			return 0.5 * (v + v2);
		}
		else if (f == 3) {
			return 0.5 * (v + v3);
		}
		else {
			return 0;
		}
	};

	
//// SETUP

	// wait for the browser to load
	window.onload = function() {
	// set up background basic template
		base00(); // draw entire canvas
		drawblot(x0, y0, 4, "yellow"); // init blot
		drawblot(x1, y1, 4, "red"); //target blots
		drawblot(x2, y2, 4, "green"); 
		drawblot(x3, y3, 4, "blue"); 
	};
	
    // setup single white canvas
	function base00()  {
		var canvas = document.getElementById("canvas"); // only one canvas
		var ctx = canvas.getContext("2d");
 		ctx.fillStyle = "black"; //  bg color
 		ctx.fillRect (0, 0, 320, 280);
	};
	
	// draw a blot from upper corner (x, y), height and width w, color c
	function drawblot(x, y, w, c) {
		var canvas = document.getElementById("canvas"); // only one canvas
		var ctx = canvas.getContext("2d");
		//ctx.clearRect(x, y, w, w);
 		ctx.fillStyle = c; //  colored rect
 		ctx.fillRect (x, y, w, w);
	};

//// declare and init vars for iteration
  	var unow = u0;
  	var vnow = v0;
  	var unext = 0.5 * unow; // temp version of map
  	var vnext = 0.5 * vnow;
  	var xnext = screenx(unext);
  	var ynext = screeny(vnext);

//// step functions
	function step() {
		var face = rollem(); // chose face
		//alert(mycolor[face]);
		unext = affu(unow, face); // apply the dorband map
  		vnext = affv(vnow, face);
  		xnext = screenx(unext); // get screen coords
  		ynext = screeny(vnext);
  		var temp1 = dist(unow, vnow, unext, vnext);
  		var temp2 = Math.floor(40 * temp1);
		drawblot(xnext, ynext, 2, a[temp2]); // draw next point
		unow = unext; // now step the map
		vnow = vnext;
	};
	
	function multistep(n) {
		for (count=0; count < n; count++)
			step();
	};
  	
    // this is for interaction
    // NOTE: javascript has no widgets other than the canvas
    // 	so we have made some primitive buttons in the HTML code
	document.onclick = function(ev) { // to step the map
		// alert(rollem());
		//step();
		var dx = ev.clientX; // document coords not equal to canvas coords
		if (dx > 240) {
			multistep(10000);
		}
		else if (dx > 160) {
			multistep(1000);
		}
		else if (dx > 80) {
			multistep(100);
		}
		else {
			multistep(1);
		};
	};

////////// END ///////////
