
//---------------------------------------------- Constants ---------------------------------------------------

var PI=3.14;
var TWO_PI=2*PI;
var SIZE=50;

//------------------------------------------- CTrajectory Class ------------------------------------------------

function CTrajectory(speed,dir) {

	this.speed=0; 
	this.direction=0;
	
	this.CurrentLocation=CTrajectory_CurrentLocation;
	this.SetDirection=CTrajectory_SetDirection;
	this.ToString=CTrajectory_ToString;
	
    if ( arguments.length > 0 ) {
		this.speed = speed;
		this.direction  = dir;
	}
};

function CTrajectory_ToString() {
	return this.speed +"," + this.direction;
};
	
// POST: current direction is set to angle radians (polar direction)
function CTrajectory_SetDirection(angle) {
	var mult = (angle / TWO_PI);
	this.direction = angle - mult*TWO_PI;
	if (angle < 0) 
		this.direction += TWO_PI;
};


// POST: the current location of the point along the trajectory is returned
function CTrajectory_CurrentLocation(startPos,startTime,currentTime) {
	var elapsedSeconds = (currentTime - startTime)/60;//CLOCKS_PER_SEC;
	var distTraveled = this.speed * elapsedSeconds;
	return new CPoint2D(startPos.x + distTraveled * Math.cos(this.direction), 
						startPos.y + distTraveled * Math.sin(this.direction));
};



//---------------------------------------------- CPoint2D Class -----------------------------------------------

function CPoint2D(x, y){

	this.x=0;
	this.y=0;
	
	this.SetCoord=CPoint2D_SetCoord;
	this.Rotate=CPoint2D_Rotate;
	this.Distance=CPoint2D_Distance;
	this.Move=CPoint2D_Move;
	this.OffsetTo=CPoint2D_OffsetTo;
	this.Theta=CPoint2D_Theta;
	this.ToString=CPoint2D_ToString;
	
    if ( arguments.length > 0 ) {
		this.x = x;
		this.y = y;
	}
};
	
function CPoint2D_ToString() {
	return this.x + "," + this.y;
};

function CPoint2D_SetCoord(x, y) {
	this.x = x;
	this.y = y;
};

function CPoint2D_Theta(pt2)
{
	var theta = Math.atan2(pt2.y - this.y, pt2.x - this.x);
	if (theta < 0) theta += TWO_PI;
	return theta;
};

function CPoint2D_Rotate(theta,centre) {
	// Translate point so that centre is at origin
	this.x -= centre.x;
	this.y -= centre.y;

	// Rotate point around origin theta degrees
	var cosTheta = Math.cos(theta);	// save re-calculating twice!
	var sinTheta = Math.sin(theta);

	var xtmp, ytmp;
	xtmp = this.x * cosTheta - this.y * sinTheta;
	ytmp = this.x * sinTheta + this.y * cosTheta;

	// Translate point back to its original position
	this.x = xtmp + centre.x;
	this.y = ytmp + centre.y;
};


// POST: a point halfway between this and otherPoint is returned.
function CPoint2D_Centre(otherPoint) { //CPoint2D param
	var cx = (this.x + otherPoint.x) / 2.0;
	var cy = (this.y + otherPoint.y) / 2.0;
	return new CPoint2D(cx, cy);
};

//POST: the distance between this point and the offset has been returned.
function CPoint2D_Distance(offset) { //CPoint2D param
	var dx = this.x - offset.x;
	var dy = this.y - offset.y;

	return Math.sqrt(dx*dx + dy*dy);
};

//POST: this point is offset in positive direction from its previous postion.
function CPoint2D_Move(offset) { //CPoint2D param
	this.x += offset.x;
	this.y += offset.y;
};

//POST: returns the offset required to Move this point to p2.
function CPoint2D_OffsetTo(p2) {
	return new CPoint2D(p2.x - this.x, p2.y - this.y);
};



//---------------------------------------------- CLetter Class -----------------------------------------------

function CLetter(ID,position,width,height,colorOff,colorOn,character) {

	this.ID="";
	this.position=null;
	this.width=0;
	this.height=0;
	this.colorOff="";
	this.colorOn="";
	this.character="";
	//this.style="";
	
	this.innerButton=null;
	this.selected=false;
	this.destination=null;
	this.trajectory=null;
	this.isMoving=false;
	this.lastMoveTime=0;
	
	this.Updateposition=CLetter_Updateposition;
	this.ToString=CLetter_ToString;
	this.Select=CLetter_Select;
	this.Start=CLetter_Start;
	this.Move=CLetter_Move;
	this.Centre=CLetter_Centre;
	
if (arguments.length == 7) {
		this.ID=ID;
		this.position=position;
		this.width=width;
		this.height=height;
		this.colorOff=colorOff;
		this.colorOn=colorOn;
		this.character=character;
		
		abutton = document.createElement('INPUT');
		abutton.id = this.ID;
		abutton.type = "button";
		abutton.value = this.character;
		abutton.style.width = this.width+"px";
		abutton.style.height = this.height+"px";
		abutton.style.position = "absolute";
		abutton.style.left = this.position.x+"px";
		abutton.style.top = this.position.y+"px";
		abutton.style.color="darkblue";
		abutton.style.backgroundColor="transparent";
		abutton.style.margin="0px";
		abutton.style.padding="0px";
		abutton.style.fontWeight="bold";
		abutton.style.fontSize=Math.floor(this.width*.7)+"px";
		abutton.style.fontFamily="Times New Roman";
		document.getElementById("divTitleContainer").appendChild(abutton);
	}			
};

function CLetter_ToString() {
	return "CLetter   ID: " + this.ID + "   Loc: " + this.position.ToString();
};	

function CLetter_Select(isSelected) {	
	this.selected=isSelected;
	this.innerButton.style.backgroundColor=(isSelected?this.colorOn:this.colorOff);
};

function CLetter_Updateposition() {
	this.Move();
	document.getElementById(this.ID).style.left=Math.floor(this.position.x)+"px";
	document.getElementById(this.ID).style.top=Math.floor(this.position.y)+"px";
};

function CLetter_Start(t) {
	this.trajectory = t;
	this.lastMoveTime=CLetter_Clock();
	this.isMoving=true;
};

function CLetter_Move() { 
	if (!this.isMoving) return;
	var newLocation = this.trajectory.CurrentLocation(this.position, this.lastMoveTime, CLetter_Clock());	
	if (this.position.Distance(this.destination)<1 || newLocation.Distance(this.destination)>this.position.Distance(this.destination)) {
		this.position=this.destination;
		this.isMoving=false;
		return;
	}
	if (this.position.Distance(newLocation)>1) {
		this.position=newLocation;
		this.lastMoveTime=CLetter_Clock();
		return true;
	}
	else return false;
};


function CLetter_Centre() {
	return new CPoint2D(this.position.x()+(this.width/2.0),this.position.y()+(this.height/2.0));
};

function CLetter_Clock() {
	var futdate = new Date();
	return futdate.getTime()/10; //  1/10 secs
};




//---------------------------------------------- Start -----------------------------------------------

var CheckMovementTimer = null;
var letters=new Array;

function CheckMovement() {
	clearTimeout(CheckMovementTimer);
	for (var i=0; i<letters.length; i++) {
		letters[i].Updateposition(); 
	}	
	CheckMovementTimer = setTimeout("CheckMovement()",1);
}


function StartAnimate() { 

  var speed = 500;
	var startTime = new Date();
	for (var i=0, j=1; i<100000; i++) j++;
	if (new Date()-startTime>75) {
	  speed=100000;
  }
  
	var ptstart=new CPoint2D(-1000,0);
	var ptdest=new CPoint2D(((-4.5)*SIZE),0);
	var letter=new CLetter("Letter_W",ptstart,SIZE,SIZE,"green","red","W");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1100,-50);
	var ptdest=new CPoint2D(((-3.5)*SIZE),0);
	var letter=new CLetter("Letter_o",ptstart,SIZE,SIZE,"green","red","O");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1200,-100);
	var ptdest=new CPoint2D(((-2.5)*SIZE),0);
	var letter=new CLetter("Letter_r",ptstart,SIZE,SIZE,"green","red","R");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1300,-150);
	var ptdest=new CPoint2D(((-1.5)*SIZE),0);
	var letter=new CLetter("Letter_d",ptstart,SIZE,SIZE,"green","red","D");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1400,-200);
	var ptdest=new CPoint2D(((-.5)*SIZE),0);
	var letter=new CLetter("Letter_s",ptstart,SIZE,SIZE,"green","red","S");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1500,-250);
	var ptdest=new CPoint2D((.5*SIZE),0);
	var letter=new CLetter("Letter_l",ptstart,SIZE,SIZE,"green","red","L");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1600,-300);
	var ptdest=new CPoint2D((1.5*SIZE),0);
	var letter=new CLetter("Letter_i",ptstart,SIZE,SIZE,"green","red","I");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1700,-350);
	var ptdest=new CPoint2D((2.5*SIZE),0);
	var letter=new CLetter("Letter_d2",ptstart,SIZE,SIZE,"green","red","D");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);

	var ptstart=new CPoint2D(-1800,-400);
	var ptdest=new CPoint2D((3.5*SIZE),0);
	var letter=new CLetter("Letter_e",ptstart,SIZE,SIZE,"green","red","E");
  var traj=new CTrajectory(speed,ptstart.Theta(ptdest));
  letter.destination=ptdest;
  letter.Start(traj); 
	letters.push(letter);
	
	CheckMovementTimer = setTimeout("CheckMovement()",20);
}
	
	
