
function Retro() {
	
	var stage = {x:0, y:0, width:0, height:0};
	var ball = {x:20, y:300, width:45, height:45, color:"rgb(0,102,153)", speed: {x:Math.random()*50, y:Math.random()*-50}};
	var physics = {gravity: 2, drag: 0.98, bounce: 0.9};
	
	var block = {x:780, y:220, width:50, height:50};
	var empty = {x:780, y:220, width:50, height:50};
	var mushroom = {x:780, y:250, width:50, height:50, speed: {x: -10, y: 0}};
	var mushroomPhysics = {gravity: 2, drag: 1, bounce: 0};
	
	var dragging = null;
	var last = {}, mouse = {};
	
	function setup() {
		setInterval(tick, 50);
		stage.context.drawImage(empty.img, empty.x, empty.y);
		stage.bitmap = stage.context.getImageData(0, 0, stage.width, stage.height);
		stage.context.drawImage(block.img, block.x, block.y);
		stage.element.onmousemove = null;
		stage.element.onmousedown = mouseDown;
		stage.element.onclick = click;
	}
	
	function tick(event) {
		
		if(mushroom.enabled) {
			patchItem(mushroom, stage.context);
			mushroom.x += mushroom.speed.x;
			mushroom.y += mushroom.speed.y;
			applyBoundingPhysics(mushroom, stage, mushroomPhysics);
			drawItem(mushroom, stage.context);
		}
		
		if(!dragging) {
			var patch = eraseBall(ball, stage.context);
			ball.x += ball.speed.x;
			ball.y += ball.speed.y;
			drawBall(ball, stage.context);
			applyBoundingPhysics(ball, stage, physics);
			if(!mushroom.enabled && !ball.big && 
			   (ball.x+ball.width > block.x && ball.x < block.x+block.width) &&
			   (ball.y < block.y+block.height && ball.y+ball.height > block.y)) {
				block.sound.play();
				mushroom.enabled = true;
				patchItem(block, stage.context);
			}
			if(!ball.big && mushroom.y == stage.height-mushroom.height && 
			   (ball.x+ball.width > mushroom.x && ball.x < mushroom.x+mushroom.width) &&
			   (ball.y < mushroom.y+mushroom.height && ball.y+ball.height > mushroom.y)) {
				mushroom.sound.play();
				ball.big = true;
				ball.width = ball.height = 60;
				ball.color = "rgb(255, 0, 0)";
				mushroom.enabled = false;
				patchItem(mushroom, stage.context);
				ball.y -= 20;
			}
		} else {
			var patch = patchItem(ball, stage.context);
			ball.x = mouse.x-ball.width/2;
			ball.y = mouse.y-ball.height/2;
			drawBall(ball, stage.context);
			ball.speed.x = mouse.x - last.x;
			ball.speed.y = mouse.y - last.y;
			last.x = mouse.x;
			last.y = mouse.y;
		}
		
	}
	
	function applyBoundingPhysics(item, box, physics) {
		if(item.x < 0) {
			item.x = 0;
			item.speed.x *= -1;
		}
		if(item.y < 0) {
			item.y = 0;
			item.speed.y *= physics.bounce * -1;
		}
		if(item.x+item.width > box.width) {
			item.x = box.width - item.width;
			item.speed.x *= -1;
		}
		if(item.y+item.height > box.height) {
			item.y = box.height - item.height;
			item.speed.y *= physics.bounce * -1;
		}
		item.speed.x = item.speed.x * physics.drag;
		item.speed.y = item.speed.y * physics.drag + physics.gravity;
	}
	
	function mouseDown(event) {
		getMouse(event, mouse);
		if(mouse.x > ball.x && mouse.x < ball.x+ball.width &&
		   mouse.y > ball.y && mouse.y < ball.y+ball.height) {
			dragging = ball;
			stage.element.onmousemove = mouseMove;
			stage.element.onmouseup = mouseUp;
			getMouse(event, last);
		}
	}
	
	function mouseMove(event) {
		getMouse(event, mouse);
	}
	
	function mouseUp(event) {
		document.onmousemove = null;
		document.onmouseup = null;
		dragging = null;
	}
	
	function click(event) {
		getMouse(event, mouse);
		if(!mushroom.enabled && !ball.big && 
		   (mouse.x > block.x && mouse.x < block.x+block.width) &&
		   (mouse.y < block.y+block.height && mouse.y > block.y)) {
			mushroom.sound.play();
			mushroom.enabled = true;
			patchItem(block, stage.context);
		}
	}
	
	function getMouse(event, object) {
		if(event.offsetX) {
			object.x = event.offsetX;
			object.y = event.offsetY;
		} else if(event.layerX) {
			object.x = event.layerX;
			object.y = event.layerY;
		}
		return object;
	}
	
	function eraseBall(ball, context) {
		
		var pad = ball.big ? 6 : 0;
		var px = Math.round(ball.x)-pad;
		var py = Math.round(ball.y)-pad;
		var pw = Math.round(ball.width)+pad*2;
		var ph = Math.round(ball.height)+pad*2;
		
		px = Math.max(px, 0);
                py = Math.max(py, 0);
                pw -= Math.max(px+pw-stage.width, 0);
                ph -= Math.max(py+ph-stage.height, 0);
		var w2 = pw/2;
                var h2 = ph/2;
		
		var i = 0;
		var quads = {};
		var data = stage.bitmap;
		var patch = context.getImageData(px, py, pw, ph);
		for(var y = 0; y < ph; y++) {
			var di = ((py+y)*stage.width + px) * 4;
			for(var x = 0; x < pw; x++) {
				// physics based on quads
				if(data.data[di] > 0) {
					if(x < w2 && y < h2) { quads.q1 = true; }
					if(x > w2 && y < h2) { quads.q2 = true; }
					if(x < w2 && y > h2) { quads.q3 = true; }
					if(x > w2 && y > h2) { quads.q4 = true; }
				}
				if(ball.x < 710 && ball.big) {// img specific # here
					patch.data[i++] = data.data[di++] = 0;
					patch.data[i++] = data.data[di++] = 0;
					patch.data[i++] = data.data[di++] = 0;
					patch.data[i++] = data.data[di++] = 255;
				} else {
					patch.data[i++] = data.data[di++];// = 0;
					patch.data[i++] = data.data[di++];// = 0;
					patch.data[i++] = data.data[di++];// = 0;
					patch.data[i++] = data.data[di++];// = 255;
				}
			}
		}
		applyQuadPhysics(ball, quads, physics);
		context.putImageData(patch, px, py);
		return patch;
	}
	
	function applyQuadPhysics(item, quads, physics) {
		var changed = false;
		if((item.speed.x > 0 && quads.q2 && quads.q4) ||
		   (item.speed.x < 0 && quads.q1 && quads.q3)) {
			item.speed.x *= physics.bounce * -1;
			item.x += item.speed.x;
			changed = true;
		}
		if((item.speed.y < 0 && (quads.q1 || quads.q2)) ||
		   (item.speed.y > 0 && (quads.q3 || quads.q4))) {
			item.speed.y *= physics.bounce * -1;
			item.y += item.speed.y;
			changed = true;
		}
		if(changed && ball.big && ball.x < 710) {
			ball.sound.play();
		} else if(changed && ball.big && ball.x > 710) {
			empty.sound.play();
		}
	}
	
	function patchItem(item, context) {
		var px = Math.round(item.x);
		var py = Math.round(item.y);
		var pw = item.width;
		var ph = item.height;

		px = Math.max(px, 0);
		py = Math.max(py, 0);
		pw -= Math.max(px+pw-stage.width, 0);
		ph -= Math.max(py+ph-stage.height, 0);

		var i = 0;
		var data = stage.bitmap;
		var patch = context.getImageData(px, py, pw, ph);
		for(var y = 0; y < ph; y++) {
			var di = ((py+y)*stage.width + px) * 4;
			for(var x = 0; x < pw; x++) {
				patch.data[i++] = data.data[di++];
				patch.data[i++] = data.data[di++];
				patch.data[i++] = data.data[di++];
				patch.data[i++] = data.data[di++];
			}
		}
		context.putImageData(patch, px, py);
		return patch;
	}
	
	function drawItem(item, context) {
		context.drawImage(item.img, item.x, item.y);
	}
	
	function drawBall(ball, context) {
		context.lineWidth = 3;
		context.fillStyle = ball.color;
		context.strokeStyle = "rgb(255,255,255)";
		context.beginPath();
		context.arc(ball.x+ball.width/2,ball.y+ball.height/2,(ball.width-6)/2,0,Math.PI*2,true);
		context.fill();
		context.stroke();
	}
	
	function imageLoaded(event) {
		stage.element = document.getElementById("logo");
		stage.context = stage.element.getContext("2d");
		stage.width = parseInt(stage.element.getAttribute("width"));
		stage.height = parseInt(stage.element.getAttribute("height"));
		stage.context.drawImage(stage.img, 0, 0);
		updateLoaded(event);
	}
	
	function updateLoaded(event) {
		event.target.loaded = true;
		if(stage.img.loaded && block.img.loaded && empty.img.loaded) {
			stage.element.onmousemove = setup;
		}
	}
	
	function loadImages() {
		stage.img = new Image();
		stage.img.onload = imageLoaded;
		stage.img.src = "http://digitalanalog.com/images/linux_promo.png";
		block.img = new Image();
		block.img.onload = updateLoaded;
		block.img.src = "http://digitalanalog.com/images/block.png";
		empty.img = new Image();
		empty.img.onload = updateLoaded;
		empty.img.src = "http://digitalanalog.com/images/empty_block.png";
		mushroom.img = new Image();
		mushroom.img.src = "http://digitalanalog.com/images/mushroom.png";
		// load sounds too
		block.sound = new Audio("http://digitalanalog.com/audio/power_block.mp3");
		empty.sound = new Audio("http://digitalanalog.com/audio/empty_block.mp3");
		mushroom.sound = new Audio("http://digitalanalog.com/audio/power_up.mp3");
		ball.sound = new Audio("http://digitalanalog.com/audio/break.mp3");
	}
	
	this.load = function() {
		//$("#imageContainer img").hide();
		//$("#imageContainer").append('<canvas id="logo" width="950" height="410" style="cursor: crosshair;"></canvas>');
		loadImages();
		return false;
	}
}

var retro = new Retro();

