$(function() {
	var canvas = $("#c");
	var canvasHeight;
	var canvasWidth;
	var ctx;
	var dt = 0.1;
	
	var pointCollection;
	
	function init() {
		updateCanvasDimensions();
		
		var g = [new Point(2, 2, 0.0, 7, "#008020"),new Point(2, 19, 0.0, 9, "#008020"),new Point(4, 37, 0.0, 9, "#008020"),new Point(4, 55, 0.0, 10, "#008020"),new Point(5, 73, 0.0, 9, "#008020"),new Point(17, 11, 0.0, 8, "#008020"),new Point(33, 6, 0.0, 8, "#008020"),new Point(50, 14, 0.0, 9, "#008020"),new Point(54,31, 0.0, 9, "#008020"),new Point(54, 50, 0.0, 9, "#008020"),new Point(54, 69, 0.0, 10, "#008020"),new Point(80, 48, 0.0, 9, "#ff8060"),new Point(84, 30, 0.0, 8, "#ff8060"),new Point(95, 20, 0.0, 7, "#ff8060"),new Point(110, 17, 0.0, 7, "#ff8060"),new Point(125, 23, 0.0, 7, "#ff8060"),new Point(132, 38, 0.0, 7, "#ff8060"),new Point(117, 42, 0.0, 7, "#ff8060"),new Point(99, 45, 0.0, 8, "#ff8060"),new Point(85, 65, 0.0, 8, "#ff8060"),new Point(100, 73, 0.0, 8, "#ff8060"),new Point(115, 73, 0.0, 7, "#ff8060"),new Point(130, 69, 0.0, 7, "#ff8060"),new Point(137, 60, 0.0, 4, "#ff8060"),new Point(505, 48, 0.0, 9, "#ff8060"),new Point(159+350, 30, 0.0, 8, "#ff8060"),new Point(170+350, 20, 0.0, 7, "#ff8060"),new Point(185+350, 17, 0.0, 7, "#ff8060"),new Point(200+350, 23, 0.0, 7, "#ff8060"),new Point(207+350, 38, 0.0, 7, "#ff8060"),new Point(192+350, 42, 0.0, 7, "#ff8060"),new Point(174+350, 45, 0.0, 8, "#ff8060"),new Point(160+350, 65, 0.0, 8, "#ff8060"),new Point(175+350, 73, 0.0, 8, "#ff8060"),new Point(190+350, 73, 0.0, 7, "#ff8060"),new Point(205+350, 69, 0.0, 7, "#ff8060"),new Point(212+350, 60, 0.0, 4, "#ff8060"),new Point(148, 12, 0.0, 8, "#ffc060"),new Point(153, 28, 0.0, 8, "#ffc060"),new Point(155, 44, 0.0, 8, "#ffc060"),new Point(159, 60, 0.0, 8, "#ffc060"),new Point(163, 73, 0.0, 6, "#ffc060"),new Point(170, 50, 0.0, 6, "#ffc060"),new Point(176, 40, 0.0, 6, "#ffc060"),new Point(183, 50, 0.0, 6, "#ffc060"),new Point(190, 62, 0.0, 7, "#ffc060"),new Point(197, 48, 0.0, 7, "#ffc060"),new Point(200, 33, 0.0, 8, "#ffc060"),new Point(202, 16, 0.0, 8, "#ffc060"),new Point(260, 16, 0.0, 8, "#ff0000"),new Point(244, 22, 0.0, 8, "#ff0000"),new Point(232, 29, 0.0, 6, "#ff0000"),new Point(223, 38, 0.0, 5, "#ff0000"),new Point(220, 50, 0.0, 6, "#ff0000"),new Point(223, 63, 0.0, 6, "#ff0000"),new Point(233, 71, 0.0, 7, "#ff0000"),new Point(247, 73, 0.0, 7, "#ff0000"),new Point(263, 70, 0.0, 8, "#ff0000"),new Point(290, 20, 0.0, 6, "#ffc060"),new Point(284, 33, 0.0, 7, "#ffc060"),new Point(285, 50, 0.0, 8, "#ffc060"),new Point(290, 65, 0.0, 7, "#ffc060"),new Point(305, 68, 0.0, 7, "#ffc060"),new Point(317, 59, 0.0, 6, "#ffc060"),new Point(323, 46, 0.0, 7, "#ffc060"),new Point(321, 30, 0.0, 7, "#ffc060"),new Point(302, 15, 0.0, 7, "#ffc060"),new Point(315, 18, 0.0, 6, "#ffc060"),new Point(328, 71, 0.0, 6, "#ffc060"),new Point(327, 61, 0.0, 4, "#ffc060"),new Point(317, 69, 0.0, 4, "#ffc060"),new Point(344, 29, 0.0, 7, "#0000ff"),new Point(354, 18, 0.0, 7, "#0000ff"),new Point(367, 12, 0.0, 7, "#0000ff"),new Point(381, 15, 0.0, 7, "#0000ff"),new Point(349, 37, 0.0, 6, "#0000ff"),new Point(362, 40, 0.0, 7, "#0000ff"),new Point(376, 44, 0.0, 7, "#0000ff"),new Point(384, 55, 0.0, 6, "#0000ff"),new Point(378, 67, 0.0, 7, "#0000ff"),new Point(365, 72, 0.0, 7, "#0000ff"),new Point(350, 68, 0.0, 8, "#0000ff"),new Point(343, 56, 0.0, 5, "#0000ff"),new Point(344-342, 29+100, 0.0, 7, "#0000ff"),new Point(354-342, 18+100, 0.0, 7, "#0000ff"),new Point(367-342, 12+100, 0.0, 7, "#0000ff"),new Point(381-342, 15+100, 0.0, 7, "#0000ff"),new Point(349-342, 37+100, 0.0, 6, "#0000ff"),new Point(362-342, 40+100, 0.0, 7, "#0000ff"),new Point(376-342, 44+100, 0.0, 7, "#0000ff"),new Point(384-342, 55+100, 0.0, 6, "#0000ff"),new Point(378-342, 67+100, 0.0, 7, "#0000ff"),new Point(365-342, 72+100, 0.0, 7, "#0000ff"),new Point(350-342, 68+100, 0.0, 8, "#0000ff"),new Point(343-342, 56+100, 0.0, 5, "#0000ff"),new Point(148-85, 12+100, 0.0, 8, "#ffc060"),new Point(153-85, 28+100, 0.0, 8, "#ffc060"),new Point(155-85, 44+100, 0.0, 8, "#ffc060"),new Point(159-85, 60+100, 0.0, 8, "#ffc060"),new Point(163-85, 73+100, 0.0, 6, "#ffc060"),new Point(170-85, 50+100, 0.0, 6, "#ffc060"),new Point(176-85, 40+100, 0.0, 6, "#ffc060"),new Point(183-85, 50+100, 0.0, 6, "#ffc060"),new Point(190-85, 62+100, 0.0, 7, "#ffc060"),new Point(197-85, 48+100, 0.0, 7, "#ffc060"),new Point(200-85, 33+100, 0.0, 8, "#ffc060"),new Point(202-85, 16+100, 0.0, 8, "#ffc060"),new Point(2+160, 2+100, 0.0, 7, "#008020"),new Point(2+160, 19+100, 0.0, 9, "#008020"),new Point(4+160, 37+100, 0.0, 9, "#008020"),new Point(4+160, 55+100, 0.0, 10, "#008020"),new Point(5+160, 73+100, 0.0, 9, "#008020"),new Point(17+160, 11+100, 0.0, 8, "#008020"),new Point(33+160, 6+100, 0.0, 8, "#008020"),new Point(50+160, 14+100, 0.0, 9, "#008020"),new Point(54+160,31+100, 0.0, 9, "#008020"),new Point(54+160, 50+100, 0.0, 9, "#008020"),new Point(54+160, 69+100, 0.0, 10, "#008020"),new Point(2+460, 2+100, 0.0, 7, "#008020"),new Point(2+460, 19+100, 0.0, 9, "#008020"),new Point(4+460, 37+100, 0.0, 9, "#008020"),new Point(4+460, 55+100, 0.0, 10, "#008020"),new Point(5+460, 73+100, 0.0, 9, "#008020"),new Point(17+460, 11+100, 0.0, 8, "#008020"),new Point(33+460, 6+100, 0.0, 8, "#008020"),new Point(50+460, 14+100, 0.0, 9, "#008020"),new Point(54+460,31+100, 0.0, 9, "#008020"),new Point(54+460, 50+100, 0.0, 9, "#008020"),new Point(54+460, 69+100, 0.0, 10, "#008020"),new Point(2+135, 2+108, 0.0, 9, "#8060c0"),new Point(2+136, 19+110, 0.0, 7, "#8060c0"),new Point(4+135, 37+106, 0.0, 7, "#8060c0"),new Point(4+135, 55+102, 0.0, 7, "#8060c0"),new Point(5+135, 73+99, 0.0, 8, "#8060c0"),new Point(2+135+300, 2+108, 0.0, 9, "#8060c0"),new Point(2+136+300, 19+110, 0.0, 7, "#8060c0"),new Point(4+135+300, 37+106, 0.0, 7, "#8060c0"),new Point(4+135+300, 55+102, 0.0, 7, "#8060c0"),new Point(5+135+300, 73+99, 0.0, 8, "#8060c0"),new Point(405, 20, 0.0, 8, "#ffff20"),new Point(421, 22, 0.0, 7, "#ffff20"),new Point(437, 24, 0.0, 8, "#ffff20"),new Point(454, 25, 0.0, 7, "#ffff20"),new Point(430, 9, 0.0, 7, "#ffff20"),new Point(429, -7, 0.0, 8, "#ffff20"),new Point(427, 38, 0.0, 8, "#ffff20"),new Point(424, 53, 0.0, 7, "#ffff20"),new Point(425, 68, 0.0, 7, "#ffff20"),new Point(438, 73, 0.0, 6, "#ffff20"),new Point(450, 64, 0.0, 8, "#ffff20"),new Point(480, 70, 0.0, 8, "#8000a0"),new Point(478, 60, 0.0, 7, "#8000a0"),new Point(477, 50, 0.0, 6, "#8000a0"),new Point(477, 38, 0.0, 7, "#8000a0"),new Point(476, 24, 0.0, 7, "#8000a0"),new Point(477, 10, 0.0, 7, "#8000a0"),new Point(475, -5, 0.0, 8, "#8000a0"),new Point(250, 115, 0.0, 8, "#ff0000"),new Point(237, 125, 0.0, 8, "#ff0000"),new Point(237, 125, 0.0, 8, "#ff0000"),new Point(234, 141, 0.0, 7, "#ff0000"),new Point(237, 156, 0.0, 7, "#ff0000"),new Point(248, 168, 0.0, 8, "#ff0000"),new Point(264, 168, 0.0, 7, "#ff0000"),new Point(273, 157, 0.0, 7, "#ff0000"),new Point(276, 141, 0.0, 8, "#ff0000"),new Point(276, 125, 0.0, 7, "#ff0000"),new Point(266, 113, 0.0, 8, "#ff0000"),new Point(275, 178, 0.0, 7, "#ff0000"),new Point(277, 194, 0.0, 8, "#ff0000"),new Point(272, 209, 0.0, 7, "#ff0000"),new Point(261, 218, 0.0, 7, "#ff0000"),new Point(246, 219, 0.0, 7, "#ff0000"),new Point(231, 214, 0.0, 8, "#ff0000"),new Point(227, 200, 0.0, 6, "#ff0000"),new Point(276, 167, 0.0, 4, "#ff0000"),new Point(280, 113, 0.0, 5, "#ff0000"),new Point(250+300, 115, 0.0, 8, "#ff0000"),new Point(237, 125, 0.0, 8, "#ff0000"),new Point(237+300, 125, 0.0, 8, "#ff0000"),new Point(234+300, 141, 0.0, 7, "#ff0000"),new Point(237+300, 156, 0.0, 7, "#ff0000"),new Point(248+300, 168, 0.0, 8, "#ff0000"),new Point(264+300, 168, 0.0, 7, "#ff0000"),new Point(273+300, 157, 0.0, 7, "#ff0000"),new Point(276+300, 141, 0.0, 8, "#ff0000"),new Point(276+300, 125, 0.0, 7, "#ff0000"),new Point(266+300, 113, 0.0, 8, "#ff0000"),new Point(275+300, 178, 0.0, 7, "#ff0000"),new Point(277+300, 194, 0.0, 8, "#ff0000"),new Point(272+300, 209, 0.0, 7, "#ff0000"),new Point(261+300, 218, 0.0, 7, "#ff0000"),new Point(246+300, 219, 0.0, 7, "#ff0000"),new Point(231+300, 214, 0.0, 8, "#ff0000"),new Point(227+300, 200, 0.0, 6, "#ff0000"),new Point(276+300, 167, 0.0, 4, "#ff0000"),new Point(280+300, 113, 0.0, 5, "#ff0000"),new Point(405-100, 20+100, 0.0, 8, "#ffff20"),new Point(421-100, 22+100, 0.0, 7, "#ffff20"),new Point(437-100, 24+100, 0.0, 8, "#ffff20"),new Point(454-100, 25+100, 0.0, 7, "#ffff20"),new Point(430-100, 9+100, 0.0, 7, "#ffff20"),new Point(429-100, -7+100, 0.0, 8, "#ffff20"),new Point(427-100, 38+100, 0.0, 8, "#ffff20"),new Point(424-100, 53+100, 0.0, 7, "#ffff20"),new Point(425-100, 68+100, 0.0, 7, "#ffff20"),new Point(438-100, 73+100, 0.0, 6, "#ffff20"),new Point(450-100, 64+100, 0.0, 8, "#ffff20"),new Point(377, 170, 0.0, 8, "#60a000"),new Point(377, 154, 0.0, 7, "#60a000"),new Point(376, 140, 0.0, 7, "#60a000"),new Point(375, 125, 0.0, 7, "#60a000"),new Point(374, 109, 0.0, 8, "#60a000"),new Point(373, 94, 0.0, 6, "#60a000"),new Point(388, 132, 0.0, 6, "#60a000"),new Point(401, 128, 0.0, 7, "#60a000"),new Point(415, 132, 0.0, 7, "#60a000"),new Point(420, 145, 0.0, 6, "#60a000"),new Point(420, 157, 0.0, 6, "#60a000"),new Point(420, 171, 0.0, 7, "#60a000")];
		
		gLength = g.length;
		for (var i = 0; i < gLength; i++) {
			g[i].curPos.x = (canvasWidth/2 - 180) + g[i].curPos.x;
			g[i].curPos.y = (canvasHeight/2 - 65) + g[i].curPos.y;
			
			g[i].originalPos.x = (canvasWidth/2 - 180) + g[i].originalPos.x;
			g[i].originalPos.y = (canvasHeight/2 - 65) + g[i].originalPos.y;
		};
		
		pointCollection = new PointCollection();
		pointCollection.points = g;
		
		initEventListeners();
		timeout();
	};
	
	function initEventListeners() {
		$(window).bind('resize', updateCanvasDimensions).bind('mousemove', onMove);
	};
	
	function updateCanvasDimensions() {
		canvas.attr({height: $(window).height(), width: $(window).width()});
		canvasWidth = canvas.width();
		canvasHeight = canvas.height();

		draw();
	};
	
	function onMove(e) {
		if (pointCollection)
			pointCollection.mousePos.set(e.pageX, e.pageY);
	};
	
	function timeout() {
		draw();
		update();
		
		setTimeout(function() { timeout() }, 30);
	};
	
	function draw() {
		var tmpCanvas = canvas.get(0);

		if (tmpCanvas.getContext == null) {
			return; 
		};
		
		ctx = tmpCanvas.getContext('2d');
		ctx.clearRect(0, 0, canvasWidth, canvasHeight);
		
		if (pointCollection)
			pointCollection.draw();
	};
	
	function update() {		
		if (pointCollection)
			pointCollection.update();
	};
	
	function Vector(x, y, z) {
		this.x = x;
		this.y = y;
		this.z = z;
 
		this.addX = function(x) {
			this.x += x;
		};
		
		this.addY = function(y) {
			this.y += y;
		};
		
		this.addZ = function(z) {
			this.z += z;
		};
 
		this.set = function(x, y, z) {
			this.x = x; 
			this.y = y;
			this.z = z;
		};
	};
	
	function PointCollection() {
		this.mousePos = new Vector(0, 0);
		this.points = new Array();
		
		this.newPoint = function(x, y, z) {
			var point = new Point(x, y, z);
			this.points.push(point);
			return point;
		};
		
		this.update = function() {		
			var pointsLength = this.points.length;
			
			for (var i = 0; i < pointsLength; i++) {
				var point = this.points[i];
				
				if (point == null)
					continue;
				
				var dx = this.mousePos.x - point.curPos.x;
				var dy = this.mousePos.y - point.curPos.y;
				var dd = (dx * dx) + (dy * dy);
				var d = Math.sqrt(dd);
				
				if (d < 150) {
					point.targetPos.x = (this.mousePos.x < point.curPos.x) ? point.curPos.x - dx : point.curPos.x - dx;
					point.targetPos.y = (this.mousePos.y < point.curPos.y) ? point.curPos.y - dy : point.curPos.y - dy;
				} else {
					point.targetPos.x = point.originalPos.x;
					point.targetPos.y = point.originalPos.y;
				};
				
				point.update();
			};
		};
		
		this.draw = function() {
			var pointsLength = this.points.length;
			for (var i = 0; i < pointsLength; i++) {
				var point = this.points[i];
				
				if (point == null)
					continue;

				point.draw();
			};
		};
	};
	
	function Point(x, y, z, size, colour) {
		this.colour = colour;
		this.curPos = new Vector(x, y, z);
		this.friction = 0.8;
		this.originalPos = new Vector(x, y, z);
		this.radius = size;
		this.size = size;
		this.springStrength = 0.1;
		this.targetPos = new Vector(x, y, z);
		this.velocity = new Vector(0.0, 0.0, 0.0);
		
		this.update = function() {
			var dx = this.targetPos.x - this.curPos.x;
			var ax = dx * this.springStrength;
			this.velocity.x += ax;
			this.velocity.x *= this.friction;
			this.curPos.x += this.velocity.x;
			
			var dy = this.targetPos.y - this.curPos.y;
			var ay = dy * this.springStrength;
			this.velocity.y += ay;
			this.velocity.y *= this.friction;
			this.curPos.y += this.velocity.y;
			
			var dox = this.originalPos.x - this.curPos.x;
			var doy = this.originalPos.y - this.curPos.y;
			var dd = (dox * dox) + (doy * doy);
			var d = Math.sqrt(dd);
			
			this.targetPos.z = d/100 + 1;
			var dz = this.targetPos.z - this.curPos.z;
			var az = dz * this.springStrength;
			this.velocity.z += az;
			this.velocity.z *= this.friction;
			this.curPos.z += this.velocity.z;
			
			this.radius = this.size*this.curPos.z;
			if (this.radius < 1) this.radius = 1;
		};
		
		this.draw = function() {
			ctx.fillStyle = this.colour;
			ctx.beginPath();
			ctx.arc(this.curPos.x, this.curPos.y, this.radius, 0, Math.PI*2, true);
			ctx.fill();
		};
	};
	
	init();
});
