var canvas;

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

var themes = [ [ "#10222B", "#95AB63", "#BDD684", "#E2F0D6", "#F6FFE0" ],
		[ "#362C2A", "#732420", "#BF734C", "#FAD9A0", "#736859" ],
		[ "#0D1114", "#102C2E", "#695F4C", "#EBBC5E", "#FFFBB8" ],
		[ "#2E2F38", "#FFD63E", "#FFB54B", "#E88638", "#8A221C" ],
		[ "#121212", "#E6F2DA", "#C9F24B", "#4D7B85", "#23383D" ],
		[ "#343F40", "#736751", "#F2D7B6", "#BFAC95", "#8C3F3F" ],
		[ "#000000", "#2D2B2A", "#561812", "#B81111", "#FFFFFF" ],
		[ "#333B3A", "#B4BD51", "#543B38", "#61594D", "#B8925A" ] ];
var theme;

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

var walls = [];
var wall_thickness = 200;
var wallsSetted = false;

var clicks = [];

var bodies, elements, text;

var createMode = false;
var destroyMode = false;

var isMouseDown = false;
var mouseJoint;
var mouseX = 0;
var mouseY = 0;

var PI2 = Math.PI * 2;

var timeOfLastTouch = 0;

var resetTimer = 0;

init();
play();

function init() 
{
	canvas = document.getElementById( 'canvas' );

	document.onmousedown = onDocumentMouseDown;
	document.onmouseup = onDocumentMouseUp;
	document.onmousemove = onDocumentMouseMove;
	document.ondblclick = onDocumentDoubleClick;
	$(window).bind('resize', function(e)
	{
		clearTimeout(resetTimer);
		resetTimer = setTimeout(reset, 500);
	});

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

	// init box2d
	
	worldAABB = new b2AABB();
	worldAABB.minVertex.Set( -200, -200 );
	worldAABB.maxVertex.Set( screen.width + 200, screen.height + 200 );
	//worldAABB.setMaxValues( (screen.width + screen.height) * new b2Vec2 (0, 0));

	world = new b2World( worldAABB, new b2Vec2( 0, 0 ), true );
	
	setWalls();
	reset();
}


function play() 
{
	setInterval( loop, 1000 / 40 );
}

function createHiggs(world, x, y) 
{
	var x = x;
	var y = y;

	var size = 1.0;

	var element = document.createElement("canvas");
	element.width = size;
	element.height = size;
	element.style['position'] = 'absolute';
	element.style['left'] = x + 'px';
	element.style['top'] = y + 'px';

//	var graphics = element.getContext("2d");

//	var num_circles = Math.random() * 10 >> 0;

	//for (var i = size; i > 0; i-= (size/num_circles)) {

	/*	graphics.fillStyle = '#fff';
		graphics.beginPath();
		graphics.arc(size * .5, size * .5, size * .5, 0, PI2, true); 
		graphics.closePath();
		graphics.fill();*/
//	}

	canvas.appendChild(element);

	elements.push( element );

	var b2body = new b2BodyDef();

	var circle = new b2CircleDef();
	circle.radius = size;
	circle.density = 2;
	circle.friction = 10;
	circle.restitution = 2;
	b2body.AddShape(circle);
	b2body.userData = {element: element};

	b2body.position.Set( x, y );
	b2body.linearVelocity.Set( Math.random() * 400 - 200, Math.random() * 400 - 200 );
	var b = world.CreateBody(b2body);
	bodies.push( b );
	
	return b;

	/*var ballSd = new b2CircleDef();
	ballSd.density = 2.0;
	ballSd.radius = 1;
	ballSd.restitution = 2;
	var ballBd = new b2BodyDef();
	ballBd.AddShape(ballSd);
	ballBd.position.Set(x,y);
	
	return world.CreateBody(ballBd);*/
};

function createInstructions(i, colorname) 
{
	var size = 155;
//	alert('do');
	clicks[i] = 0;
	
	var shadow = document.createElement( 'div' );
	shadow.width = size;
	shadow.height = size;	
	shadow.style.position = 'absolute';
	shadow.style.left = -200 + 'px';
	shadow.style.top = '87%';
	shadow.style.cursor = "default";
	shadow.style.textAlign = 'center';
	$(shadow).addClass('shadow');

	canvas.appendChild(shadow);
	elements.push( shadow );
	
	text = document.createElement( 'div' );
	text.onSelectStart = null;
	text.innerHTML = '<img src="/img/shadow.png" />';
	
	text.style.position = 'absolute';
	text.style.left = '0px';
	text.style.top = '0px';
	text.style.textAlign = 'center';
	shadow.appendChild(text);

	var element = document.createElement( 'div' );
	element.width = size;
	element.height = size;	
	element.style.position = 'absolute';
	element.style.left = -200 + 'px';
	//element.style.cursor = "pointer";
	element.style.top = 700 + 'px';
	element.style.cursor = "default";

	$(element).addClass('el_'+(i+1));
	
	canvas.appendChild(element);
	elements.push( element );

	var circle = document.createElement( 'canvas' );
	circle.width = size;
	circle.height = size;

	element.appendChild( circle );
	
	text = document.createElement( 'div' );
	text.onSelectStart = null;
	text.innerHTML = '<div class="ball '+colorname+'"></div>';
	
	text.style.position = 'absolute';
	text.style.left = '0px';
	text.style.top = '0px';
	text.style.textAlign = 'center';
	
	element.appendChild(text);
	
	

	var reflection = document.createElement( 'div' );
	reflection.width = size;
	reflection.height = size;	
	reflection.style.position = 'absolute';
	reflection.style.left = '0px';
	reflection.style.top ='0px';
	reflection.style.cursor = "pointer";
	$(reflection).addClass('reflection');
	
	canvas.appendChild(reflection);
	elements.push( reflection );

	var b2body = new b2BodyDef();

	var circle = new b2CircleDef();
	circle.radius = size / 2;
	circle.density = 0.2; 
	circle.friction = 0.01;
	circle.restitution = 0.4;

	b2body.AddShape(circle);
	b2body.userData = {element: element};

	b2body.position.Set( (stage[2] / 4 ) * (i + 1), stage[3] * 2 / 3);
//	b2body.linearVelocity.Set( Math.random() * 400 - 200, Math.random() * 400 - 200 );
	var b = world.CreateBody(b2body);
	bodies.push( b );
	b.WakeUp();
}

function shuffle(o)
{
	for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
	return o;
};

function reset() 
{
	var i;
	
	if ( bodies ) 
	{
		for ( i = 0; i < bodies.length; i++ ) 
		{
			var body = bodies[ i ];
			
			canvas.removeChild( body.GetUserData().element );
			
			for (var j = 0; j < 3; j++)
			{
				$(elements[i * 3 + j]).remove();
			}
			world.DestroyBody( body );
			body = null;
			
		}
	}

	bodies = [];
	elements = [];

	var colors = new Array('#ff0000', '#00ff00', '#0000ff');
	
	var names = new Array('r', 'g', 'b', 'p', 'o', 'm');
	
	//shuffle(names);
	
	for (i = 0; i < colors.length; i++)
	{
		createInstructions(i, names[i]);
		/*var num = Math.floor( Math.random( ) * names.length )
		
		if (names[num] != '0')
		{
			createInstructions(i, names[num]);
			names[num] = '0';
		}*/
	}
	
	var ball = createHiggs(world, mouseX, mouseY);
	
	var md = new b2MouseJointDef();
	
	md.body1 = world.m_groundBody;
	
	md.body2 = ball;
	md.target.Set(0, 0);
	md.maxForce = 3000000000000;
	md.timeStep = 1.0/60;
	mouseJoint = world.CreateJoint(md);
	ball.WakeUp();
}

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 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 = 350 + delta[1];
	
	mouseDrag();
	world.Step(timeStep, iterations);
	

	for (i = 0; i < bodies.length; i++) 
	{
		var body = bodies[i];
		
		for (j = 0; j < 3; j++)
		{
			var element = elements[i * 3 + j];

		//	alert( (body.m_position0.x - (element.width >> 1)) + 'px');
			
			element.style.left = (body.m_position0.x - (element.width >> 1)) + 'px';
			
			if ($(element).hasClass('shadow'))
			{
				//if ((body.m_position0.x > stage[2] / 2 - 232) && (body.m_position0.x < stage[2] / 2 + 232) && (body.m_position0.y < (stage[3] + 66) / 2 - 20) && (body.m_position0.y > (stage[3] + 66) / 2 - 20) + 26)
			//	{
				//	$(elements[i * 3].style.top = '48%');
				//	$(element).children('div').children('img').width(156 - (((stage[3] + wall_thickness)*0.24) - body.m_position0.y) * 0.2);
			//	}
			//	else
			//	{
				//	$(elements[i * 3].style.top = '87%');
					
			//	}
				$(element).children('div').children('img').width(156 - (((stage[3] + wall_thickness)*0.63) - body.m_position0.y) * 0.2);
			}
			else
			{
				element.style.top = (body.m_position0.y - (element.height >> 1)) + 'px';
			}
			
			if ($(element).hasClass('reflection'))
			{

			}
			
			if (element.tagName == 'DIV' && !$(element).hasClass('reflection') && !$(element).hasClass('shadow')) 
			{
				var rotationStyle = 'rotate(' + (body.m_rotation0 * 57.2957795) + 'deg)';
				element.style.WebkitTransform = rotationStyle;
				element.style.MozTransform = rotationStyle;
				element.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 = 50000;
	}
	
	boxSd.friction = 10;

	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)
	{
		var body = getBodyAtMouse();

		if (body) 
		{
			var str = $(body.m_userData.element).attr('class').substr(3);

			clicks[str]++;
			
			/*if (clicks[str] % 2 == 0)
			{
				$(body.m_userData.element).find('.ball').after('<div class="ball m"></div>');
				$(body.m_userData.element).find('.ball:first').fadeOut(250, function(e)
				{
					$(this).remove();
				});
				//alert($(body.m_userData.element).find('.ball').css('class'));
			}*/
			
			body.m_linearVelocity.Set((body.m_position0.x - mouseX) * 10, (body.m_position0.y - mouseY) * 15);
		}
	}
	
	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]);
		world.DestroyBody(walls[4]);

		walls[0] = null; 
		walls[1] = null;
		walls[2] = null;
		walls[3] = null;
		walls[4] = 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)*0.9, stage[2], wall_thickness *0.9); 
	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]);		
	walls[4] = createBox(world, (stage[2]) / 2 + 5, (stage[3] + 66) / 2 - 21, 486 / 2, 26); 
	
/*
	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;

}

