window.onload = function (){
	var pine = {
		framerate				: 30,
		width 					: window.innerWidth,
		height 					: window.innerHeight,
		cycleTime				: 0.0,
		cycleFull				: 60.0,
		sides						: 6,
		alarm						: "13:59:26 March 14, 2010"
	}
	pine.alarm = new Date(pine.alarm);
	
	var lastTime = new Date();

	//calculate the right sizes
	if (pine.width > pine.height){pine.radius = pine.height/2.5;}
	else{pine.radius = pine.width/2.5}
	
	//make a Processing.js instance
	var p = Processing("canvasElement");

	//Setup    
	p.setup = function(){
		this.size(pine.width,pine.height);
		this.frameRate(pine.framerate);
		};
		
	p.draw = function () {
		//STEP
		//set rendered time to current time
		var nowTime = new Date();
		pine.cycleTime = nowTime.getSeconds() + (nowTime.getMilliseconds()/1000);
		
		//if we've advanced a minute, reset the timekeeper and increment NGon
		if(nowTime.getMinutes() > lastTime.getMinutes() ||
				nowTime.getHours() > lastTime.getHours()){
			pine.sides = pine.sides+1;
			lastTime = new Date();
			updateUI(pine.sides);
			}
				
		//DRAW
		this.background(0,51,102);
	
		this.translate(pine.width/2, pine.height/2);
		//base square
		this.stroke(0,94,188);
		this.fill(5,65,125);
		this.rect(-pine.radius, -pine.radius,2*pine.radius,2*pine.radius);
		//grid
		this.line(0,pine.radius,0,-pine.radius);
		this.line(-pine.radius,0,pine.radius,0);
		
//		this.noFill();
//		this.ellipse(0,0,2*pine.radius,2*pine.radius);

		this.noStroke();
		this.fill(0,50,120,128);
		complementNGon(pine.sides,pine.radius,{"x":4,"y":4});

	
		this.stroke(8,111,216,192);
		this.fill(8,111,216,128);
		//this.ellipse(0,0,2*pine.radius, 2*pine.radius);
		//ngon(11);
		//this.noFill();
		//this.stroke(255,0,0,255);
		var nGonPerimeter = timedNGon(pine.sides);
		this.noStroke();
		this.fill(150,150,216,128);
//		complementNGon(pine.sides,pine.radius*2/3);
		this.fill(75,130,216,128);
//		complementNGon(pine.sides,pine.radius*5/6);
		
	
		var squarePerimeter = (8*pine.radius);
		var derivedPi = 4*nGonPerimeter/(squarePerimeter * (pine.cycleTime/pine.cycleFull));
		this.textSize(12);
		this.text("π≈"+derivedPi.toFixed(15),-pine.radius,pine.radius+20);
  	this.text(pine.sides+" sides",-pine.radius,pine.radius+40);
  	
  	/****************
  	***		Alarm		***
  	****************/
  	
  	//at a minute from the alarm, count it down
  	if(pine.alarm - nowTime < 59000 && pine.alarm - nowTime > -3000){
  		if(pine.alarm - nowTime > 0){
	  		var countdown = (pine.alarm - nowTime) / 1000 + 1;
  			this.textSize(pine.radius);
  			this.fill(250,20,20,175);
  			this.text(countdown.toFixed(0),
  				-pine.radius/2,pine.radius/3);
  			}
  		else{
  			this.textSize(pine.radius);
  			this.fill(250,250,250,175 - 175 *((nowTime - pine.alarm)/3000));
  			this.text("π",-pine.radius/4,pine.radius/3)		
	  		}
  		}
  	};

	//keep the canvas element the same size as the window
	this.resize = function(){
		pine.width = window.innerWidth;
		pine.height = window.innerHeight;
		p.size(pine.width,pine.height);
		
		//calculate the right sizes the right sizes
		if (pine.width > pine.height){pine.radius = pine.height/3;}
		else{pine.radius = pine.width/3}
		}
	
	this.ngon = function(sides){
		var theta = 0.0;
		p.beginShape();
		for(var i = 0; i <= sides; i++){
			var x = pine.radius * Math.sin(theta);
			var y = pine.radius * Math.cos(theta);
			theta = theta + (2*exPi)/sides;
			p.vertex(x,-y);
		};
		p.endShape();
	}
	
	this.pt = function(theta, radius){
		if(!radius){radius=pine.radius;}
		var point = new Array();
		point["x"] = radius * Math.sin(theta);
		point["y"] = -radius * Math.cos(theta);
		return point;
	}
	
	
	this.timedNGon = function(sides){
		var theta = 0.0;
		//var area = 0.0;
		var perim = 0.0;
		p.beginShape();
		p.vertex(0,0);
		p.vertex(0,-pine.radius);
		//loop through vertices already revealed
		var i = 1;
		//draw next vertex and get the area of the composed triangle
		while (i/sides <= pine.cycleTime/pine.cycleFull && pine.cycleTime < pine.cycleFull){
			
			//calc & draw
			var prev = pt(theta);
			theta = theta + (2*exPi)/sides;
			var next = pt(theta);
			p.vertex(next.x, next.y);
			
			//area
			//area += triArea(prev,next);
			perim += triBase(prev,next);
			
			i++;
			}
		
		//Find the final vertex
		var prev = pt(theta);
		var next = pt(theta + (2*exPi)/sides);
		var curr = pt((pine.cycleTime/pine.cycleFull) * (2*exPi));
		
		var finalVertex = intersect(prev,next,curr,{"x":0,"y":0});
		p.vertex(finalVertex["x"],finalVertex["y"]);
		
		p.vertex(0,0); //close it, because p.endShape(CLOSE) didn't work
		p.endShape();
		
		//and get the area of the advancing triangle
		//area += triArea(prev, finalVertex);
		perim += triBase(prev, finalVertex);
		return perim;
	}
	
	this.complementNGon = function(sides, radius, offset){
		var theta = 0.0;
		if(!offset){offset = {"x":0,"y":0};};
		p.beginShape();
		p.vertex(0,0);
		p.vertex(0,-radius+offset.x+offset.y);
		//loop through vertices already revealed
		var i = 1;
		//draw next vertex and get the area of the composed triangle
		while (i/sides <= pine.cycleTime/pine.cycleFull && pine.cycleTime < pine.cycleFull){
			theta = theta + (2*exPi)/sides;
			var next = pt(theta, radius);
			p.vertex(next.x+offset.x, next.y+offset.y);
			i++;
			}
		
		//Find the final vertex
		var prev = pt(theta, radius);
		var next = pt(theta + (2*exPi)/sides, radius);
		var curr = pt((pine.cycleTime/pine.cycleFull) * (2*exPi));
		
		var finalVertex = intersect(prev,next,curr,{"x":0,"y":0});
		p.vertex(finalVertex["x"]+offset.x,finalVertex["y"]+offset.y);
		
		p.vertex(0,0); //close it, because p.endShape(CLOSE) didn't work
		p.endShape();
		
	}
	
	this.triArea = function(p1,p2){
		//note: function assumes third point is at centre
		//get base
		var lX = p2.x - p1.x;
		var lY = p2.y - p1.y;
		var base = Math.sqrt(lX*lX + lY*lY);
		
		//get height
		var halfX = (p2.x - p1.x)/2 + p1.x; //unstated: subtracting by centrepoint, at zero
		var halfY = (p2.y - p1.y)/2 + p1.y; //unstated: subtracting by centrepoint, at zero
		var height = Math.sqrt(halfX*halfX + halfY*halfY);
				
		return 0.5*base*height;
		}
	
	this.triBase = function(p1,p2){
		var lX = p2.x - p1.x;
		var lY = p2.y - p1.y;
		var base = Math.sqrt(lX*lX + lY*lY);
		
		return base;
	}
		
	
	this.intersect = function(a1,a2,b1,b2){
		//adapted from http://workshop.evolutionzone.com/2007/09/10/code-2d-line-intersection/
		
		//calculate differences
		var xD1 = a2.x-a1.x;
		var xD2 = b2.x-b1.x;
		var yD1 = a2.y-a1.y;
		var yD2 = b2.y-b1.y;
		var xD3 = a1.x-b1.x;
		var yD3 = a1.y-b1.y;
		
		//find intersection
		var pt = new Array();
		var div = yD2*xD1-xD2*yD1;
		var ua = (xD2*yD3-yD2*xD3)/div;
		var ub = (xD1*yD3-yD1*xD3)/div;
		pt["x"] = a1.x+ua*xD1;
		pt["y"] = a1.y+ua*yD1;
		
		return pt;
		
	}
		

	/*********************
	**		Interface			**
	*********************/
	this.updateUI = function(sides){
		$("input#sides").val(sides);
		//console.log(sides);
		};
	
	
		
	$("input#sides").change(function(){
		pine.sides = this.value;
		});

	//start processing.js
	p.init();
	
};

window.onresize = function(){this.resize();}


