/*
 * Copyright 2000-2001, The Train Gif Java Script Project
 * Writen by Brian E Clough
 *
 * This code is "Grovelware", if you use it, then meet the
 * author, you must drop to your knees, touch your forehead
 * to the ground, and shout "YOU DA' MAN" three times, slowly.
 *
 */

var gaAllScenes = new Array();
var gaAllImgs = new Array();
var gaPostLoad = new Array();
var gaSceneDims = new Array();
var currentScene = -1;
var currentTrack = -1;
var currentStatic = -1;
var errorLockout = 0;
var oTimer=null;

//Constants
var Left = -1;
var Right = 1;
var Top = 0;
var Bottom = 1;
var normalDelay = 50;
var longDelay = 2000;
var scale = 2.06;


function locateScene(name, hT, wD)
{
	if(locateScene.arguments.length>=3)
	{
		width = wD;
	}
	else
	{
		width = "100%";
	}
	document.write("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 HEIGHT="+hT+" WIDTH="+width+
		"><TR><TD VALIGN=top><A NAME="+name+"A>&nbsp;</A></TD></TR></TABLE>");
	gaSceneDims[name] = new Array(width, hT);
}

function locateSceneBg(name, image)
{
	document.write("<IMG NAME="+name+"I SRC="+image+" ALT="+image+" ALLIGN='top'>");
	preLoadImgs(image);
	gaSceneDims[name] = image;
}

function preLoadImgs(szImgs)
{
	var aImgLst = szImgs.split(",");
	if(aImgLst.length < 1)return;
	for(i=0; i<aImgLst.length; i++)
	{
		var szImgName = aImgLst[i];
		szImgName=szImgName.replace(/(^\s+)|(\s+$)/g, "");
		if(typeof(gaAllImgs[szImgName]) != 'object' && szImgName != "")
		{
			gaAllImgs[szImgName] = new Image();
			gaAllImgs[szImgName].src = szImgName;
		}
	}
}

function getImgDims(szImgs)
{
	var aImgLst = szImgs.split(",");
	var tempW=0;
	var tempH=0;
	for(i=0; i<aImgLst.length; i++)
	{
		var szImgName = aImgLst[i];
		szImgName=szImgName.replace(/(^\s+)|(\s+$)/g, "");
		if(szImgName != "")
		{
			tempW += gaAllImgs[szImgName].width;
			tempH = Math.max(gaAllImgs[szImgName].height, tempH);
		}
	}
	results = new Array(tempW, tempH);
	return results;
}

function createScene(name, szColor)
{
	errorLockout = 0;
	var szScene = DC_FRAMEpath+"document.all."+name;
	oScene = DCcreate(szScene, 0, 0, 1, 1);
	if(!oScene)return;
	DCshow(oScene, false);
	currentScene = gaAllScenes.length;
	currentTrack = -1;
	oScene.sName = name;
	oScene.started = 0;
	oScene.trackList = new Array();
	oScene.consists = new Array();
	if(createScene.arguments.length>1)DCsetBcolor(oScene, szColor);
	gaAllScenes[currentScene] = oScene;

	switch(typeof(gaSceneDims[name]))
	{
		case "object":
			dims = gaSceneDims[name];
			break;

		case "string":
			dims = getImgDims(gaSceneDims[name]);
			break;

		default:
			DCalert("ERROR: cannot find dims for scene "+name+", Type - "+typeof(gaSceneDims[name]));
			return;
	}

	var iWidth = (typeof(dims[0])=="string")?DCgetWinWidth(self)-(DC_IE?24:34):dims[0];
	oScene.style.width = iWidth;
	oScene.style.height = dims[1];
	DCclip(oScene,0, iWidth, dims[1],0);
}

function createTrack(name, y, z, delay)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before track "+name);
		errorLockout = 1;
		return
	}
	oScene = gaAllScenes[currentScene];
	if(!oScene)return
	currentTrack = oScene.trackList.length;
	oTrack = new Object();
	oScene.trackList[currentTrack] = oTrack;
	oTrack.name = name;
	oTrack.index = currentTrack;
	oTrack.trainList = new Array();
	oTrack.currentTrain = -1;
	oTrack.y = DCgetH(oScene)-y;
	oTrack.z = z;
	if(createTrack.arguments.length>=4)oTrack.delay = delay*1000;
	else oTrack.delay = 0;
}

function createConsist(name, szGifs)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before consist "+name);
		errorLockout = 1;
		return
	}
	preLoadImgs(szGifs);
	gaPostLoad[gaPostLoad.length] = 'createConsistPL("'+name+'", "'+szGifs+'", '+currentScene+')';
}

function createConsistPL(name, szGifs, sceneIndex)
{
	oScene=gaAllScenes[sceneIndex];
	if(!oScene)return
	szObject=DCgetPath(oScene).szPath+".all."+name+DCgetName(oScene);
	aGifs=szGifs.split(",");
	for(i=0; i<aGifs.length; i++)aGifs[i]=aGifs[i].replace(/(^\s+)|(\s+$)/g, '')
	szConsist='<NOBR><IMG SRC="'+aGifs.join('"><IMG SRC="')+'"></NOBR>';
	aD=getImgDims(szGifs);
	oCars=DCcreate(szObject, 0, 0, aD[0], aD[1]);
	oScene.consists[name] = oCars;
	DCshow(oCars, false);
	oCars.inUse = 0;
	DCsetContent(oCars, szConsist);
}

function createTrain(name, consist, dir, speed, delay, target, accel)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before train "+name);
		errorLockout = 1;
		return
	}
	if(currentTrack<0)
	{
		DCalert("You must define a track before train "+name);
		errorLockout = 1;
		return
	}
	oScene = gaAllScenes[currentScene];
	oTrack = oScene.trackList[currentTrack];
	oTrain = new Object();
	oTrack.trainList[oTrack.trainList.length] = oTrain;
	oTrain.name = name;
	oTrain.startSpeed = Math.abs(speed)*dir;
	oTrain.delay = (createTrain.arguments.length >= 5)?((delay > 0.5)?(delay*1000):0.51):0;
	oTrain.targetSpeed = Math.abs((createTrain.arguments.length >= 6)?target:speed)*dir;
	oTrain.accel = (createTrain.arguments.length >= 7)?accel*dir*((target<speed)?-1:1):0.0;
	oTrain.consist = consist;
}


function moveAllTrains()
{
	oDate = new Date();
	time = oDate.getTime();
	for(i=0; i<gaAllScenes.length; i++)
	{
		oScene = gaAllScenes[i];
		if(oScene.started)
		{
			for(j=0; j<oScene.trackList.length; j++)
			{
				oTrack = oScene.trackList[j];
				if(time>oTrack.timeout)
				{
					oTrain = oTrack.trainList[oTrack.currentTrain];
					oCars = oScene.consists[oTrain.consist];
					var elapsedTime = time - oTrack.prevTime;
					oTrack.prevTime = time;
					if(elapsedTime >= 200) elapsedTime = normalDelay;
					var deltaV = oTrack.accel * (elapsedTime/1000);
					oTrack.speed += deltaV;
					if(((oTrack.speed < oTrack.speedTarget) && (oTrack.accel < 0)) || ((oTrack.speed > oTrack.speedTarget) && (oTrack.accel > 0)))
						oTrack.speed = 1.0 * oTrack.speedTarget;
					var pixelSpeed = oTrack.speed * scale;
					oTrack.floatLoc += pixelSpeed * (elapsedTime/1000);
					loc = Math.round(oTrack.floatLoc);
					if((loc < -1*DCgetW(oCars))||(loc > DCgetW(oScene)))
					{
						DCshow(oCars, false);
						oCars.inUse = 0;
						nextTrain(oScene, oTrack, time);
					}
					else
					{
						DCmoveTo(oCars, loc, DCgetY(oCars));
						if(oTrack.speed == 0.0)
						{
							rev = (Math.abs(oTrain.startSpeed) <= 25)?1:(-1)
							oTrack.speedTarget = oTrain.startSpeed*(-1*rev);
							oTrack.accel *= rev;
							oTrack.timeout = time+longDelay;
						}
						else oTrack.timeout=time;
					}
				}
			}
		}
	}
}


function nextTrain(oScene, oTrack)
{
	var i = oTrack.currentTrain+1;
	nextN = (oTrack.currentTrain < 0)?oTrack.trainList.length:oTrack.currentTrain;

	for( ; i != nextN; i++)
	{
		if(i >= oTrack.trainList.length)i = 0;
		oTrain = oTrack.trainList[i];
		oCars = oScene.consists[oTrain.consist];
		if(!oTrain.consist){DCalert("Can't find consist "+oTrain.consist);return;}
		if(!oCars.inUse)break;
	}

	oDate = new Date();
	time = oDate.getTime();

	if(oCars.inUse)
	{
		oTrack.timeout = time+longDelay;
		DCstatus("Cannot find an available consist for Scene - "+oScene.sName+", Track - "+oTrack.name);
	}
	else
	{
		oTrack.currentTrain = i;
		oCars.inUse = 1;

		oTrack.accel = oTrain.accel;
		oTrack.speed = 1.0 * oTrain.startSpeed;
		oTrack.speedTarget = oTrain.targetSpeed;
		tempDelay = oTrack.delay;
		oTrack.delay = oTrain.delay;
		oTrack.floatLoc = (oTrack.speed < 0)?DCgetW(oScene):-1*DCgetW(oCars);

		DCmoveTo(oCars, oTrack.floatLoc, oTrack.y - DCgetH(oCars));
		DCsetZindex(oCars, oTrack.z);
		DCshow(oCars, true);
		oTrack.prevTime = time;
		oTrack.timeout = time+tempDelay;
	}
}

function retryNextTrain(szScene, szTrack)
{
	oScene = gaAllScenes[szScene];
	oTrack = oScene.trackList[szTrack];
	nextTrain(oScene, oTrack);
}

function placeStatic(name, x, y, mode, z)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before static item "+name);
		return
	}
	preLoadImgs(name);
	gaPostLoad[gaPostLoad.length] = "placeStaticPL('"+name+"', "+x+", "+y+", "+mode+", "+z+", "+currentScene+")";
}

function placeStaticPL(name, x, y, mode, z, sceneIndex)
{
	oScene = gaAllScenes[sceneIndex];
	szImg = name.split(".")[0];
	if(!oScene.getElementById(szImg+"0"))currStat = 0;
	szImg += currentStatic++;
	szImgDOM=DCgetPath(oScene).szPath+".all."+szImg+DCgetName(oScene);
	szImage = '<IMG SRC="'+name+'">';
	aD = getImgDims(name);
	vertPos = DCgetH(oScene)-y-((mode)?aD[1]:0);
	oImg = DCcreate(szImgDOM, x, vertPos, DCgetW(oScene), aD[1],"clear");
	DCshow(oImg, true);
	DCsetContent(oImg, szImage);
	DCsetZindex(oImg, z);
}

function placeStaticStretch(name, y, mode, z)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before static item "+name);
		return
	}
	preLoadImgs(name);
	gaPostLoad[gaPostLoad.length] = "placeStaticStretchPL('"+name+"', "+y+", "+mode+", "+z+", "+currentScene+")";
}

function placeStaticStretchPL(name, y, mode, z, sceneIndex)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before stretched static item "+name);
		return
	}
	oScene = gaAllScenes[sceneIndex];
	szImg=DCgetPath(oScene).szPath+".all."+name.split(".")[0]+DCgetName(oScene);
	aD = getImgDims(name);
	szImageStretch = '<IMG SRC="'+name+'" width=100% height='+aD[1]+'>';

	vertPos = DCgetH(oScene)-y-((mode)?aD[1]:0);
	sceneW = DCgetW(oScene)
	oImg = DCcreate(szImg, 0, vertPos, ((sceneW<aD[0])?aD[0]:sceneW), aD[1],"clear");
	DCshow(oImg, true);
	DCsetContent(oImg, szImageStretch);
	DCsetZindex(oImg, z);
}

function placeStaticRepeat(name, y, mode, z)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before static item "+name);
		return
	}
	preLoadImgs(name);
	gaPostLoad[gaPostLoad.length] = "placeStaticRepeatPL('"+name+"', "+y+", "+mode+", "+z+", "+currentScene+")";
}

function placeStaticRepeatPL(name, y, mode, z, sceneIndex)
{
	if(errorLockout)return;
	if(currentScene<0)
	{
		DCalert("You must define a scene before repeated static item "+name);
		return
	}
	oScene = gaAllScenes[sceneIndex];
	szImg=DCgetPath(oScene).szPath+".all."+name.split(".")[0]+DCgetName(oScene);
	aD = getImgDims(name);
	szImageRepeat = '<IMG SRC="'+name+'">';
	for(i=1; i < Math.ceil(DCgetW(oScene)/aD[0]); i++)szImageRepeat+='<IMG SRC="'+name+'">';
	vertPos = DCgetH(oScene)-y-((mode)?aD[1]:0);
	oImg = DCcreate(szImg, 0, vertPos, aD[0]*i, aD[1],"clear");
	DCsetContent(oImg, szImageRepeat);
	DCsetZindex(oImg, z);
	DCshow(oImg, true);
}

function allignScene(oScene)
{
	if(typeof(gaSceneDims[oScene.sName])=="object")
	{DCflyToAnchor(oScene, oScene.sName+"A")}
	else
	{
		szIMG = DC_FRAMEpath+"document.images."+oScene.sName+"I";
		oIMG = eval(szIMG)
		DCwhereIs(oIMG);
		DCmoveTo(oScene, oIMG.LEFT, oIMG.TOP);
		DCshow(oScene, true);
	}
}

function allignAllScenes()
{
	for(var i=0; i < gaAllScenes.length; i++)
	{
		oScene = gaAllScenes[i];
		allignScene(oScene);
	}
}

function startAllScenes()
{
	doRep = 0;
	for(i=0; i < gaAllScenes.length; i++)
	{
		oScene = gaAllScenes[i];
		if(!oScene.started)
		{
			if(DCgetW(oScene)!=1 && DCgetH(oScene)!=1)
			{
				for(var j=0; j < oScene.trackList.length; j++)
				{
					oTrack = oScene.trackList[j];
					oTrack.currentTrain = -1;
					nextTrain(oScene, oTrack);
				}
				allignScene(oScene);
				oScene.started=1;
			}else{
				doRep = 1;
			}
		}
	}
	if(doRep)setTimeout("startAllScenes()", 1000);
}

var loadCount = 0;
function checkImgLoad()
{
	var done=true;
	for(i in gaAllImgs)
	{
		if(typeof gaAllImgs[i]=='object')
		{
			if(!gaAllImgs[i].complete){done=false;break;}
		}
	}
	if(done || loadCount++ >= 100)
	{
		clearInterval(oTimer);oTimer=null;
		for(i in gaPostLoad)eval(gaPostLoad[i]);
		startAllScenes();
		setInterval("moveAllTrains()", normalDelay);
	}
}

function autoexec()
{
	if(typeof(traingifSetup)=='undefined')
	{
		DCalert("You must define the function traingifSetup() in your HTML file.");
		return;
	}
	if(DC_IE){window.onresize = allignAllScenes};
	traingifSetup();
	oTimer=setInterval("checkImgLoad()", 100);
}


