
var data;
var osMap;
var tracks = [];
var waypoints = [];			
var errmsg = '';

var mineasting = 9999999;
var maxeasting = -1;
var minnorthing = 9999999;
var maxnorthing = -1;


// Gets filename from the parameter string (?f=filename)
// and passes it to the parser to extract the data.
//
function init() 
{  	
	var queryString = window.location.search.substring(1);

	var fileName;
	
	if  (queryString.length > 0)
	{
		if (queryString.indexOf("f=") > -1)
		{
			fileName = queryString.substring(queryString.indexOf("f=") + 2);
		}
	}
	
	if	(fileName && fileName.length > 4)
	{ 	
		var xotree = new XML.ObjTree();
		data = xotree.parseHTTP("gpx/"+fileName,{});
	}
	else
	{
		displayMap();
		displayParishBounds();
		// error('No map data file name supplied.');	
		// return;	
	}
	
	// This commented-out code uses the filename  
	// (minus the ".gpx") as the title of the page ...   
	// 
	// var heading = document.getElementById("pageheading");
	// heading.innerHTML = fileName.substring(0, fileName.length - 4); 
	
	// This code uses the filename (minus .gpx) as the page title ...
	// document.title = fileName.substring(0, fileName.length - 4); 
	 
	
	// Workaround so that script works with Firefox 3.0 
	//  and Safari 3.1. Can be removed once OpenSpace
	//  is based on v2.6 (or later) of OPenLayers.
	 
	OpenLayers.Renderer.SVG.prototype.supported = function() {
        var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
        return (document.implementation &&
           (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
            document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
            document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
	};
	
	if  (data)
	{
		doGPXOverlay(data);
		
		if	(tracks.length == 0 && waypoints.length == 0)
		{
			error('No data found - may not be a valid GPX file');
			return;
		}
		
		displayMap();
		// displayParishBounds();
		displayData();
	}
	else
	{
		// error('Data parse problem. Cannot load map data file.')
	}
}  


//  Runs through all the data (tracks, routes and waypoints) extracted from the
//  GPX file and converts each point into a form suitable for use by OpenSpace.
//
function doGPXOverlay(data)
{
	var t = data.gpx.trk;
	var r = data.gpx.rte
	var wp = data.gpx.wpt;

	if  (typeOf(t) == 'array')
	{
		for (var i = 0; i < t.length; i++) 
		{
			var track = new Object();
			track.name = t[i].name;
			track.points = [];

			var seg = t[i].trkseg;

			if (typeOf(seg) == 'array') 
			{
				for (var j = 0; j < seg.length; j++) 
				{
					for (var k = 0; k < seg[j].trkpt.length; k++)
					{
						track.points.push(makeTrackPoint(seg[j].trkpt[k]));
						
					}
				}
			}

			if (typeOf(seg) == 'object') 
			{
				for (var j = 0; j < seg.trkpt.length; j++) 
				{
					track.points.push(makeTrackPoint(seg.trkpt[j]));
				}
			}
			
			tracks.push(track);
		}
	}

	if  (typeOf(t) == 'object')
	{
		var track = new Object();
		track.name = t.name;
		track.points = [];

		var seg = t.trkseg;

		if (typeOf(seg) == 'array') 
		{
			for (var i = 0; i < seg.length; i++) 
			{
				for (var j = 0; j < seg[i].trkpt.length; j++)
				{
					track.points.push(makeTrackPoint(seg[i].trkpt[j]));
				}
			}
		}

		if (typeOf(seg) == 'object') 
		{
			for (var i = 0; i < seg.trkpt.length; i++) 
			{
				track.points.push(makeTrackPoint(seg.trkpt[i]));
			}
		}
		
		tracks.push(track);
	}


	if  (typeOf(r) == 'object')
	{
		var route = new Object();
		route.name = r.name;
		route.points = [];
	
		var seg = r.rtept;
		
		if (typeOf(seg) == 'array') 
		{
			for (var i = 0; i < seg.length; i++) 
			{
				route.points.push(makeTrackPoint(seg[i]));
			}
		}
		else
		{
			route.points.push(makeTrackPoint(seg));
		}
		
		tracks.push(route);
	}


	if  (typeOf(r) == 'array')
	{
		for (var i = 0; i < r.length; i++) 
		{
			var route = new Object();
			route.name = r[i].name;
			route.points = [];
			
			var seg = r[i].rtept;
	
			if (typeOf(seg) == 'array') 
			{
				for (var j = 0; j < seg.length; j++) 
				{
					route.points.push(makeTrackPoint(seg[j]));
				}
			}
			else
			{
				route.points.push(makeTrackPoint(seg));
			}

			tracks.push(route);
		}
	}

	if  (typeOf(wp) == 'array')
	{
		for (var i = 0; i < wp.length; i++) 
		{
			storeWaypoint(wp[i]);
		}
	}

	if  (typeOf(wp) == 'object')
	{
		storeWaypoint(wp);
	}
}


// Stores a waypoint for subsequent display 
//
function storeWaypoint(lonlat)
{
	if (!lonlat) 
	{
		return;
	}

	var wp = makeWaypoint(lonlat);
	
	if (wp) 
	{
		var waypoint = new Object();
		
		waypoint.mappoint = wp;
		waypoint.name = lonlat['name'];
		waypoint.cmt = lonlat['cmt'];
		waypoint.desc = lonlat['desc'];
		
		waypoints.push(waypoint);
	}
}


// Converts a track or route point from Lon/Lat to OpenSpace format
//
function makeTrackPoint(lonlat)
{
	var pos = new OpenLayers.LonLat(lonlat['-lon'], lonlat['-lat']);
	var gridProjection = new OpenSpace.GridProjection();
	var mp = gridProjection.getMapPointFromLonLat(pos);
	checkBounds(mp);
	return new OpenLayers.Geometry.Point(mp.getEasting(), mp.getNorthing());
}


// Converts a waypoint from Lon/Lat to OpenSpace format
//
function makeWaypoint(lonlat)
{
	var pos = new OpenLayers.LonLat(lonlat['-lon'], lonlat['-lat']);
	var gridProjection = new OpenSpace.GridProjection();
	var mp = gridProjection.getMapPointFromLonLat(pos);
	checkBounds(mp);
	return new OpenSpace.MapPoint(mp.getEasting(), mp.getNorthing());
}


// Determines if a point lies outside the existing known bounds
// of the map, and if so extends those bounds to accommodate it. 
//
function checkBounds(mp)
{
	if	(mp.getEasting() < mineasting) 
	{
		mineasting = mp.getEasting();
	}

	if	(mp.getEasting() > maxeasting) 
	{
		maxeasting = mp.getEasting();
	}

	if	(mp.getNorthing() < minnorthing) 
	{
		minnorthing = mp.getNorthing();
	}

	if	(mp.getNorthing() > maxnorthing) 
	{
		maxnorthing = mp.getNorthing();
	}
}


// Initialises the map at the highest zoom level that will allow  
// all of the tracks, routes and waypoints to be visible. 
//
function displayMap() 
{
	osMap = new OpenSpace.Map('map');  
	// var zoomLevel = osMap.getZoomForExtent(new OpenSpace.MapBounds(mineasting, minnorthing, maxeasting, maxnorthing));
	// osMap.setCenter(new OpenSpace.MapPoint((mineasting + maxeasting) / 2 , (minnorthing + maxnorthing) / 2), zoomLevel);
	osMap.setCenter(new OpenSpace.MapPoint(174500, 40670), 7);
}

// dsiplays parish boundaries
function displayParishBounds()
{
	var vectorLayer = new OpenLayers.Layer.Vector("Vector Layer"); 
	    osMap.addLayer(vectorLayer); 
	  
	    /* 
	    * Define polygon style 
	    */ 
	    var style_green = 
	    { 
	        strokeColor: "#000000", 
	        strokeOpacity: 1, 
	        strokeWidth: 1.5, 
	        fillColor: "#00ff00", 
	        fillOpacity: 0.1 
	    }; 
	  
	    // Define polygon area 
	    var p1 = new OpenLayers.Geometry.Point(173055, 43640); 
	    var p2 = new OpenLayers.Geometry.Point(173205, 43525); 
	    var p3 = new OpenLayers.Geometry.Point(173590, 43435); 
	    var p4 = new OpenLayers.Geometry.Point(173850, 43310); 
	    var p5 = new OpenLayers.Geometry.Point(174040, 43155); 
	    var p6 = new OpenLayers.Geometry.Point(174160, 43025); 
	    var p7 = new OpenLayers.Geometry.Point(174655, 42945); 
	    var p8 = new OpenLayers.Geometry.Point(174900, 42900); 
	    var p9 = new OpenLayers.Geometry.Point(175290, 42435); 
	    var p10 = new OpenLayers.Geometry.Point(175555, 42305); 
	    var p11 = new OpenLayers.Geometry.Point(175815, 42295); 
	    var p12 = new OpenLayers.Geometry.Point(176145, 42040); 
	    var p13 = new OpenLayers.Geometry.Point(177385, 41280); 
	    var p14 = new OpenLayers.Geometry.Point(177360, 40990); 
	    var p15 = new OpenLayers.Geometry.Point(177390, 40965); 
	    var p16 = new OpenLayers.Geometry.Point(177180, 40660); 
	    var p17 = new OpenLayers.Geometry.Point(177165, 40595); 
	    var p18 = new OpenLayers.Geometry.Point(176725, 40275); 
	    var p19 = new OpenLayers.Geometry.Point(176475, 40040); 
	    var p20 = new OpenLayers.Geometry.Point(176475, 39955); 
	    var p21 = new OpenLayers.Geometry.Point(176395, 39720); 
	    var p22 = new OpenLayers.Geometry.Point(176465, 39545); 
	    var p23 = new OpenLayers.Geometry.Point(175930, 39430); 
	    var p24 = new OpenLayers.Geometry.Point(175520, 39080); 
	    var p25 = new OpenLayers.Geometry.Point(175275, 38975); 
	    var p26 = new OpenLayers.Geometry.Point(175235, 38845); 
	    var p27 = new OpenLayers.Geometry.Point(174860, 38665); 
	    var p28 = new OpenLayers.Geometry.Point(174460, 38560); 
	    var p29 = new OpenLayers.Geometry.Point(174380, 38340); 
	    var p30 = new OpenLayers.Geometry.Point(174295, 38430); 
	    var p31 = new OpenLayers.Geometry.Point(174050, 38260); 
	    var p32 = new OpenLayers.Geometry.Point(174090, 38205); 
	    var p33 = new OpenLayers.Geometry.Point(173520, 38175); 
	    var p34 = new OpenLayers.Geometry.Point(173325, 38255); 
	    var p35 = new OpenLayers.Geometry.Point(173335, 38360); 
	    var p36 = new OpenLayers.Geometry.Point(172825, 38275); 
	    var p37 = new OpenLayers.Geometry.Point(172600, 37875); 
	    var p38 = new OpenLayers.Geometry.Point(172460, 37985); 
	    var p39 = new OpenLayers.Geometry.Point(172185, 38205); 
	    var p40 = new OpenLayers.Geometry.Point(171755, 38455); 
	    var p41 = new OpenLayers.Geometry.Point(172435, 38830); 
	    var p42 = new OpenLayers.Geometry.Point(172480, 39040); 
	    var p43 = new OpenLayers.Geometry.Point(172670, 39100); 
	    var p44 = new OpenLayers.Geometry.Point(172675, 39165); 
	    var p45 = new OpenLayers.Geometry.Point(172830, 39305); 
	    var p46 = new OpenLayers.Geometry.Point(172905, 39280); 
	    var p47 = new OpenLayers.Geometry.Point(173035, 39525); 
	    var p48 = new OpenLayers.Geometry.Point(173045, 39595); 
	    var p49 = new OpenLayers.Geometry.Point(172940, 39585); 
	    var p50 = new OpenLayers.Geometry.Point(172910, 39845); 
	    var p51 = new OpenLayers.Geometry.Point(173100, 39855); 
	    var p52 = new OpenLayers.Geometry.Point(172975, 40220); 
	    var p53 = new OpenLayers.Geometry.Point(173005, 40315); 
	    var p54 = new OpenLayers.Geometry.Point(172920, 40310); 
	    var p55 = new OpenLayers.Geometry.Point(172880, 40585); 
	    var p56 = new OpenLayers.Geometry.Point(172900, 40705); 
	    var p57 = new OpenLayers.Geometry.Point(172975, 40720); 
	    var p58 = new OpenLayers.Geometry.Point(172985, 40905); 
	    var p59 = new OpenLayers.Geometry.Point(173305, 40990); 
	    var p60 = new OpenLayers.Geometry.Point(173295, 41070); 
	    var p61 = new OpenLayers.Geometry.Point(173745, 41120); 
	    var p62 = new OpenLayers.Geometry.Point(173745, 41295); 
	    var p63 = new OpenLayers.Geometry.Point(173670, 41450); 
	    var p64 = new OpenLayers.Geometry.Point(173795, 41550); 
	    var p65 = new OpenLayers.Geometry.Point(173865, 41530); 
	    var p66 = new OpenLayers.Geometry.Point(173695, 41795); 
	    var p67 = new OpenLayers.Geometry.Point(173550, 41740); 
	    var p68 = new OpenLayers.Geometry.Point(173465, 41830); 
	    var p69 = new OpenLayers.Geometry.Point(173380, 41825); 
	    var p70 = new OpenLayers.Geometry.Point(173550, 42640); 
	    var p71 = new OpenLayers.Geometry.Point(172965, 43155); 
	    var p72 = new OpenLayers.Geometry.Point(172995, 43350); 
	    var p73 = new OpenLayers.Geometry.Point(173095, 43485); 
	  
	    var points = []; 
	    points.push(p1); points.push(p2); points.push(p3); points.push(p4); points.push(p5); 
	    points.push(p6); points.push(p7); points.push(p8); points.push(p9); points.push(p10); 
	    points.push(p11); points.push(p12); points.push(p13); points.push(p14); points.push(p15); 
	    points.push(p16); points.push(p17); points.push(p18); points.push(p19); points.push(p20); 
	    points.push(p21); points.push(p22); points.push(p23); points.push(p24); points.push(p25); 
	    points.push(p26); points.push(p27); points.push(p28); points.push(p29); points.push(p30); 
	    points.push(p31); points.push(p32); points.push(p33); points.push(p34); points.push(p35); 
	    points.push(p36); points.push(p37); points.push(p38); points.push(p39); points.push(p40); 
	    points.push(p41); points.push(p42); points.push(p43); points.push(p44); points.push(p45); 
	    points.push(p46); points.push(p47); points.push(p48); points.push(p49); points.push(p50); 
	    points.push(p51); points.push(p52); points.push(p53); points.push(p54); points.push(p55); 
	    points.push(p56); points.push(p57); points.push(p58); points.push(p59); points.push(p60); 
	    points.push(p61); points.push(p62); points.push(p63); points.push(p64); points.push(p65); 
	    points.push(p66); points.push(p67); points.push(p68); points.push(p69); points.push(p70); 
	    points.push(p71); points.push(p72); points.push(p73); 
	  
	    // create a polygon feature from a list of points 
	    var linearRing = new OpenLayers.Geometry.LinearRing(points); 
	    var polygonFeature = new OpenLayers.Feature.Vector(linearRing, null, style_green); 
	  
	    vectorLayer.addFeatures([polygonFeature]); 
}

// Displays a single line for each of the included tracks and/or routes,
// plus a single marker (with default or custom icon) for each waypoint.
//
function displayData() 
{
	if	(tracks.length > 0)
	{
 		vectorLayer = osMap.getVectorLayer();
		osMap.addLayer(vectorLayer); 
	}
	
	for (var i = 0; i < tracks.length; i++)
	{
		var lineString = new OpenLayers.Geometry.LineString(tracks[i].points); 
	
		var style_red = 
		{ 
			strokeColor: "#FF0000", 
			strokeOpacity: 0.7, 
			strokeWidth: 4 
		};
		 
		var lineFeature = new OpenLayers.Feature.Vector(lineString, null, style_red); 
		vectorLayer.addFeatures([lineFeature]); 
	}
	
	for (var i = 0; i < waypoints.length; i++) 
	{
		var html;
		
		if  (waypoints[i].desc && waypoints[i].desc.length > 0)
		{
			html = waypoints[i].desc;
		}
		else if (waypoints[i].cmt && waypoints[i].cmt.length > 0)
		{
			html = waypoints[i].cmt;
		}	
		
		if  (waypoints[i].name.length > 4)
		{
			if (waypoints[i].name.search(/.png$/i) > -1)
			{
				var icon = new OpenSpace.Icon(waypoints[i].name, new OpenLayers.Size(34, 45), new OpenLayers.Pixel(-17, -45));
				osMap.createMarker(waypoints[i].mappoint, icon, html);			
			}
			else
			{
				osMap.createMarker(waypoints[i].mappoint, null, html); 
			}		
		}
		
	}
}


function error(msg)
{
	errmsg += '<li>' + msg + '</li>\n';
	var errDiv = document.getElementById('error');
	errDiv.innerHTML = '<h4>Error!</h4><ul>' + errmsg + '</ul>' ;
	errDiv.style.display = 'block';
}


function typeOf(value) 
{    
	var s = typeof value;    
	
	if (s === 'object') 
	{        
		if (value) 
		{            
			if (value instanceof Array) 
			{                
				s = 'array';            
			}        
		} 
		else 
		{            
			s = 'null';        
		}    
	}    
	return s;
}


