var initId = 0;
var world;
var ctx;
var canvasWidth;
var canvasHeight;
var canvasTop;
var canvasLeft;
var logoImage = new Image();
logoImage.src = "logotext.png";
var mouseBd;
var mouseJoint = null;
var allDotsVisible = false;

function createWorld() {
	var worldAABB = new b2AABB();
	worldAABB.minVertex.Set(-1000, -1000);
	worldAABB.maxVertex.Set(1000, 1000);
	var gravity = new b2Vec2(0, 1000);
	var doSleep = true;
	var world = new b2World(worldAABB, gravity, doSleep);
	createGround(world);
	return world;
}

function createGround(world) {
	var groundSd = new b2CircleDef();
	groundSd.radius = 350;
	groundSd.restitution = 0;
	var groundBd = new b2BodyDef();
	groundBd.userData = {
		name: 'ground'
	};
	groundBd.AddShape(groundSd);
	groundBd.position.Set(502, 800);
	return world.CreateBody(groundBd)
}

function createDot(world, options) {
	var dotSd = new b2CircleDef();
	dotSd.density = options.density || 1.0;
	dotSd.radius = options.radius || 2.5;
	dotSd.restitution = options.restitution || 0.3;
	var dotBd = new b2BodyDef();
	dotBd.userData = options.userData || null;
	dotBd.isSleeping = true;
	dotBd.AddShape(dotSd);
	dotBd.position.Set(options.x,options.y);
	return world.CreateBody(dotBd);
}

function createBox(world, x, y, width, height, fixed) {
	if (typeof(fixed) == 'undefined') fixed = true;
	var boxSd = new b2BoxDef();
	if (!fixed) boxSd.density = 1.0;
	boxSd.extents.Set(width, height);
	var boxBd = new b2BodyDef();
	boxBd.AddShape(boxSd);
	boxBd.position.Set(x,y);
	return world.CreateBody(boxBd)
}

function step(cnt) {
	var stepping = false;
	var timeStep = 1.0/60;
	var iteration = 1;
	world.Step(timeStep, iteration);
	ctx.clearRect(0, 0, canvasWidth, canvasHeight);
	drawWorld(world, ctx);
	setTimeout('step(' + (cnt || 0) + ')', 10);
}

function drawWorld(world, context) {
	for (var b = world.m_bodyList; b; b = b.m_next) {
		if ( b.GetUserData() == null ) {
			for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
				drawShape(s, context);
			}
		} else {
			var bodyName = b.GetUserData().name;
			if(bodyName == 'logo')
				drawLogo(b);
			
		}
	}
}

function drawShape(shape, context) {
	context.fillStyle = '#000000';
	context.beginPath();
	switch (shape.m_type) {
	case b2Shape.e_circleShape:
		var circle = shape;
		var pos = circle.m_position;
		var r = circle.m_radius;
		var segments = 16.0;
		var theta = 0.0;
		var dtheta = 2.0 * Math.PI / segments;
		// draw circle
		context.moveTo(pos.x + r, pos.y);
		for (var i = 0; i < segments; i++) {
			var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
			var v = b2Math.AddVV(pos, d);
			context.lineTo(v.x, v.y);
			theta += dtheta;
		}
		context.lineTo(pos.x + r, pos.y);

		// draw radius
		context.moveTo(pos.x, pos.y);
		var ax = circle.m_R.col1;
		var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
		context.lineTo(pos2.x, pos2.y);
		
		break;
	case b2Shape.e_polyShape:
		var poly = shape;
		var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
		context.moveTo(tV.x, tV.y);
		for (var i = 0; i < poly.m_vertexCount; i++) {
			var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
			context.lineTo(v.x, v.y);
		}
		context.lineTo(tV.x, tV.y);
		
		break;
	}
	context.fill();
}

function createLogo(x,y) {
	var logoSd = new b2CircleDef();
	logoSd.density = 0;
	logoSd.radius = 50;
	logoSd.restitution = 0.6;
	var logoBd = new b2BodyDef();
	logoBd.isSleeping = true;
	logoBd.userData = {
		name: 'logo'
	};
	logoBd.AddShape(logoSd);
	logoBd.position.Set(x+1,y);
	return world.CreateBody(logoBd);

}

function drawLogo(body) {
	ctx.drawImage(logoImage, body.m_position.x-59, body.m_position.y-52, 117, 99);	
}

function drawDots(xCentre, yCentre) {
	var radius = 120;
	var t;
	var i = 0;
	
	drawDot();
	
	function drawDot() {
		if(i < 64) {
			var theta = (360/64) * i;
			var xpos = xCentre + (radius * 0.7) * Math.sin(theta * Math.PI/180);
			var ypos = yCentre + radius * Math.cos(theta * Math.PI/180);
			createDot(world, {x: xpos, y: ypos});
			i++;
			t = setTimeout(drawDot, 20);
		} else {
			allDotsVisible = true;
			clearTimeout(t);
			setTimeout(function() {
				for (var b = world.m_bodyList; b; b = b.m_next) {
					b.WakeUp();
				}
				setTimeout(function() {
					if(typeof(console) != 'undefined')
						console.log("Fade to page")
				}, 5000);
			}, 1000);
		}
	}
	
}

Event.observe(window, 'load', function() {
	world = createWorld();
	ctx = $('canvas').getContext('2d');
	var canvasElm = $('canvas');
	canvasWidth = parseInt(canvasElm.width);
	canvasHeight = parseInt(canvasElm.height);
	createLogo(parseInt(canvasWidth / 2), 240);
	drawDots(parseInt(canvasWidth / 2), 240);
	var position = $(canvasElm).positionedOffset();
	canvasTop = parseInt(position[1]);
	canvasLeft = parseInt(position[0]);
	
	Event.observe('canvas', 'mousemove', function(e) {
		var xpos = Event.pointerX(e) - canvasLeft, ypos = Event.pointerY(e) - canvasTop;
		if(mouseJoint == null) {
			if(allDotsVisible) {
				mouseBd = createDot(world, {
					x: xpos, 
					y: ypos, 
					userData: {name:'mouse'}, 
					radius: 15,
					restitution: 0
				});
				var md = new b2MouseJointDef();
				md.body1 = world.GetGroundBody();
				md.body2 = mouseBd;
				md.target.Set(xpos, ypos);
				md.collideConnected = true;
				md.maxForce = 1000000 * mouseBd.GetMass();
				mouseJoint = world.CreateJoint(md);
			}
		} else {
			mouseJoint.SetTarget(new b2Vec2(xpos, ypos));
		}
	});
	
	step();
});
