function Stars(canvas){
	var ctx = canvas.ctx; 
	var SCREEN_HEIGHT = canvas.height; 
	var SCREEN_WIDTH = canvas.width;
	var PI = 3.14159; 
	var SCREEN_DEPTH  = 400;
	var STAR_SIZE = 3; 			//max width of stars
	var numStars = 100; 		//number of stars
	var fastStars = true; 		//render stars as squares
	var stars = new Array(); 	//packed array of star coordinates
	var speed = .1; 
	var heading = .1919;
	
	function createStars(){
		for (i = 0; i < numStars * 3; i = i + 3){
			stars[i] = Math.random()*SCREEN_WIDTH + 1;
			stars[i+1] = Math.random()*SCREEN_HEIGHT + 1;
			stars[i+2] = STAR_SIZE * (Math.random()*SCREEN_DEPTH) / SCREEN_DEPTH;
		}
	}
	
	createStars();
	
	return {
		setNumStars:function(){
			numStars = this.value;
			createStars();
		},setSpeed:function(){
			speed = this.value / 10;
		},setHeading:function(){
			heading = this.value * PI / 180;
		},toggleMode:function(){
			if (fastStars){
				fastStars = false; 
				this.value = "Render Square Stars"; 
			}else{
				fastStars = true; 
				this.value = "Render Circular Stars";
			}
		},render:function(){
			for (i =0 ; i < numStars * 3; i = i + 3){
				
				ctx.fillStyle = "#cac";
				if (fastStars){
					//draw stars as squares
					ctx.fillRect(stars[i],stars[i+1],stars[i+2],stars[i+2]);
				}else{
					//draw stars as circles
					ctx.beginPath();
					ctx.arc(stars[i], stars[i+1], stars[i+2],PI*2, 0,true); 
					ctx.closePath();
					ctx.fill();
				}
				
				//move stars
				var relspeed =  speed * stars[i+2] * stars[i+2]; 
				stars[i] += relspeed * Math.cos(heading); 
				stars[i+1] += relspeed * Math.sin(heading); 
				
				//wrap stars at edges
				if (stars[i] > SCREEN_WIDTH) stars[i] = 0;
				if (stars[i]< 0) stars[i] = SCREEN_WIDTH;
				if (stars[i+1] > SCREEN_HEIGHT) stars[i+1] = 0;
				if (stars[i+1]< 0) stars[i+1] = SCREEN_HEIGHT;
				
			}
		}
	}
}

/**
	by Dejapong (dejapong.com)
	10/30/10

	This object is used to display frames-per-second (fps) information. 
	
 	Parameters
		id: 		Id of element to print fps info to. 

 	Returns
 		tick(): 	Call this at render intervals. It will replace element's html with fps info 
 					once a second.
*/
function FPS(id){
	var sfr = 0;
	var frames = 0;
	var frtotal = 0;
	var frct = 0;
	var firstTime = true;
	return new function(){
		this.tick = function(){
			var timeNow = new Date()
			timeNow = timeNow.getTime();
			frames++;
			if (timeNow > sfr + 1000){
				if (firstTime){
					firstTime =false
					frames = 0;
					sfr = timeNow; 
				}else{
					frtotal = frtotal  + frames; 
					frct ++ ;
					sfr = timeNow; 
					document.getElementById(id).innerHTML = "Frames per second: " + frames + "<br> Average: " + Math.floor(frtotal / frct);
					frames = 0; 
				}
			}
		}
	}
}

/**
	by Dejapong (dejapong.com)
	10/30/10

	This object sets up a rendering canvas 
	
 	Parameters
 		id:			Id of the canvas element to render to
		width: 		Width of the rendering canvas
		height:		Height of the rendering canvas

 	Returns
 		ctx:		Reference to the canvas context
 		height:		Height of the rendering canvas
 		width:		Width of the rendering canvas
*/
function Canvas(id,width,height){
	var canvas = document.getElementById(id); 
	canvas.width = width;
	canvas.height = height;
	var ctx = canvas.getContext('2d'); 
	
	return {
		ctx:ctx,
		height:height,
		width:width
	}
}

function initStars(){
	var fps = FPS('fps');
	var c = Canvas('canvas',200,200);
	var s = Stars(c);
	setEvents(s);
	setInterval(function(){
		c.ctx.clearRect(0,0,200,200);
		s.render();
		fps.tick();
	},0);
}

function setEvents(s){
	document.getElementById("numStars").onchange = s.setNumStars;
	document.getElementById("speed").onchange = s.setSpeed;
	document.getElementById("heading").onchange = s.setHeading;
	document.getElementById("toggle").onclick = s.toggleMode;
}

initStars();
