/*
* All rights reserved.
* copyright (c) 2005 Chris Lacy
*/

// factory class
function TravellerFactory() {}

TravellerFactory.travellerArray = [];

function TravellerFactory_createTravellers(gpx_url, maxTrkpts) {

	var request =  new XMLHttpRequest();
	request.open("GET", gpx_url, true);
	request.setRequestHeader("Content-Type",
		"application/x-javascript;");
 
	request.onreadystatechange = function() {
		if (request.readyState == 4 && request.status == 200) {
			if (request.responseXML) {
				TravellerFactory.initialize(request.responseXML, maxTrkpts);
			}
		}
	};
	request.send(null);

}
TravellerFactory.createTravellers = TravellerFactory_createTravellers;

TravellerFactory.initialize = function(xmlDoc, maxTrkpts) {
	
	var error = null;
	var travellerArray = [];
	var trkElements = xmlDoc.getElementsByTagName('trk');
	
	for(var j=0; j<trkElements.length; j++) {
		
		var colorContainer = ColorContainerFactory.createColorContainer();
		var traveller = new Traveller(colorContainer, maxTrkpts);
		var trkElementNameElementArray = trkElements[j].getElementsByTagName('name');

		if(trkElementNameElementArray != null && trkElementNameElementArray.length > 0) {
			var te = trkElementNameElementArray[0];
			if(te != null) {
				traveller.trkName = te.firstChild.nodeValue;
			}
		}

		if(traveller.trkName == null || traveller.trkName == "") {
			traveller.trkName = j.toString();
		}
		var trkptElements = trkElements[j].getElementsByTagName('trkpt');
		
		// time kludge
		var tempTrkptElement = trkptElements[0];
		if(tempTrkptElement.getElementsByTagName('time')[0] == null) {
			alert("No time elements, so tracking won't work. Will try to display waypoints.");
			trkptElements = [];
		}
		else {
			var temp2dArray = [];
			for(var i=0; i<trkptElements.length; i++) {
				var trkptElement = trkptElements[i];
				var lat = parseFloat(trkptElement.getAttribute('lat'));
		        var lon = parseFloat(trkptElement.getAttribute('lon'));
		        var time = TimeUtil.timeToNumber(trkptElement.getElementsByTagName('time')[0].firstChild.nodeValue);
		        
		        if(traveller.maxLat == null || traveller.maxLat < lat) {
		        	traveller.maxLat = lat;
		        }
		        if(traveller.minLat == null || traveller.minLat > lat) {
		        	traveller.minLat = lat;
		        }
		        if(traveller.maxLon == null || traveller.maxLon < lon) {
		        	traveller.maxLon = lon;
		        }
		        if(traveller.minLon == null || traveller.minLon > lon) {
		        	traveller.minLon = lon;
		        }
		        if(traveller.maxTime == null || traveller.maxTime < time) {
		        	traveller.maxTime = time;
		        }
		        if(traveller.minTime == null || traveller.minTime > time) {
		        	traveller.minTime = time;
		        }
		
				temp2dArray[i] = [time, new LatLon(lat, lon)];
			}
			for(var i=0; i<temp2dArray.length; i++) {
				traveller.timeToLatLonArray[temp2dArray[i][0] - traveller.minTime] = temp2dArray[i][1];
			}
	
			traveller.createWaypointLatLonArray(xmlDoc);
			traveller.assignCenterLatLon();
			travellerArray[j] = traveller;
		}
	}

	if(travellerArray.length == 0) {
		var colorContainer = ColorContainerFactory.createColorContainer();
		var traveller = new Traveller(colorContainer, maxTrkpts);
		traveller.createWaypointLatLonArray(xmlDoc);
		var latLon = traveller.waypointLatLonArray[0];
		
		if(latLon == null || latLon.getLat() == null) {
			travellerArray = [];
			error = new Error("Sorry, can't display your data: no trk or waypoint elements");
		}
		else {
			traveller.minLat = latLon.getLat() - 1.0;
			traveller.maxLat = latLon.getLat() + 1.0;
			traveller.maxLon = latLon.getLon() + 1.0;
			traveller.minLon = latLon.getLon() - 1.0;
	
			traveller.minTime = ((new Date()).valueOf()/100) - 10;
			traveller.maxTime = ((new Date()).valueOf()/100) + 10;
			traveller.centerLatLon = latLon;
			traveller.timeToLatLonArray[0] = new LatLon(traveller.minLat, traveller.minLon);
			traveller.timeToLatLonArray[20] = new LatLon(traveller.maxLat, traveller.maxLon);
			alert("No trk elements, displaying waypoints and dummy traveler");
			travellerArray[0] = traveller;
		}
	}
	
	Controller.update(travellerArray, error);
};
