// The Mouse Movie namespace
var MouseMovie = {
	// A timeline with a stack of mouse position frames
	TimeLine : function () {
		// --- Public variables ---
		this.Frames = new Array();
		this.FirstFrame;
		this.LastFrame;
		
		// Add a frame to the stack of frame with the options passed 
		this.addFrame = function (options) { 
							// Create a new frame
							var NewFrame = new MouseMovie.Frame({XPosition: options.XPosition, YPosition: options.YPosition});
							
							// Set the previous frame for the new frame and the next frame for the last frame
							if (this.Frames.length > 0)	{
								var PreviousFrame = this.Frames[this.Frames.length - 1];
								NewFrame.PreviousFrame = PreviousFrame;
								PreviousFrame.NextFrame = NewFrame;
							}
							// If this is the first frame in the stack, set the FirstFrame property
							else
								this.FirstFrame = NewFrame;
							
							// Add the new frame to the stack
							this.Frames.push(NewFrame); 
							this.LastFrame = NewFrame;
						}
		
		// Override the toString() function
		this.toString =	function ()	{
			var serializedTimeline = "";
			$A(this.Frames).each( function(frame){serializedTimeline += "[ " + frame + " ] "; })
			return serializedTimeline;
		}	
	},
	
	// An individual mouse position frame
	Frame : function (options) {
		// Public
		this.TimeStamp = Date();
		this.XPosition = 0;
		this.YPosition = 0;
		this.NextFrame;
		this.PreviousFrame;
		
		// Override the toString() function
		this.toString =	function ()	{
			var serializedFrame;
			serializedFrame = "X Position: " + this.XPosition + ", ";
			serializedFrame += "Y Position: " + this.YPosition + ", ";
			serializedFrame += "TimeStamp: " + this.TimeStamp;
			return serializedFrame;
		}
		
		// Initialize with any options passed to the constructor
		if (options) {
			if (options.XPosition)
				this.XPosition = options.XPosition;
			if (options.YPosition)
				this.YPosition = options.YPosition;
			if (options.PreviousFrame)
				this.PreviousFrame = options.PreviousFrame;
			if (options.NextFrame)
				this.NextFrame = options.NextFrame;
		}
	},
	
	// A tracker for tracking the mouse as it moves
	// The tracker can take in an external timeline or use an internal one if the user provides none
	Tracker : function (ThisTimeLine) {
		// Get the TimeLine passed to the tracker
		// or create a new TimeLine
		if (ThisTimeLine)
			var _TimeLine = ThisTimeLine;
		else
			var _TimeLine = new MouseMovie.TimeLine();
		
		// Make the TimeLine public	
		this.TimeLine = _TimeLine;
		
		// Is the tracker running or not?
		this.Running = false;
		
		// Functions for starting and stopping the mouse tracker
		this.start = function () {Event.observe(window, "mousemove",  _trackMouse); this.Running = true; };	  
		this.stop = function () { Event.stopObserving(window, "mousemove", _trackMouse); this.Running = false; };
		
		// The function that tracks the mouse and adds a frame for each position of the mouse  
		function _trackMouse(e)	{
			_TimeLine.addFrame({ XPosition: Event.pointerX(e), YPosition: Event.pointerY(e)});
				var newPoint = document.createElement("div");
				newPoint.style.background = "red";
				newPoint.style.height = "1px";
				newPoint.style.width = "1px";
				newPoint.style.position = "absolute";
				newPoint.style.top = (Event.pointerY(e)-1) + "px";
				newPoint.style.left = Event.pointerX(e) + "px";
				var body = document.getElementsByTagName("body")[0];
				body.appendChild(newPoint);

		}
	},
	
	// Function that animates the timeline that is passed to it
	Animate : function (options) {
		// Set the speed to the option passed or to a default
		var _speed = options.Speed || 10;
		
		// Get the cursor from the options
		if (options.Cursor)
			var _cursor = options.Cursor;
		
		// If a cursor was passed to the animator, create a new cursor
		else {
			// Create a new cursor and style it
			var newCursor = document.createElement("div");
			newCursor.style.background = "green";
			newCursor.style.height = "10px";
			newCursor.style.width = "10px";
			newCursor.style.position = "absolute";
			newCursor.style.top = 0;
			newCursor.style.left = 0;
			
			// Add the cursor to the body
			var body = document.getElementsByTagName("body")[0];
			body.appendChild(newCursor);
			
			_cursor = newCursor;
		}
		
		
		// Start moving the cursor
		_moveCursor(options.TimeLine.FirstFrame);
	
		function _moveCursor(CurrentFrame) {
			_cursor.style.top = CurrentFrame.YPosition + "px";
			_cursor.style.left = CurrentFrame.XPosition + "px";
			
			if(CurrentFrame.NextFrame) {
				setTimeout(_moveCursor,_speed,CurrentFrame.NextFrame);
				return true;
			}
			else
				return false;
		}
	},
	
	// Function that traces the path of the mouse animation
	Trace : function (TimeLine)	{
		// Loops through the frames and draws a point for each frame
		var FrameArray = $A(TimeLine.Frames);
		FrameArray.each(
			function(CurrentFrame) {
				// Create a new cursor and style it
				var newPoint = document.createElement("div");
				newPoint.style.background = "green";
				newPoint.style.height = "5px";
				newPoint.style.width = "5px";
				newPoint.style.position = "absolute";
				newPoint.style.top = CurrentFrame.YPosition + "px";
				newPoint.style.left = CurrentFrame.XPosition + "px";
				var body = document.getElementsByTagName("body")[0];
				body.appendChild(newPoint);
			}
		)
	},
	
	// Function that traces the path of the mouse animation
	Elkuld : function (TimeLine)	{
		// ?pontok=306-226%2C276-283%2C336-277#regio
		var haver = document.getElementById("kijelol");
		haver.innerHTML="";
		var FrameArray = $A(TimeLine.Frames);
		FrameArray.each(
			function(CurrentFrame) {
				var haver = document.getElementById("kijelol");
				haver.innerHTML=haver.innerHTML + "%2C" + CurrentFrame.XPosition + "-" + CurrentFrame.YPosition;
			}
		)
		haver.innerHTML="./?pontok=" + haver.innerHTML.substr(3);
		document.location.href=haver.innerHTML;
	}
}
