// gemachine.js

google.load("earth", "1");
google.load("maps", "2.99");  // For JS geocoder
var ge = null;
var geocoder = null;
var cam = null;
//var waypoints = new Array();
var catchKeys = true;
var playState = false;
var tracks = Array();
var curTrackIndex = 0;
var curCamTrackIndex = 0;
var dbug = 0;
var theCam = null;
var projectName = '';

function sanity()
{
	if (!dbug)
		return;
	if (tracks.length < 1)
		return;
//	if (Math.floor(tracks[0].mover.localAnchorLla[0]) != 51)
//	if (Math.floor(tracks[0].mover.localAnchorLla[0]) != 0)
//		alert ('dammit llaz track ');
	for (var i = 0; i < tracks.length; i++)
	{
		for (var j = 0; j < 3; j++)
		{
			if (tracks[i].mover.localAnchorLla[j] == NaN || tracks[i].mover.localAnchorLla[j] == undefined)
				alert ('dammit lla track '+i);
			if (tracks[i].mover.localAnchorCartesian[j] == NaN || tracks[i].mover.localAnchorCartesian[j] == undefined)
				alert ('dammit llaC track '+i);
		}
	}
}

function dbugit()
{
	d = document.getElementById('dbugdiv');
	if (!d)
		return;

	var h = '';
	for (t = 0; t < tracks.length; t++)
	{
		h += 'Track ' + t + ' ' + tracks[t].trackType + '<br>';
		if (!tracks[t].waypoints)
			h += ' no waypoints at all';
		else
		{
			h += tracks[t].waypoints.length + ' waypoints';

		}
		h += '<br>';
	}
	d.innerHTML = h;
}

String.prototype.trim = function ()
{
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

function createAjaxRq()
{
	try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {}
	try { return new ActiveXObject("Msxml4.XMLHTTP"); } catch (e) {}
	try { return new ActiveXObject("Msxml3.XMLHTTP"); } catch (e) {}
	try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {}
	try { return new XMLHttpRequest(); } catch(e) {}
	return null;
}

//----------------------------------------------------------------------------
// Input Handlers
//----------------------------------------------------------------------------

function kmlKeyDown(event)
{
	var d = 0;
}

function kmlKeyUp(event)
{
	var d = 0;
}

function keyDown(event)
{
	var mvr = theCam;
	var cam = theCam;

	if (tracks[curTrackIndex].trackType == 'Model')
		mvr = tracks[curTrackIndex].mover;

	if (!event)
		event = window.event;

	if (!catchKeys)
	{
	    event.returnValue = true;
		return true;
	}

	if (event.keyCode == 13) // Enter, record view
	{
	    event.returnValue = false;
		recordCam();
	}

	if (event.keyCode == 33) {  // Altitude Up
		if (event.shiftKey)
			mvr.altitudeUp = true;
		else
			cam.altitudeUp = true;
		event.returnValue = false;
	}
	else if (event.keyCode == 34) {  // Altitude Down
		if (event.shiftKey)
			mvr.altitudeDown = true;
		else
			cam.altitudeDown = true;
		event.returnValue = false;
	}
	else if (event.keyCode == 37) {  // Turn Left.
		if (event.shiftKey)
			mvr.turnLeft = true;
		else
			cam.turnLeft = true;
		event.returnValue = false;
	}
	else if (event.keyCode == 39) {  // Turn Right.
		if (event.shiftKey)
			mvr.turnRight = true;
		else
			cam.turnRight = true;
		event.returnValue = false;
  } else if (event.keyCode == 38) {  // Tilt Up.
    mvr.tiltUp = true;
    event.returnValue = false;
  } else if (event.keyCode == 40) {  // Tilt Down.
    mvr.tiltDown = true;
    event.returnValue = false;
  } else if (event.keyCode == 81) {  // roll Left
    mvr.rollLeft = true;
    event.returnValue = false;
  } else if (event.keyCode == 69) {  // roll Right
    mvr.rollRight = true;
    event.returnValue = false;
  } else if (event.keyCode == 65 ||
             event.keyCode == 97) {  // Strafe Left.
    mvr.strafeLeft = true;
    event.returnValue = false;
  } else if (event.keyCode == 68 ||
             event.keyCode == 100) {  // Strafe Right.
    mvr.strafeRight = true;
    event.returnValue = false;
  } else if (event.keyCode == 87 ||
             event.keyCode == 119) {  // Move Forward.
    mvr.moveForward = true;
    event.returnValue = false;
  } else if (event.keyCode == 83 ||
             event.keyCode == 115) {  // Move Forward.
    mvr.moveBackward = true;
  } else {
    return true;
  }
  return false;
}

function keyUp(event)
{
//	var mvr = tracks[curTrackIndex].mover;
	var mvr = theCam;
	var cam = theCam;

	if (tracks[curTrackIndex].trackType == 'Model')
		mvr = tracks[curTrackIndex].mover;

	if (!event)
		event = window.event;

  if (event.keyCode == 33) {  // Altitude Up
		if (event.shiftKey)
			mvr.altitudeUp = false;
		else
			cam.altitudeUp = false;
    event.returnValue = false;
  } else if (event.keyCode == 34) {  // Altitude Down
		if (event.shiftKey)
			mvr.altitudeDown = false;
		else
			cam.altitudeDown = false;
    event.returnValue = false;
  } else if (event.keyCode == 37) {  // Left.
		if (event.shiftKey)
		    mvr.turnLeft = false;
		else
		    cam.turnLeft = false;
		event.returnValue = false;
  } else if (event.keyCode == 39) {  // Right.
		if (event.shiftKey)
			mvr.turnRight = false;
		else
			cam.turnRight = false;
    event.returnValue = false;
  } else if (event.keyCode == 38) {  // Up.
    mvr.tiltUp = false;
    event.returnValue = false;
  } else if (event.keyCode == 40) {  // Down.
    mvr.tiltDown = false;
    event.returnValue = false;
 } else if (event.keyCode == 81) {  // Left.
    mvr.rollLeft = false;
    event.returnValue = false;
  } else if (event.keyCode == 69) {  // Right.
    mvr.rollRight = false;
    event.returnValue = false;
  } else if (event.keyCode == 65 ||
             event.keyCode == 97) {  // Strafe Left.
    mvr.strafeLeft = false;
    event.returnValue = false;
  } else if (event.keyCode == 68 ||
             event.keyCode == 100) {  // Strafe Right.
    mvr.strafeRight = false;
    event.returnValue = false;
  } else if (event.keyCode == 87 ||
             event.keyCode == 119) {  // Move Forward.
    mvr.moveForward = false;
    event.returnValue = false;
  } else if (event.keyCode == 83 ||
             event.keyCode == 115) {  // Move Forward.
    mvr.moveBackward = false;
  }
  return false;
}

var nextTrackId = 0;
function track()
{
	this.trackType = '';
	this.id = nextTrackId;
	nextTrackId++;
	this.name = '';
	this.shakiness = 0;
	this.loop = false;
	this.waypoints = new Array();
	this.curWaypointIndex = 0;
	this.mover = null; // derives from moverClass
	this.playWaypoint = 0;
	this.playFraction = 0;
	this.playTween = 0;
	this.playing = false;
	sanity();
}

function numCameras()
{
	var n = 0;
	for (var t = 0; t < tracks.length; t++)
		if (tracks[t].trackType == 'Camera')
			n++;
	return n;
}

function trackFromId (id)
{
	for (var t = 0; t < tracks.length; t++)
		if (id == tracks[t].id)
			return t;
	return -1;
}

cameraTrack = function(edit)
{
//	if (edit)
	this.mover = new FirstPersonCam(false);
	this.trackType = 'Camera';
	this.name = 'Camera ' + (this.id + 1);
	sanity();
};
cameraTrack.prototype = new track();

cameraTrack.prototype.getDiv = function ctgd()
{
	sanity();
	var t = trackFromId (this.id);
	var d = '';
//	d += "<table>";
	d += "<table style='font-size:80%'>";

	d += "<tr><td colspan='6'>Track name:<input size='25' value='"+this.name+"' id='camtrkname-"+t+"' onfocus='setCatchKeys(false)' onblur='setTrackName("+t+")'></td>";
	d += "<td colspan='5'>Loop:<input type='checkbox' onclick='setLoop(this.checked)' id='loop'";
	if (this.loop)
		d += " CHECKED";
	d += " /></td></tr>";

	d += "<tr><td>&nbsp;</td><td>&nbsp;</td><td>#</td><td>Name</td><td>Lat</td><td>Lon</td><td>Alt</td><td>Fly?</td><td>Heading</td><td>Tilt</td><td>Roll</td>";
	d += "<td>Time</td><td>Duration</td>";
//	d += "<td>Tweens</td>";
	d += "</tr>";
	for (var i=0; i < this.waypoints.length; i++)
	{
		this.waypoints[i].id = i;
		d += this.waypoints[i].getDiv(t,(i == this.waypoints.length-1));
	}
	d += "</table>";
	return d;
	sanity();
};

modelTrack = function()
{
	this.url = '';
	this.trackType = 'Model';
	this.mover = new model();
	this.waypoints[0] = new waypoint();
	this.placemark = null;
	this.name = 'Model ' + (this.id + 1);
	sanity();
};
modelTrack.prototype = new track();

modelTrack.prototype.loadModel = function mtlm(kml)
{
	this.removeModel();
	if (!this.url)
		return;
	else if (this.url.indexOf('.dae') > 0)
		this.makeModel(this.url);
	else
	{
		var that = this;
		that.scheduleKml();
//		google.earth.fetchKml(ge, this.url, function(obj) { that.finishInit(obj); });
	}
}

modelTrack.prototype.scheduleKml = function mtscheduleKml()
{
//		google.earth.fetchKml(ge, trackui.value, function(obj) { tracks[curTrackIndex].finishInit(obj); });

//tracks[t].url = 'http://sketchup.google.com/3dwarehouse/download?mid=3c9a1cac8c73c61b6284d71745f1efa9&rtyp=zip&fn=milktruck&ctyp=milktruck';
	var that = this;
	var u = this.url;
	google.earth.fetchKml(ge, u, function (obj)
		{
			that.finishInit(obj);
		}
	);
}

modelTrack.prototype.finishInit = function mtfininit(kml)
{
	sanity();
	// The model zip file is actually a kmz, containing a KmlFolder with
	// a camera KmlPlacemark (we don't care) and a model KmlPlacemark
	// (our milktruck).
	if (!kml)
		return;
	this.placemark = kml.getFeatures().getChildNodes().item(1);
	this.mover.geMover = this.placemark.getGeometry();
	this.mover.geMover.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);
	this.mover.orientation = this.mover.geMover.getOrientation();
	this.mover.location = this.mover.geMover.getLocation();
	// Set model at current active camera's position (on the ground)
	var lla = this.waypoints[0].lla;
	this.mover.localAnchorLla = lla;
	this.mover.localAnchorCartesian = V3.latLonAltToCartesian(this.mover.localAnchorLla);
	this.mover.location.setLatLngAlt (lla[0],lla[1],lla[2]);
	this.mover.headingAngle = this.waypoints[0].heading;
	this.mover.tiltAngle = this.waypoints[0].tilt;
	this.mover.rollAngle = this.waypoints[0].roll;
	ge.getFeatures().appendChild(this.placemark);
	sanity();
}

modelTrack.prototype.makeModel = function mtmakeModel(url)
{
	this.placemark = ge.createPlacemark('');
	this.placemark.setName('myModel');
	this.mover.geMover = ge.createModel('');
	this.placemark.setGeometry(this.mover.geMover);
	this.mover.location = ge.createLocation('');
	var mlink = ge.createLink('');

	// A textured model created in Sketchup and exported as Collada.
	mlink.setHref(url);
	this.mover.geMover.setLink(mlink);

	var lla = this.waypoints[0].lla;
	this.mover.localAnchorLla = lla;
	this.mover.localAnchorCartesian = V3.latLonAltToCartesian(this.mover.localAnchorLla);
	this.mover.location.setLatLngAlt (lla[0],lla[1],lla[2]);
	this.mover.headingAngle = this.waypoints[0].heading;
	this.mover.tiltAngle = this.waypoints[0].tilt;
	this.mover.rollAngle = this.waypoints[0].roll;

	this.mover.location.setLatitude(lla[0]);
	this.mover.location.setLongitude(lla[1]);
	this.mover.location.setAltitude(lla[2]);
	this.mover.geMover.setLocation(this.mover.location);

	this.mover.orientation = ge.createOrientation('');
	this.mover.orientation.setHeading(this.mover.headingAngle);
	this.mover.orientation.setTilt(this.mover.tiltAngle);
	this.mover.orientation.setRoll(this.mover.rollAngle);
	this.mover.geMover.setOrientation(this.mover.orientation);

	this.mover.geMover.setAltitudeMode(ge.ALTITUDE_RELATIVE_TO_GROUND);

	ge.getFeatures().appendChild(this.placemark);
}

modelTrack.prototype.removeModel = function mtremoveModel()
{
	if (this.placemark)
		ge.getFeatures().removeChild(this.placemark);
	this.placemark = null;
}

modelTrack.prototype.getDiv = function ctgd()
{
	sanity();
	var t = trackFromId (this.id);
	var d = '';
	d += "<table style='font-size:90%'>";
//this.url = 'http://sketchup.google.com/3dwarehouse/download?mid=3c9a1cac8c73c61b6284d71745f1efa9&rtyp=zip&fn=milktruck&ctyp=milktruck';
	d += "<tr><td colspan='6'>Track name:<input size='15' value='"+this.name+"' id='mdltrkname-"+t+"' onfocus='setCatchKeys(false)' onblur='setTrackName("+t+")'>";
	d += "<td colspan='3'>Loop:<input type='checkbox' onclick='setLoop(this.checked)' id='loop'";
	if (this.loop)
		d += " CHECKED";
	d += " /></td>";
	d += "<td colspan='4'>Model Url:<input size='35' value='"+this.url+"' id='mdl_"+t+"' onfocus='setCatchKeys(false)' onblur='setCatchKeys(true)'>";
	d += "<input type='button' value='Load' onClick='setModelUrl("+t+")'></td></tr>";
	d += "<tr><td>&nbsp;</td><td>&nbsp;</td><td>#</td><td>Name</td><td>Lat</td><td>Lon</td><td>Alt</td><td>Fly?</td><td>Heading</td><td>Tilt</td><td>Roll</td>";
	d += "<td>Time</td><td>Duration</td>";
//	d += "<td>Tweens</td>";
	d += "</tr>";
	for (var i=0; i < this.waypoints.length; i++)
	{
		this.waypoints[i].id = i;
		d += this.waypoints[i].getDiv(t,(i == this.waypoints.length-1));
	}
	d += "</table>";
	sanity();
	return d;
};

function waypoint()
{
	this.id = 0;
	this.name = '';
//	this.lla = [37.79333, -122.40, 10000];
	this.lla = [0,0,2];
	this.heading = 0;
	this.tilt = 0;
	this.roll = 0;
	this.time = 0;
	this.duration = 3;
	this.tweens = 20;
	this.altitudeAbsolute = false;
	return this;
}

waypoint.prototype.getDiv = function wpgd(trackId,last)
{
	sanity();
	var dummy = 0;
	var d = "";
//	d += "<div><table id='evt_"+this.id+"'>";
	d += "<tr id='evt_"+this.id+"'>";
	d += "<td><a href='javascript:tracks["+trackId+"].gotoWaypointId("+this.id+")'><img border='0' alt='Go to and edit this location' src='images/edit.png'></a></td>";
	d += "<td><a href='javascript:deleteWaypoint("+this.id+")'><img border='0' alt='Delete this view' src='images/delete.png'></a></td>";
	d += "<td>"+this.id+"</td>";
	d += "<td><input size='5' id='nam_"+this.id+"' value = '"+this.name+"' onfocus='setCatchKeys(false)' onblur='setName("+this.id+")'></td>";
	d += "<td><input size='5' id='lat_"+this.id+"' value = '"+this.lla[0]+"' onfocus='setCatchKeys(false)' onblur='setLat("+this.id+")'></td>";
	d += "<td><input size='5' id='lon_"+this.id+"' value = '"+this.lla[1]+"' onfocus='setCatchKeys(false)' onblur='setLon("+this.id+")'></td>";
	d += "<td><input size='5' id='alt_"+this.id+"' value = '"+this.lla[2]+"' onfocus='setCatchKeys(false)' onblur='setAlt("+this.id+")'></td>";
	if (this.altitudeAbsolute)
		d += "<td><input type='checkbox' id='mod_"+this.id+"' checked onclick='setAltMode("+this.id+")'></td>";
	else
		d += "<td><input type='checkbox' id='mod_"+this.id+"' onclick='setAltMode("+this.id+")'></td>";
	d += "<td><input size='4' id='hed_"+this.id+"' value = '"+this.heading+"' onfocus='setCatchKeys(false)' onblur='setHeading("+this.id+")'></td>";
	d += "<td><input size='4' id='til_"+this.id+"' value = '"+this.tilt+"' onfocus='setCatchKeys(false)' onblur='setTilt("+this.id+")'></td>";
	d += "<td><input size='4' id='rol_"+this.id+"' value = '"+this.roll+"' onfocus='setCatchKeys(false)' onblur='setRoll("+this.id+")'></td>";
	d += "<td><input id='tim_"+this.id+"' value = '"+this.time+"' type='text' size='4' onfocus='setCatchKeys(false)' onblur='recalcTime("+this.id+")'><img src='js/cal.gif' border='0' alt='Pick a date' onclick='javascript:NewCal(\"tim_"+this.id+"\",\"ddmmmyyyy\",true,12)'></td>";
	d += "<td><input size='3' id='dur_"+this.id+"' value = '"+this.duration+"' onfocus='setCatchKeys(false)' onblur='recalcDuration("+this.id+")'></td>";
//	if (!last)
//		d += "<td><input size='3'  id='twn_"+this.id+"' value = '"+this.tweens+"' onfocus='setCatchKeys(false)' onblur='setTweens("+this.id+")'></td>";
//	d += '</table>';
	sanity();
	return d;
};

track.prototype.getTween = function ggetTween(start, fraction) // from start index, fractional amount between start and next
{
	sanity();
	var end;
	if (fraction == 0)
		end = 0;
	else
		end = 1;
	var startWaypoint = this.waypoints[start];
	var endWaypoint = this.waypoints[start+end];
	var t = new waypoint();
	t.lla[0] = (startWaypoint.lla[0]+fraction*(endWaypoint.lla[0]-startWaypoint.lla[0]));
	t.lla[1] = (startWaypoint.lla[1]+fraction*(endWaypoint.lla[1]-startWaypoint.lla[1]));
	t.lla[2] = (startWaypoint.lla[2]+fraction*(endWaypoint.lla[2]-startWaypoint.lla[2]));
	t.heading = (startWaypoint.heading+fraction*(endWaypoint.heading-startWaypoint.heading));
	t.tilt = (startWaypoint.tilt+fraction*(endWaypoint.tilt-startWaypoint.tilt));
	t.roll = (startWaypoint.roll+fraction*(endWaypoint.roll-startWaypoint.roll));
	t.altitudeAbsolute = startWaypoint.altitudeAbsolute;
	sanity();
	return t;
};

moverClass.prototype.gotoWaypoint = function mcg2wp(w)
{
	sanity();
	if (!w)
		return;
/*
		tracks[curTrackIndex].mover.localAnchorLla = w.lla;
		tracks[curTrackIndex].mover.localAnchorCartesian = V3.latLonAltToCartesian(tracks[curCamTrackIndex].mover.localAnchorLla);
		tracks[curTrackIndex].mover.movereraAltitude = w.lla[2];
		tracks[curTrackIndex].mover.headingAngle = w.heading;
		tracks[curTrackIndex].mover.tiltAngle = w.tilt;
		tracks[curTrackIndex].mover.rollAngle = w.roll;
		tracks[curTrackIndex].mover.altMode = w.altitudeAbsolute;
	//	supressUpdateKluge = true;
		tracks[curTrackIndex].mover.updateGE();
	//	supressUpdateKluge = false;
*/
	this.localAnchorLla = w.lla;
	this.localAnchorCartesian = V3.latLonAltToCartesian(this.localAnchorLla);
//	this.cameraAltitude = w.lla[2];
	this.headingAngle = w.heading;
	this.tiltAngle = w.tilt;
	this.rollAngle = w.roll;
	this.altMode = w.altitudeAbsolute;
	this.updateGE();
};

track.prototype.gotoTween = function fgotoTween(start, fraction)
{
	sanity();
	var t = this.getTween(start, fraction);
	if (this.trackType == 'Camera')
		theCam.gotoWaypoint(t);
	else
		this.mover.gotoWaypoint(t);
	sanity();
};

function onTick()
{
//	tracks[curCamTrackIndex].mover.update();
	theCam.update();
	for (var t = 0; t < tracks.length; t++)
	{
		if (tracks[t].trackType == 'Model')
			tracks[t].mover.update();
	}
}

function player()
{
	this.tweenCB = null;
	this.timer = null;
}
//hiliteWaypointId
player.prototype.stop = function player_stop()
{
	sanity();
	this.playState = false;
	for (var t=0; t < tracks.length; t++)
	{
		tracks[t].playWaypoint = 0;
		tracks[t].playFraction = 0;
		tracks[t].playTween = 0;
		tracks[t].playing = false;
	}
	if (this.tweenCB)
		this.tweenCB(this.playWaypoint);
	if (this.timer)
		clearTimeout (this.timer);
}

player.prototype.pause = function player_pause(resume)
{
	sanity();
	this.playState = resume;
	for (var t=0; t < tracks.length; t++)
	{
		tracks[t].playing = resume;
	}
}

player.prototype.play = function player_play(reset)
{
	var that = this;
	var duration = 1;
	if (reset)
	{
		this.stop();
		for (var t = 0; t < tracks.length; t++)
			if (tracks[t].waypoints.length > 0)
				tracks[t].playing = true;
	}

	for (var t = 0; t < tracks.length; t++)
	{
		if (!tracks[t].playing || (curCamTrackIndex != t && tracks[t].trackType == 'Camera'))
			continue;

		if (tracks[t].playWaypoint >= tracks[t].waypoints.length)
		{
			if (tracks[t].loop)
			{
				tracks[t].playWaypoint = 0;
				tracks[t].playTween = 0;
				duration = .0001;
			}
			else
			{
//				this.stop();
				tracks[t].playWaypoint = 0;
				tracks[t].playFraction = 0;
				tracks[t].playTween = 0;
				tracks[t].playing = false;
				var j;
				for (j=0; j < tracks.length; j++)
					if (tracks[j].playing)
						break;
				if (j == tracks.length) // all done
					return; // stop playing
			}
		}
		this.playState = true;
		tracks[t].gotoTween(tracks[t].playWaypoint, tracks[t].playFraction);
		tracks[t].playTween++;
		if (tracks[t].playTween >= tracks[t].waypoints[tracks[t].playWaypoint].tweens)
		{
			tracks[t].playTween = 0;
			tracks[t].playFraction = 0;
			tracks[t].playWaypoint++;
			if (tracks[t].playWaypoint >= tracks[t].waypoints.length)
			{
				if (tracks[t].loop)
				{
					tracks[t].playWaypoint = 0;
					duration = .0001;
				}
				else
				{
					tracks[t].playing = false;
					var j;
					for (j=0; j < tracks.length; j++)
						if (tracks[j].playing)
							break;
					if (j == tracks.length) // all done
						return; // stop playing
				}
			}
			if (this.tweenCB)
				this.tweenCB(tracks[t].playWaypoint);
		}
		if (tracks[t].playing)
		{
			if (tracks[t].waypoints[tracks[t].playWaypoint].tweens > 0 && tracks[t].playWaypoint < (tracks[t].waypoints.length-1))
			{
				tracks[t].playFraction = tracks[t].playTween / tracks[t].waypoints[tracks[t].playWaypoint].tweens;
				duration = tracks[t].waypoints[tracks[t].playWaypoint].duration / tracks[t].waypoints[tracks[t].playWaypoint].tweens;
			}
			else if (tracks[t].loop && tracks[t].playWaypoint == (tracks[t].waypoints.length-1))
				duration = .0001;
		}
	}
	this.timer = setTimeout (function () { that.play(false); }, duration * 1000);
};

function loadProject(projId,edit,onLoadCB)
{
	projectId = projId;
	var url = 'getProject.php?projId='+projId+'&rid='+Math.random();
	var ajaxRq = createAjaxRq();
    ajaxRq.onreadystatechange = function ()
	{
        if (ajaxRq.readyState == 4)
		{
			if (ajaxRq.status == 200)
			{
				newProject();
				dbugit();
				var projs = ajaxRq.responseXML.getElementsByTagName("project");
				if (projs.length > 0)
				{
					projectName = projs[0].firstChild.nodeValue.trim();
				}

				projectDesc = '';
				var descs = ajaxRq.responseXML.getElementsByTagName("description");
				if (descs.length > 0)
				{
					if (descs[0].firstChild && descs[0].firstChild.nodeValue)
						projectDesc = descs[0].firstChild.nodeValue.trim();
				}

				var incomingTracks = ajaxRq.responseXML.getElementsByTagName("Folder");
				if (incomingTracks.length > 0)
				{
					curTrackIndex = 0;
					curCamTrackIndex = 0;
//					tracks = new Array (new waypoint);
					for (var t = 0; t < incomingTracks.length; t++)
					{
						var incomingTrack = incomingTracks[t];
						var trackType = incomingTrack.getElementsByTagName("tracktype")[0].firstChild.nodeValue
						if (trackType == 'Camera')
							tracks[t] = new cameraTrack(edit);
						else if (trackType == 'Model')
							tracks[t] = new modelTrack();
						else
							tracks[t] = new modelTrack();
						tracks[t].trackType = trackType;
						tracks[t].id = t;
						tracks[t].name = incomingTrack.getElementsByTagName("name")[0].firstChild?incomingTrack.getElementsByTagName("name")[0].firstChild.nodeValue.trim() : '';
						tracks[t].loop = parseInt(incomingTrack.getElementsByTagName("loop")[0].firstChild.nodeValue);
						tracks[t].shakiness = parseFloat(incomingTrack.getElementsByTagName("shakiness")[0].firstChild.nodeValue);
						if (trackType == 'Model' && incomingTrack.getElementsByTagName("url")[0].firstChild)
							tracks[t].url = unescape(incomingTrack.getElementsByTagName("url")[0].firstChild.nodeValue.trim());
						var items = incomingTrack.getElementsByTagName("Placemark");
						if (items.length > 0)
						{
							// NOTE: FIX THIS
							tracks[t].waypoints = new Array();
							tracks[t].curWaypointIndex = 0;
							for (var i = 0; i < items.length; i++)
							{
								var placemark = items[i];
								var cameras = placemark.getElementsByTagName("Camera");
								if (tracks[t].trackType == 'Camera' && cameras.length > 0)
								{
//									tracks[t].mover.shakiness = tracks[t].shakiness;
									for (var j = 0; j < cameras.length; j++)
									{
										var camera = cameras[j];
										var wp = new waypoint();
										wp.id = i;
										var name = camera.getAttribute("id");
										wp.name = name;
										wp.lla[0] = parseFloat(camera.getElementsByTagName("latitude")[0].firstChild.nodeValue);
										wp.lla[1] = parseFloat(camera.getElementsByTagName("longitude")[0].firstChild.nodeValue);
										wp.lla[2] = parseFloat(camera.getElementsByTagName("altitude")[0].firstChild.nodeValue);
										wp.heading = parseFloat(camera.getElementsByTagName("heading")[0].firstChild.nodeValue);
										wp.tilt = parseFloat(camera.getElementsByTagName("tilt")[0].firstChild.nodeValue);
										wp.roll = parseFloat(camera.getElementsByTagName("roll")[0].firstChild.nodeValue);
										wp.time = parseFloat(camera.getElementsByTagName("time")[0].firstChild.nodeValue);
										wp.duration = parseFloat(camera.getElementsByTagName("duration")[0].firstChild.nodeValue);
										wp.tweens = parseFloat(camera.getElementsByTagName("tweens")[0].firstChild.nodeValue);
										var altMode = camera.getElementsByTagName("altitudeMode")[0].firstChild.nodeValue;
										if (altMode == 'absolute')
											wp.altitudeAbsolute = true;
										else
											wp.altitudeAbsolute = false;
										tracks[t].curWaypointIndex = tracks[t].waypoints.length;
										tracks[t].waypoints[tracks[t].waypoints.length] = wp;
									} // for all cams
								}

								var models = placemark.getElementsByTagName("Model");
								if (tracks[t].trackType == 'Model' && models.length > 0)
								{
									for (var j = 0; j < models.length; j++)
									{
										var model = models[j];
										var wp = new waypoint();
										wp.id = i;
										var name = model.getAttribute("id");
										wp.name = name;
										wp.lla[0] = parseFloat(model.getElementsByTagName("latitude")[0].firstChild.nodeValue);
										wp.lla[1] = parseFloat(model.getElementsByTagName("longitude")[0].firstChild.nodeValue);
										wp.lla[2] = parseFloat(model.getElementsByTagName("altitude")[0].firstChild.nodeValue);
										wp.heading = parseFloat(model.getElementsByTagName("heading")[0].firstChild.nodeValue);
										wp.tilt = parseFloat(model.getElementsByTagName("tilt")[0].firstChild.nodeValue);
										wp.roll = parseFloat(model.getElementsByTagName("roll")[0].firstChild.nodeValue);
										wp.time = parseFloat(model.getElementsByTagName("time")[0].firstChild.nodeValue);
										wp.duration = parseFloat(model.getElementsByTagName("duration")[0].firstChild.nodeValue);
										wp.tweens = parseFloat(model.getElementsByTagName("tweens")[0].firstChild.nodeValue);
										var altMode = model.getElementsByTagName("altitudeMode")[0].firstChild.nodeValue;
										if (altMode == 'absolute')
											wp.altitudeAbsolute = true;
										else
											wp.altitudeAbsolute = false;

										if (model.getElementsByTagName("Link").length > 0)
										{
											var link = model.getElementsByTagName("Link")[0].firstChild.nodeValue;
											if (link)
											{
												wp.url = link.getElementsByTagName("href")[0].firstChild.nodeValue;
											}
										}
										tracks[t].curWaypointIndex = tracks[t].waypoints.length;
										tracks[t].waypoints[tracks[t].waypoints.length] = wp;
									} // for all objs
								}
							} //for all waypoints
							if (tracks[t].trackType == 'Model' && tracks[t].url)
								tracks[t].loadModel();
						} // if waypoints
					} // for all tracks
				} // if tracks
				if (onLoadCB)
					onLoadCB();
			}
		}
	};

	ajaxRq.open("GET", url, true);
	ajaxRq.send(null);
}


