//------------------------------------------------------------
// 
// Animation.js contains all DHTML animation classes and utilities
// It requires an external DIV called animatedImageStore
// 		<div id="animatedImagesStore">
//		</div>
// Written January 2002 by Rares Ispas
//------------------------------------------------------------
var animatedImages = new AnimatedCollection();
function initAnimation()
{
	//
	// make sure to use sub unit speed values, else the image will jump
	//
		var animator, polyArray;
	
	var referenceX = 0;
	var referenceY = -5;

	// right curved side down, switch to left, down
	polyArray = transformRelativeToAbsolute( referenceX, referenceY-2, new Array( 0,49, 219,0, 1,-10, 2,-5, 3,-6, 4,-4, 5,-5, 5,-3, 6,-4, 6,-2, 7,-2, 37,0, 450,0 ) );
	animator = new PathPoly( polyArray, fillArray(1, polyArray.length/2), true );
	animatedImages.add( IMAGEPATH, animator );
		
	polyArray = transformRelativeToAbsolute( referenceX-7, referenceY-1, new Array( 16,39, 0,-26, 10,0, 3,2, 0,6, -4,4, -6,0, 6,0, 8,14, 10,0, 4,-12, 6,-13, 10,25, 14,0, 0,-26 ) );
	animator = new PathPoly( polyArray, fillArray(0.5, polyArray.length/2), true );
	animatedImages.add( IMAGEPATH, animator );
/*
	// left side down, switch right, down
	polyArray = transformRelativeToAbsolute( referenceX, referenceY, new Array( 0,0, -46,0, 0,233, 67,0, 0, 200));
	animator = new PathPoly( polyArray , fillArray(0.6, polyArray.length/2), true );
	animatedImages.add( "Template/Images/glow.gif", animator );

	polyArray = transformRelativeToAbsolute( referenceX, referenceY, new Array( 0,0, 103,8, 60,-11, 69,-5, 178,0, 0,-34, 23,0, 24,30, 8,0, 0,-20, 14,0, 0, -12, 175,0 ) );
	animator = new PathPoly( polyArray, fillArray(0.8, polyArray.length/2), true );
	animatedImages.add( "Template/Images/glow.gif", animator );

	polyArray = transformRelativeToAbsolute( referenceX, referenceY, new Array( 0,0, 28,37, 35,-20, 40,-13, 5,12, 11,9, 409,0, 13,-9, 5,-10, 79, 11, 45, 6 ));
	animator = new PathPoly( polyArray , fillArray(1, polyArray.length/2), true );
	animatedImages.add( "Template/Images/glow.gif", animator );

	// synapse edge circus
	animator = new PathCircular( referenceX, referenceY, 37, 15, true );
	animatedImages.add( "Template/Images/glow.gif", animator );
*/
	setAnimateTimer();
}

function setAnimateTimer()
{
	window.setTimeout( "moveImages();", 10, "JavaScript" );
}

function moveImages()
{
	animatedImages.animate();
	
	setAnimateTimer();
}

//
// AnimatedCollection class constructor
//
function AnimatedCollection()
{
	//
	// Members
	//
	this.count = 0;
	this._animators = new Array();
	
	//
	// Methods
	//
	this.add = _createAnimatedImage;
	this.animate = _moveImages;
	
	animatedImagesStore.innerHTML = "";
}

function _createAnimatedImage( imageSource, _animator )
{
	if( typeof(imageSource) != "string" || typeof(_animator) == "undefined" || typeof(_animator.move) == "undefined" )
	{
		alert("bad parameter in call to _createAnimatedImage");
	}
	
	animatedImagesStore.innerHTML += "<div id=animatedImage_" + this.count + "><IMG src=" + imageSource + "></div>";
	this._animators[ this.count ] = _animator;

	this.count++;
}

function _moveImages()
{
	var i;
	for( i = 0; i < this.count; i++ )
	{
		this._animators[ i ].move();

		var image = document.all("animatedImage_" + i );
		image.style.position = "absolute";
		image.style.zIndex = 10;
		image.style.left = this._animators[ i ].currentPoint.x;
		image.style.top = this._animators[ i ].currentPoint.y;
	}
}


//
// returns an array of specified length filled with the value
//
function fillArray( value, arrayLength )
{
	var arr = new Array( arrayLength );
	var i;
	
	for( i = 0; i < arrayLength; i++ )
		arr[i] = value;
	
	return arr;
}

function transformRelativeToAbsolute( startX, startY, relCoordinates )
{
//	alert( "transformRelativeToAbsolute = " + startX + " " + startY );
	absCoordinates = new Array( relCoordinates.length );

	var i;
	for( i = 0; i < relCoordinates.length; i ++ )
		if( i % 2 == 0 )
		{
			absCoordinates[i] = relCoordinates[i] + startX;
			startX = absCoordinates[i];
		}
		else
		{
			absCoordinates[i] = relCoordinates[i] + startY;
			startY = absCoordinates[i];
		}
//	alert( "absCoordinates = " + absCoordinates );
	return absCoordinates;
}

//
// Point class
//
function Point( x, y )
{
	if( x == this.undefined || typeof(x) != "number" ||
		y == this.undefined || typeof(y) != "number" )
	{
		alert("Bad argument passed to Point constructor");
		break_here();
	}

	//
	// Members
	//
	this.x = x;
	this.y = y;
}

//
// PathLinear class constructor.
//
function PathLinear( startX, startY, endX, endY, speed, repeat )
{
	if( typeof(startX) != "number" || typeof(startY) != "number" || typeof(endX) != "number" || typeof(endY) != "number" || typeof(speed) != "number" || typeof(repeat) != "boolean" )
	{
		alert("error in parameters to PathLinear constructor");
		break_here();
	}
	
	//
	// members
	//
	this._startX = startX;
	this._startY = startY;
	this._endX = endX;
	this._endY = endY;
	this._speed = speed;
	this._repeat = repeat;

	this._way = 0;
	this.currentPoint = new Point( startX, startY );
	// precalculate trigonometric functions
	this._pathLength = Math.sqrt( Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2) );
	this._tan = (endY - startY) / this._pathLength;
	this._cotan = (endX - startX) / this._pathLength;

	//
	// methods
	//
	this.move = _moveLinear;
}

//
// returns true if the movement has not finished
//
function _moveLinear()
{
	var finished = false; // return value

	this._way += this._speed; // make a little step

	//
	// have we passed by the ending point?
	//
	if( this._way > this._pathLength )
	{

		newPoint = new Point( this._endX, this._endY );

		if( this._repeat )
			this._way = 0;
		else
		{
			this._way = this._pathLength;
			finished = true;
		}
	}

	var x = this._startX + this._way * this._cotan;
	var y = this._startY + this._way * this._tan;
	this.currentPoint = new Point( x, y );
	
//	window.status = "x = " + this.currentPoint.x + " y = " + this.currentPoint.y;
	return !finished;
}

//
// PathPoly class constructor
// polyArray ( X coordinate, Y coordinate} 
// speedArray.length = polyArray.length / 2
//
function PathPoly( polyArray, speedArray, repeat )
{
	if( polyArray.length % 2 != 0 || polyArray.length < 4 || polyArray.length / 2 != speedArray.length || typeof(repeat) != "boolean" )
	{
		alert("error in the polyArray parameter");
		break_here();
	}
	
	//
	// members
	//
	this.currentPoint = new Point( polyArray[0], polyArray[1] );
	this._polyArray = polyArray;
	this._speedArray = speedArray;
	this._repeat = repeat;
	this._index = 0; // poly segment index;
	this._linearPath = new PathLinear( polyArray[0], polyArray[1], polyArray[2], polyArray[3], speedArray[0], false ); // sub elements are not repeteable
	//
	// methods
	//
	this.move = _movePoly;
}

//
// return wether the move has finished (always false with repeat=true)
//
function _movePoly()
{
	// some aliases
	polyArray = this._polyArray;
	speedArray = this._speedArray;
		
	//
	// continue to move while the move is not finished
	//
	if( this._linearPath.move() )
		;
	else
	{
		//
		// advance to the next segment in the poly
		//
		this._index += 2; // advance poly segment index;

		if( this._index > polyArray.length - 4 )
		{
			if( this._repeat )
			{
				this._index = 0;	
			}
			else
			{
				//
				// just exit and forget about all things
				//
				return true;
			}
		}
		
		var i = this._index;
		this._linearPath = new PathLinear( polyArray[i], polyArray[i+1], polyArray[i+2], polyArray[i+3], speedArray[i/2], false );
		this._linearPath.move();
	}
	
	//
	// export the coordinates from PathLinear to exterior
	//
	this.currentPoint = this._linearPath.currentPoint;
	
	return false;
}

// 
// class PathCircular
//
function PathCircular( centerX, centerY, radius, speed, repeat )
{
	//
	// members
	//
	this._centerX = centerX;
	this._centerY = centerY;
	this._radius = radius;
	this._speed = speed;
	this._repeat = repeat;
	this._currentLength = 0;

	this.currentPoint = _calculateCircularPosition( centerX, centerY, radius, this._currentLength );
	
	//
	// methods
	//
	this.move = _moveCircular;
}

function _moveCircular()
{
	this._currentLength += this._speed;
	
	this.currentPoint = _calculateCircularPosition( this._centerX, this._centerY, this._radius, this._currentLength );
}

function _calculateCircularPosition( centerX, centerY, radius, currentLength )
{
	var x, y;
	
	x = centerX + radius * ( Math.cos( currentLength / (2*Math.PI * radius) ) );
	y = centerY + radius * ( Math.sin( currentLength / (2*Math.PI * radius) ) );
	
	return new Point( x, y);
}

initAnimation()
