/**
 * @ref http://mrdoob.com/lab/javascript/harmony
 */

			// SAVING MY POOR SERVER :S (These classes are supposed to be on external files)

			function chrome( context )
			{
				this.init( context );
			}

			chrome.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
		
					if (RegExp(" AppleWebKit/").test(navigator.userAgent))
						this.context.globalCompositeOperation = 'darker';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba(0, 0, 0, 0.1)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.2;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 1000)
						{
							this.context.strokeStyle = "rgba(" + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", " + Math.floor(Math.random() * 255) + ", 0.1 )";
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * size), this.points[this.count][1] + (dy * size));
							this.context.lineTo( this.points[i][0] - (dx * size), this.points[i][1] - (dy * size));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function circles( context )
			{
				this.init( context );
			}

			circles.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					var dx = mouseX - this.prevMouseX;
					var dy = mouseY - this.prevMouseY;
					var d = Math.sqrt(dx * dx + dy * dy) * 2;
					var d_half = d / 2;

					var cx = Math.floor(mouseX / 100) * 100 + 50;
					var cy = Math.floor(mouseY / 100) * 100 + 50;

					var steps = Math.floor( Math.random() * 10 );
					var step_delta = d / steps;

					for (var i = 0; i < steps; i++)
					{
						this.context.strokeStyle = "rgba(0, 0, 0, 0.1)";
						this.context.beginPath();
						this.context.arc( cx, cy, (steps - i) * step_delta, 0, Math.PI*2, true);
						this.context.stroke();
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function fur( context )
			{
				this.init( context );
			}

			fur.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba(0, 0, 0, 0.1)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.5;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 2000 && Math.random() > d / 2000)
						{
							this.context.strokeStyle = "rgba(0, 0, 0, 0.1 )";
							this.context.beginPath();
							this.context.moveTo( mouseX + (dx * size), mouseY + (dy * size));
							this.context.lineTo( mouseX - (dx * size), mouseY - (dy * size));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function grid( context )
			{
				this.init( context );
			}

			grid.prototype =
			{
				context: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;

					if (RegExp(" AppleWebKit/").test(navigator.userAgent))
						this.context.globalCompositeOperation = 'darker';

					this.context.strokeStyle = "rgba( 0, 0, 0, 0.01 )";
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
				},

				stroke: function( mouseX, mouseY )
				{
					var cx = Math.round(mouseX / 100) * 100;
					var cy = Math.round(mouseY / 100) * 100;

					var dx = (cx - mouseX) * 10;
					var dy = (cy - mouseY) * 10;

					for (var i = 0; i < 50; i++)
					{
						this.context.beginPath();
						this.context.moveTo( cx, cy );
						this.context.quadraticCurveTo(mouseX + Math.random() * dx, mouseY + Math.random() * dy, cx, cy);
						this.context.stroke();
					}
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function longfur( context )
			{
				this.init( context );
			}

			longfur.prototype =
			{
				context: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';
					this.context.strokeStyle = "rgba( 0, 0, 0, 0.05 )";
		
					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					for (var i = 0; i < this.points.length; i++)
					{
						var size = -Math.random();
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 4000 && Math.random() > d / 4000)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * size), this.points[this.count][1] + (dy * size));
							this.context.lineTo( this.points[i][0] - (dx * size) + Math.random() * 2, this.points[i][1] - (dy * size) + Math.random() * 2);
							this.context.stroke();
						}
					}
		
					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function ribbon( context )
			{
				this.init( context );
			}

			ribbon.prototype =
			{
				context: null,

				mouseX: null, mouseY: null,

				painters: null,

				interval: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.strokeStyle = "rgba( 0, 0, 0, 0.05 )";
					this.context.globalCompositeOperation = 'source-over';

					this.mouseX = SCREEN_WIDTH / 2;
					this.mouseY = SCREEN_HEIGHT / 2;

					this.painters = new Array();
		
					for (var i = 0; i < 50; i++)
					{
						this.painters.push({ dx: SCREEN_WIDTH / 2, dy: SCREEN_HEIGHT / 2, ax: 0, ay: 0, div: 0.1, ease: Math.random() * 0.2 + 0.6 });
					}
		
					this.isDrawing = false;

					this.interval = setInterval( bargs( function( _this ) { _this.update(); return false; }, this ), 1000/60 );
				},
	
				destroy: function()
				{
					clearInterval(this.interval);
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.mouseX = mouseX;
					this.mouseY = mouseY

					for (var i = 0; i < this.painters.length; i++)
					{
						this.painters[i].dx = mouseX;
						this.painters[i].dy = mouseY;
					}

					this.shouldDraw = true;
				},

				stroke: function( mouseX, mouseY )
				{
					this.mouseX = mouseX;
					this.mouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
	
				},

				update: function()
				{
					for (var i = 0; i < this.painters.length; i++)
					{
						this.context.beginPath();
						this.context.moveTo(this.painters[i].dx, this.painters[i].dy);		

						this.painters[i].dx -= this.painters[i].ax = (this.painters[i].ax + (this.painters[i].dx - this.mouseX) * this.painters[i].div) * this.painters[i].ease;
						this.painters[i].dy -= this.painters[i].ay = (this.painters[i].ay + (this.painters[i].dy - this.mouseY) * this.painters[i].div) * this.painters[i].ease;
						this.context.lineTo(this.painters[i].dx, this.painters[i].dy);
						this.context.stroke();
					}
				}
			}

			function bargs( _fn )
			{
				var args = [];
				for( var n = 1; n < arguments.length; n++ )
					args.push( arguments[ n ] );
				return function () { return _fn.apply( this, args ); };
			}

			function shaded( context )
			{
				this.init( context );
			}

			shaded.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					for (var i = 0; i < this.points.length; i++)
					{
						var size = 0.3;
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 1000)
						{
							this.context.strokeStyle = "rgba(0, 0, 0, " + ((1 - (d / 1000)) * 0.1) + " )";

							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0], this.points[this.count][1]);
							this.context.lineTo( this.points[i][0], this.points[i][1]);
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function sketchy( context )
			{
				this.init( context );
			}

			sketchy.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba(0, 0, 0, 0.05)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					this.context.strokeStyle = "rgba(0, 0, 0, 0.05 )";

					for (var i = 0; i < this.points.length; i++)
					{
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 4000 && Math.random() > d / 2000)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0] + (dx * 0.3), this.points[this.count][1] + (dy * 0.3));
							this.context.lineTo( this.points[i][0] - (dx * 0.3), this.points[i][1] - (dy * 0.3));
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function squares( context )
			{
				this.init( context );
			}

			squares.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				init: function( context )
				{
					this.context = context;
					this.context.globalCompositeOperation = 'source-over';
					this.context.strokeStyle = "rgba(0, 0, 0, 1)";
					this.context.fillStyle = "rgba(255, 255, 255, 1)";
					this.context.lineWidth = 1;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					var dx = mouseX - this.prevMouseX;
					var dy = mouseY - this.prevMouseY;

					var angle = 1.57079633;

					var px = Math.cos(angle) * dx - Math.sin(angle) * dy;
					var py = Math.sin(angle) * dx + Math.cos(angle) * dy ;

					this.context.beginPath();
					this.context.moveTo(this.prevMouseX - px, this.prevMouseY - py);
					this.context.lineTo(this.prevMouseX + px, this.prevMouseY + py);
					this.context.lineTo(mouseX + px, mouseY + py);
					this.context.lineTo(mouseX - px, mouseY - py);
					this.context.lineTo(this.prevMouseX - px, this.prevMouseY - py);
					this.context.fill();
					this.context.stroke();

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}

			function web( context )
			{
				this.init( context );
			}

			web.prototype =
			{
				context: null,

				prevMouseX: null, prevMouseY: null,

				points: null, count: null,

				init: function( context )
				{
					this.context = context;
					this.context.lineWidth = 1;
					this.context.globalCompositeOperation = 'source-over';

					this.points = new Array();
					this.count = 0;
				},

				destroy: function()
				{
				},

				strokeStart: function( mouseX, mouseY )
				{
					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;
				},

				stroke: function( mouseX, mouseY )
				{
					this.points.push( [ mouseX, mouseY ] );

					this.context.strokeStyle = "rgba(0, 0, 0, 0.5)";
					this.context.beginPath();
					this.context.moveTo(this.prevMouseX, this.prevMouseY);
					this.context.lineTo(mouseX, mouseY);
					this.context.stroke();

					this.context.strokeStyle = "rgba(0, 0, 0, 0.1)";

					for (var i = 0; i < this.points.length; i++)
					{
						var dx = this.points[i][0] - this.points[this.count][0];
						var dy = this.points[i][1] - this.points[this.count][1];
						var d = dx * dx + dy * dy;

						if (d < 2500 && Math.random() > 0.9)
						{
							this.context.beginPath();
							this.context.moveTo( this.points[this.count][0], this.points[this.count][1]);
							this.context.lineTo( this.points[i][0], this.points[i][1]);
							this.context.stroke();
						}
					}

					this.prevMouseX = mouseX;
					this.prevMouseY = mouseY;

					this.count ++;
				},

				strokeEnd: function( mouseX, mouseY )
				{
		
				}
			}
