var XMLdoc = null;
var XMLdoc1 = null;
var layerLoipen = null;
var layerWays = null;
var xapi = "XC-Map";

function mapEvent(event)
{
	var b=map.getExtent();
	if(b.getWidth()<200000 && b.getHeight()<200000)
	{
		b=b.transform(GooglePrj,WGS84);

		var bw=Math.pow(4,Math.floor(Math.log(b.getWidth())/Math.log(4)));
		var bh=Math.pow(4,Math.floor(Math.log(b.getHeight())/Math.log(4)));

		b.left=Math.floor(b.left/bw)*bw;
		b.bottom=Math.floor(b.bottom/bh)*bh;
		b.right=Math.ceil(b.right/bw)*bw;
		b.top=Math.ceil(b.top/bh)*bh;


		if(!bounds.containsBounds(b) || !event)
		{
			$("status").innerHTML = "Loading ...";
			$("status").style.backgroundColor="yellow";
			importXML("loipen.php?bbox="+b.toBBOX()+"&xapi="+xapi);
			bounds=b;
		}
		else if($("status").innerHTML == "Zoom in, to load data!")
		{ 
			$("status").innerHTML = "Ready";
			$("status").style.backgroundColor="green";
			$("status").title="You can click the Relations to get more information.";
		}
	}
	else if($("status").innerHTML != "Loading ..")
	{
		$("status").innerHTML = "Zoom in, to load data!";
		$("status").style.backgroundColor="orange";
		$("status").title="Zoom in to 200 x 200 km oder nearer. Be patient - the data download may need some time.";
	}
}

function loadError()
{
	$("status").innerHTML = "Error loading!";
	$("status").style.backgroundColor="red";
	$("status").title="The data download failed, wait some seconds and try again using the reload buttom of your browser.";
	delete bounds;
	bounds = new OpenLayers.Bounds();
}

var selectControl; 
var selectedFeature=null;

function onPopupClose(evt) 
{
	selectControl.unselect(selectedFeature);
}

function onFeatureSelect(feature) 
{
    selectedFeature = feature;
    var bound=feature.geometry.getBounds();
    layerLoipen.drawFeature(feature,{ strokeColor: feature.style.strokeColor, strokeWidth: 5 });
    popup = new OpenLayers.Popup("Loipe", new OpenLayers.LonLat(bound.left,bound.bottom), null, feature.text, true, onPopupClose);
    popup.autoSize=true;
    feature.popup = popup;
    map.addPopup(popup);
}

function onFeatureUnselect(feature) 
{
    map.removePopup(feature.popup);
    layerLoipen.drawFeature(feature);
    feature.popup.destroy();
    feature.popup = null;
    selectedFeature=null;
}    

function showLoipen()
{
	if (!XMLdoc.documentElement) {loadError(); return;}
	if (XMLdoc.documentElement.tagName == 'error') {loadError(); return;}

	var nodes=getNodes(XMLdoc);
	var ways=getWays(XMLdoc);

	layerWays.destroyFeatures();
	for (var i in ways)
	{
		if(ways[i].type!="nordic") continue;

		var color = getColor(ways[i].difficulty)
		var style = getStyle(ways[i].grooming)

		var linestyle = { strokeColor: color, strokeWidth: 1, strokeDashstyle: style };
		var pts= new Array(ways[i].pt.length);

		for (var k = 0; k < ways[i].pt.length; k++)
		{
			node = nodes[ways[i].pt[k]];
			var pt = new OpenLayers.Geometry.Point(node.lon,node.lat);
			pts.push(pt.transform(WGS84, GooglePrj));
		}

		var lineFeature =  new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(pts),null,linestyle);
		layerWays.addFeatures([lineFeature]);
		delete pts;
	}

	if(selectedFeature) 
	{
		map.removePopup(selectedFeature.popup);
		selectedFeature=null;
	}
	layerLoipen.destroyFeatures();

	var relations=XMLdoc.getElementsByTagName("relation");

	for (var i = 0; i < relations.length; i++)
	{
		var name="";
		var ref="";
		var difficulty="";
		var color="";
		var website="";
		var lit="";
		var grooming="";
		var operator="";
		var lanes="";
		var symbol="";
		var network="";
		var distance="";
		var description="";
		var type="";
		var fee="";
		
		var id=relations[i].getAttribute("id");
		var user=relations[i].getAttribute("user");

		var tags=relations[i].getElementsByTagName("tag");
		for (var j = 0; j < tags.length; j++)
		{
			switch(tags[j].getAttribute("k"))
			{
			case "piste:type":
				type = tags[j].getAttribute("v");break;
			case "name":
			case "piste:name":
				name = tags[j].getAttribute("v"); break;
			case "ref":
				ref= tags[j].getAttribute("v"); break;
			case "difficulty":
			case "piste:difficulty":
				difficulty = tags[j].getAttribute("v"); break;
			case "lit":
			case "piste:lit":
				lit=tags[j].getAttribute("v"); break;
			case "grooming":
			case "piste:grooming":
				grooming= tags[j].getAttribute("v"); break;
			case "operator":
				operator= tags[j].getAttribute("v"); break;
			case "network":
				network= tags[j].getAttribute("v"); break;
			case "color":
			case "colour":
				color= tags[j].getAttribute("v"); break;
			case "website":
				website= tags[j].getAttribute("v"); break;
			case "description":
				description= tags[j].getAttribute("v"); break;
			case "symbol":
				symbol= tags[j].getAttribute("v"); break;
			case "lanes":
				lanes= tags[j].getAttribute("v"); break;
			case "length":
			case "piste:length":
			case "distance":
				distance= tags[j].getAttribute("v"); break;
			case "fee":
			case "piste:fee":
				fee= tags[j].getAttribute("v"); break;
			}
		}
		delete tags;
		if(type!="nordic") continue;
		if(!color) color = getColor(difficulty);
		//var style = getStyle(grooming);
		var members=relations[i].getElementsByTagName("member");

		var linestyle = { strokeColor: color, strokeWidth: 3, strokeOpacity:0.5, strokeDashstyle: "solid" };
		
		var lines=new Array();
		var bbox=new OpenLayers.Bounds();
		var len=0;

		for (j = 0; j < members.length; j++)
		{

			if(members[j].getAttribute("type")=="way")
			{
				var way = ways[members[j].getAttribute("ref")];
				if(!way) continue;
				var pts= new Array(way.pt.length);
				
				for (var k = 0; k < way.pt.length; k++)
				{
					node = nodes[way.pt[k]];
					var pt = new OpenLayers.Geometry.Point(node.lon,node.lat);
					bbox.extend(pt);
					pts.push(pt);
				}

				linestring=new OpenLayers.Geometry.LineString(pts);
				len+=linestring.getGeodesicLength();
				lines.push(linestring.transform(WGS84, GooglePrj));
				delete pts;
			}
		}


		var multiLineFeature =  new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiLineString(lines),null,linestyle);

		multiLineFeature.text ="<span style='background-color:"+color+"; color:#FFFFFF; font-weight: bold; '>&nbsp;" +ref+ "&nbsp;" +name+ "&nbsp;</span>";
		multiLineFeature.text += "<br />Length (L&auml;nge): "+ Math.round(len/100)/10 + " km"; 
		if(distance)multiLineFeature.text += " (" + distance + ")";
		if(grooming) multiLineFeature.text += "<br />Grooming (Technik): " + grooming;
		if(difficulty) multiLineFeature.text += "<br />Difficulty (Schwierigkeit): "+difficulty;
		if(lanes) multiLineFeature.text += "<br />Lanes (Spuren): "+lanes;
		if(fee) multiLineFeature.text += "<br />Fee (Gebühr): "+fee;
		if(symbol) multiLineFeature.text += "<br />Symbol (Markierung):" + symbol;
		if(lit) multiLineFeature.text += "<br />Lit (Beleuchtung): "+ lit;
		if(network) multiLineFeature.text += "<br />Network (Netz): "+ network;
		if(operator) multiLineFeature.text += "<br />Operator (Betreiber): "+ operator;
		if(website) multiLineFeature.text += "<br />Website: <a target='browse' href='"+website+"'>"+website+"</a>";
		if(description) multiLineFeature.text += "<br />Description (Beschreibung):" +description;
		multiLineFeature.text += " <hr> [<a href='http://www.openstreetmap.org/browse/relation/"+id+"' target='browse' title='OSM Browse'>B</a>]";
		multiLineFeature.text += " [<a href='http://betaplace.emaitie.de/webapps.relation-analyzer/analyze.jsp?relationId="+id+"' target='browse' title='Relation Analyzer'>A</a>]";
		multiLineFeature.text += " [<a href='http://osm.cdauth.de/route-manager/relation.php?id="+id+"' target='browse' title='Routen Manager'>R</a>]";
		multiLineFeature.text += " [<a href='../history/?type=relation&ref="+id+"' target='browse' title='History Browser'>H</a>]";
		multiLineFeature.text += " [<a href='http://localhost:8111/load_and_zoom?left="+bbox.left+"&right="+bbox.right+"&top="+bbox.top+"&bottom="+bbox.bottom+"&select=relation"+id+"' target='browse' title='edit with JOSM'>J</a>]";
		multiLineFeature.text += "<br /><i>last edit: <a href='http://www.openstreetmap.org/user/"+user+"' target='browse'>"+user+"</a></i>";
		layerLoipen.addFeatures([multiLineFeature]);
		
		delete lines;
	}

	$("status").innerHTML = "Ready";
	$("status").style.backgroundColor="green";
	$("status").title="You can click the Relations to get more information.";
}

function importXML(name)
{
	if (document.implementation && document.implementation.createDocument)
	{
		XMLdoc = document.implementation.createDocument("", "", null);
		XMLdoc.onload = showLoipen;
	}
	else if (window.ActiveXObject)
	{
		XMLdoc = new ActiveXObject("Microsoft.XMLDOM");
		XMLdoc.onreadystatechange = function () { if (XMLdoc.readyState == 4) showLoipen(); };
 	}
	else
	{
		alert('Your browser can\'t handle this script');
		return;
	}
	XMLdoc.load(name);
}

function getNodes(doc)
{
	var array=doc.getElementsByTagName("node");
	var nodes= new Object();
	
	for (j = 0; j < array.length; j++)
	{
		var node=new Object();
		var id = array[j].getAttribute("id");
		node.lat = array[j].getAttribute("lat");
		node.lon = array[j].getAttribute("lon");
		nodes[id]=node;
	}
	delete array;
	return nodes;
}

function getWays(doc)
{
	var array=doc.getElementsByTagName("way");
	var ways= new Object();
	
	for (i = 0; i < array.length; i++)
	{
		var way=new Object();
		var id = array[i].getAttribute("id");
		
		pts=array[i].getElementsByTagName("nd");
		
		way.pt=new Array(pts.length);
		for (var j = 0; j < pts.length; j++)
		{
			way.pt[j]=pts[j].getAttribute("ref");
		}
		delete pts;

		var tags=array[i].getElementsByTagName("tag");
		for (var j = 0; j < tags.length; j++)
		{
			switch(tags[j].getAttribute("k"))
			{
			case "piste:type":
				way.type=tags[j].getAttribute("v"); break;
			case "piste:difficulty":
				way.difficulty = tags[j].getAttribute("v"); break;
			case "piste:grooming":
				way.grooming = tags[j].getAttribute("v"); break;
			}
		}
		delete tags;
		
		ways[id]=way;
	}
	delete array;
	return ways;
}

function getColor(difficulty)
{
	switch(difficulty)
	{
	case "novice":
	case "easy":
		return "#0000FF";
	case "intermediate":
		return "#FF0000";
	case "advanced":
	case "expert":
		return "#000000";
	default: 
		return "#008080";
	}
}

function getStyle(grooming)
{
	switch(grooming)
	{
	case "skating":
		return "solid";
	case "classic":
		return "longdash";
	case "classic+skating":
	case "classic;skating":
	case "skating;classic":
	case "classic; skating":
	case "skating; classic":
		return "longdashdot";
	default: 
		return "dash";
	}
}
