var canvas;

var delta = [0,0];
var stage = [window.screenX,window.screenY,window.innerWidth,window.innerHeight];
getBrowserDimensions();

gravity = 100;

var worldAABB, world, iterations = 1, timeStep = 1 / 20;

var walls = new Array();
var wall_thickness = 100;
var wallsSetted = false;

var bodies, elements;
var text = new Array();

var createMode = false;
var destroyMode = false;

var isMouseDown = false;
var mouseJoint;
var mouseX = 0;
var mouseY = 0;
const PI2 = Math.PI * 2;

var timeOfLastTouch = 0;

init();
play();

function init() {

	canvas = document.getElementById('canvas');

	document.onmousedown = onDocumentMouseDown;
	document.onmouseup = onDocumentMouseUp;
	document.onmousemove = onDocumentMouseMove;
	document.ondblclick = onDocumentDoubleClick;
	//document.onselectstart = function() {return false;} // ie

	document.addEventListener('touchstart', onDocumentTouchStart, false);
	document.addEventListener('touchmove', onDocumentTouchMove, false);
	document.addEventListener('touchend', onDocumentTouchEnd, false);

	// init box2d

	worldAABB = new b2AABB();
	worldAABB.minVertex.Set(-wall_thickness,-wall_thickness);
	worldAABB.maxVertex.Set(screen.width + wall_thickness, screen.height + wall_thickness);

	world = new b2World(worldAABB, new b2Vec2(0,20.0), true);

	setWalls();

	reset();
        //obstacle = createBox(world, stage[2]/2, stage[3] / 2, stage[2]/6, stage[3]/6);
        createBall('Ldot.png');
        createBall('Fdot.png');
        createBall('Ddot.png');
}


function play() {

	setInterval(loop, 25);
}

function reset() {

	if (bodies) {

		for (i = 0; i < bodies.length; i++) {

			var body = bodies[i]
			canvas.removeChild( body.GetUserData().element );
			world.DestroyBody(body);
			body = null;
		}
	}


	bodies = new Array();
	elements = new Array();

}

//

function onDocumentMouseDown() {

	isMouseDown = true;
	return false;
}

function onDocumentMouseUp() {

	isMouseDown = false;
	return false;
}

function onDocumentMouseMove(event) {

	mouseX = event.clientX;
	mouseY = event.clientY;
}

function onDocumentDoubleClick() {

	reset();
}

function onDocumentTouchStart( event ) {

	if(event.touches.length == 1) {

		event.preventDefault();

		// Faking double click for touch devices

		var now = new Date().getTime();

		if (now - timeOfLastTouch  < 250) {

			reset();
			return;
		}

		timeOfLastTouch = now;

		mouseX = event.touches[0].pageX;
		mouseY = event.touches[0].pageY;
		isMouseDown = true;
	}
}

function onDocumentTouchMove( event ) {

	if(event.touches.length == 1) {

		event.preventDefault();

		mouseX = event.touches[0].pageX;
		mouseY = event.touches[0].pageY;
	}
}

function onDocumentTouchEnd( event ) {

	if(event.touches.length == 0) {

		event.preventDefault();
		isMouseDown = false;
	}
}

function createBall(imname) {

        var size = 115;
	var element = document.createElement("div");
	element.width = size;
	element.height = size;
	element.style['position'] = 'absolute';
	element.style['left'] = -wall_thickness + 'px';
	element.style['top'] = -wall_thickness + 'px';
	element.style.cursor = "default";

	t = document.createElement('div');
	t.onSelectStart = null;
	t.innerHTML = '<img src="images/'+imname+'">';
	t.style.position = 'absolute';
	t.style.left = '0px';
	t.style.top = '0px';
	t.style.zIndex = '300';
	element.appendChild(t);
        text.push(t);

	canvas.appendChild(element);
	elements.push( element );

	var b2body = new b2BodyDef();
	var bcircle = new b2CircleDef();
	bcircle.radius = size/2;
	bcircle.density = 1;
	bcircle.friction = 0.5;
	bcircle.restitution = 0.5;
//        massData.center.Set(0.0, 0.0);
	b2body.AddShape(bcircle);
	b2body.userData = {element: element};

	b2body.position.Set( Math.random() * stage[2], Math.random() * -wall_thickness );
	b2body.linearVelocity.Set( Math.random() * 200 - wall_thickness,
                                   Math.random() * 200 - wall_thickness );
	bodies.push( world.CreateBody(b2body) );
}

//

function loop() {

	if (getBrowserDimensions())
		setWalls();

	delta[0] += (0 - delta[0]) * .5;
	delta[1] += (0 - delta[1]) * .5;

	world.m_gravity.x = 0 + delta[0];
	world.m_gravity.y = gravity + delta[1];

	mouseDrag();
	world.Step(timeStep, iterations);

	for (i = 0; i < bodies.length; i++) {

		var body = bodies[i];
		var element = elements[i];
                var t = text[i];

		element.style.left = (body.m_position0.x - (element.width >> 1)) + 'px';
		element.style.top = (body.m_position0.y - (element.height >> 1)) + 'px';

		var rotationStyle = 'rotate(' + (body.m_rotation0 * 57.2957795) + 'deg)';
                t.style.WebkitTransform = rotationStyle;
                t.style.MozTransform = rotationStyle;
                t.style.OTransform = rotationStyle;
	}
}


// .. BOX2D UTILS

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 mouseDrag()
{
	if (isMouseDown && !mouseJoint) {

		var body = getBodyAtMouse();

		if (body) {

			var md = new b2MouseJointDef();
			md.body1 = world.m_groundBody;
			md.body2 = body;
			md.target.Set(mouseX, mouseY);
			md.maxForce = 30000 * body.m_mass;
			md.timeStep = timeStep;
			mouseJoint = world.CreateJoint(md);
			body.WakeUp();

		} else {

			createMode = true;
		}
	}

	// mouse release
	if (!isMouseDown) {

		createMode = false;
		destroyMode = false;

		if (mouseJoint) {

			world.DestroyJoint(mouseJoint);
			mouseJoint = null;
		}
	}

	// mouse move
	if (mouseJoint) {

		var p2 = new b2Vec2(mouseX, mouseY);
		mouseJoint.SetTarget(p2);
	}
}

function getBodyAtMouse() {

	// Make a small box.
	var mousePVec = new b2Vec2();
	mousePVec.Set(mouseX, mouseY);

	var aabb = new b2AABB();
	aabb.minVertex.Set(mouseX - 1, mouseY - 1);
	aabb.maxVertex.Set(mouseX + 1, mouseY + 1);

	// Query the world for overlapping shapes.
	var k_maxCount = 10;
	var shapes = new Array();
	var count = world.Query(aabb, shapes, k_maxCount);
	var body = null;

	for (var i = 0; i < count; ++i) {

		if (shapes[i].m_body.IsStatic() == false) {

			if ( shapes[i].TestPoint(mousePVec) ) {

				body = shapes[i].m_body;
				break;
			}
		}
	}
	return body;
}

function setWalls() {

	if (wallsSetted) {

		world.DestroyBody(walls[0]);
		world.DestroyBody(walls[1]);
		world.DestroyBody(walls[2]);
		world.DestroyBody(walls[3]);

		walls[0] = null;
		walls[1] = null;
		walls[2] = null;
		walls[3] = null;
	}

	walls[0] = createBox(world, stage[2] / 2, - wall_thickness, stage[2], wall_thickness);
	walls[1] = createBox(world, stage[2] / 2, stage[3] + wall_thickness, stage[2], wall_thickness);
	walls[2] = createBox(world, - wall_thickness, stage[3] / 2, wall_thickness, stage[3]);
	walls[3] = createBox(world, stage[2] + wall_thickness, stage[3] / 2, wall_thickness, stage[3]);

	wallsSetted = true;
}

// BROWSER DIMENSIONS

function getBrowserDimensions() {

	var changed = false;

	if (stage[0] != window.screenX) {

		delta[0] = (window.screenX - stage[0]) * 50;
		stage[0] = window.screenX;
		changed = true;
	}

	if (stage[1] != window.screenY) {

		delta[1] = (window.screenY - stage[1]) * 50;
		stage[1] = window.screenY;
		changed = true;
	}

	if (stage[2] != window.innerWidth) {

		stage[2] = window.innerWidth;
		changed = true;
	}

	if (stage[3] != window.innerHeight) {

		stage[3] = window.innerHeight;
		changed = true;
	}

	return changed;
}
