/*******************************************************************
*
* File    : spring.js
*
* Created : 2000/12/06
*
* Author  : Roy Whittle  (Roy@Whittle.com) www.Roy.Whittle.com
*		Based on an original idea by
*		Philip Winston (pwinston@yahoo.com) www.geocities.com/pwinston/
*
* Purpose : To create a springy mouse trailer
*
* History
* Date         Version        Description
* 2000-12-06	1.0		I have reverse engineered Philip Winston's
*					Excellent "Elastic Bullets" script
*					(www.geocities.com/pwinston/
*					 pwinston@yahoo.com)
*					This is an initial version. 
* 2000-12-08	1.1		Added the function textSpring
***********************************************************************/
var mous = new xMouse();
var theMasses = new Array();
var GRAVITY = 9.8; 

//Here are the constants that affect the trailer
var FRICTION 		=  -7;
var MASS			=  10;
var SPRING_FORCE 		=  20;
var SPRING_LENGTH		=  10;
var AX = GRAVITY;		//X Acceleration constant
var AY = 0; //Y Acceleration constant

var TIMEOUT_INTERVAL	= 40;
var NUM_STEPS		= 1000/TIMEOUT_INTERVAL;

function Point(x, y)
{
	this.x = x;
	this.y = y;
}

function calculateForce(m1,m2,f)
{
	if(m1 == null || m2 == null)
		return;

	x = m2.pos.x - m1.pos.x;
	y = m2.pos.y - m1.pos.y;

	len  = Math.sqrt(x*x + y*y); // good old Pythagoras theorem
	force = SPRING_FORCE * (len - SPRING_LENGTH);

	//If we only process positive force then the spring acts
	//more like an elastic band
	if(force > 0)
	{
		f.x += force * x/len; //cos = adjacent over hypotenuse
		f.y += force * y/len; //sin = opposite over hypotenuse
	}
}

function updateSpeed()
{
	f = new Point(0,0);

	for(i=1 ; i<theMasses.length ; i++)
	{
		m = theMasses[i];
		f.x=m.dx * FRICTION;
		f.y=m.dy * FRICTION;

		for(j=0 ; j<m.conn.length ; j++)
			calculateForce(m, m.conn[j], f);

		m.dx += ((f.x/MASS) + AX)/NUM_STEPS;  // delta = dela + acc where
		m.dy += ((f.y/MASS) + AY)/NUM_STEPS;  // acc = Force/Mass (Newtons 1st? law of motion)
	}
}
function moveMasses()
{
	theMasses[0].pos.x= mous.X+10;
	theMasses[0].pos.y= mous.Y;
	
	for(i=0 ; i<theMasses.length ; i++)
	{
		m = theMasses[i];
		m.pos.x += m.dx;
		m.pos.y += m.dy;
		m.moveTo(m.pos.x, m.pos.y);
	}

}

function connectMasses()
{
	len  = theMasses.length;
	len2 = len-1;
	for(i=0 ; i<len ; i++)
	{
		theMasses[i].conn[0] = i > 0		? theMasses[i-1] : null;
		theMasses[i].conn[1] = i < (len2)	? theMasses[i+1] : null;
	}
}

function newMass(img,x,y)
{
	var mass = new xLayer(img, x, y);
	mass.pos=new Point(x,y);
	mass.conn=new Array();
	mass.dx=0;
	mass.dy=0;
	mass.show();
	return mass;
}

function animate()
{
	updateSpeed();
	moveMasses();
}

function santaSpring(n)
{
	theMasses[0] = newMass("<IMG SRC='images/rd1.gif'>", 100, 100);

	for(i=1 ; i<n ; i++)
	{
		theMasses[i] = newMass("<IMG SRC='images/rd2.gif'>", 100, 100);
	}

	theMasses[n] = newMass("<IMG SRC='images/santa.gif'>", 100, 100);

	connectMasses();
      setInterval("animate()", TIMEOUT_INTERVAL);
}
