// code for showing tracks on hiking map

function trackMapInit( dim )
{
	return createMap([ new OpenLayers.Control.Navigation(), new OpenLayers.Control.Attribution() ], 16, dim );
}

function navMapInit()
{
	return createMap([ 
		new OpenLayers.Control.Navigation(), 
		new OpenLayers.Control.Attribution(),
        new OpenLayers.Control.PanZoomBar(),
        new OpenLayers.Control.KeyboardDefaults(),
        new OpenLayers.Control.ScaleLine()
	], 16 );
}

function printMapInit()
{
	return createMap([ 
		new OpenLayers.Control.Navigation(), 
		//new OpenLayers.Control.Attribution(),
        new OpenLayers.Control.PanZoomBar(),
        new OpenLayers.Control.KeyboardDefaults(),
        new OpenLayers.Control.ScaleLine( {geodesic: true} )
	], 16 );
}

function largeMapInit()
{
	return createMap([ 
        new OpenLayers.Control.PanZoomBar(),
		new OpenLayers.Control.Navigation()
	], 19 );
}


function createMap( ctrl, levels, dim )
{
	if( dim == null )
		dim = 1.0;

	map = new OpenLayers.Map ("map", {
		controls: ctrl,
		maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
		maxResolution: 156543.0399,
		units: 'm',
		projection: new OpenLayers.Projection("EPSG:900913"),
		displayProjection: new OpenLayers.Projection("EPSG:4326")
	} );

	var base = new OpenLayers.Layer.OSM('base', 'http://wanderreitkarte.de/base/${z}/${x}/${y}.png', 
		{isBaseLayer:true, attribution: "<a href='http://wanderreitkarte.de'><b>Nop's Reit-&Wanderkarte</b></a>", numZoomLevels: levels, opacity: dim } );
	map.addLayer(base);

	var hills = new OpenLayers.Layer.OSM("shade", "http://wanderreitkarte.de/hills/${z}/${x}/${y}.png",
		{isBaseLayer:false, attribution: "DEM by <a href='http://srtm.csi.cgiar.org'>CIAT</a>" });
	map.addLayer(hills); 
	
	var trails = new OpenLayers.Layer.OSM('topo', 'http://wanderreitkarte.de/topo/${z}/${x}/${y}.png', 
	{isBaseLayer:false, attribution: "Data by <a href='http://openstreetmap.org/'>OSM</a>", opacity: dim });
	map.addLayer(trails); 

	return map;
}

function addTrack( name, file, color )
{
        var track = new OpenLayers.Layer.GPX( name, file, color);
        map.addLayer(track);
}

function trackMapShow( map, lat, lon, zoom )
{
	attr = document.getElementById( "OpenLayers.Control.Attribution_3" );
	if( attr )
	{
		attr.style.bottom = "2%";
		attr.style.right = "1%";
		attr.style.fontFamily = "Verdana";
		attr.style.color = "#333355";
		attr.children[0].style.color = "#0000FF";
		attr.children[1].style.color = "#0000AA";
		attr.children[2].style.color = "#0000AA";
	}

    var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
    if (!map.getCenter())
      map.setCenter (lonLat, zoom);
}

/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
 * See http://svn.openlayers.org/trunk/openlayers/release-license.txt 
 * for the full text of the license. */


/**
 * @class
 * 
 * @requires OpenLayers/Layer/Markers.js
 * @requires OpenLayers/Ajax.js
 */
OpenLayers.Layer.GPX = OpenLayers.Class.create();
OpenLayers.Layer.GPX.prototype = 
  OpenLayers.Class.inherit( OpenLayers.Layer.Markers, OpenLayers.Layer.Vector, {
 
    /** store url of text file
    * @type str */
    url:null,
    icolor:null,
    /** @type Array(OpenLayers.Feature) */
    features: null,
 
    /** @type OpenLayers.Feature */
    selectedFeature: null,
 
    /**
    * @constructor
    *
    * @param {String} name
    * @param {String} location
    */
    initialize: function(name, url, icolor, options) {
	var newArguments = new Array()
	newArguments.push(name, options);
	OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);
        OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name]);
        this.url = url;
        this.icolor = icolor;
        this.features = new Array();
	var results = OpenLayers.loadURL(this.url, null, this, this.requestSuccess, this.requestFailure);
    },
 
    /**
     * 
     */
 
    destroy: function() {
        this.clearFeatures();
        this.features = null;
        OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
    },
 
    /**
     * @param {XMLHttpRequest} ajaxRequest
     */
    requestSuccess:function(request) {
	var gpxns = "http://www.topografix.com/GPX/1/0";
        var doc = request.responseXML;
        if (!doc || request.fileType!="XML") {
            doc = OpenLayers.parseXMLString(request.responseText);
        }
        if (typeof doc == "string") {
            doc = OpenLayers.parseXMLString(doc);
        }
 
	/* search and display track */
//	var trk = OpenLayers.Ajax.getElementsByTagNameNS(doc, gpxns, "", "trk");
  var trk = doc.getElementsByTagName("trk");	
	var featureTRK = [];
	for (var i = 0; i< trk.length; i++) {
//    var color = '#00FF00';         // Fix Color
      var color=this.icolor;  // Random Color
		for (var j = 0; j < trk[i].childNodes.length; j++) {
                        switch (trk[i].childNodes[j].nodeName)
                        {
                                case 'topografix:color':
                                        color = '#' + OpenLayers.Util.getXmlNodeValue(trk[i].childNodes[j]);
                                        break;
                                case 'trkseg':
					if (color == '')
						color='#FF00FF';
                                        featureTRK.push(this.addLineGPX(trk[i].childNodes[j], color));
                                        break;
                                case '#text':
                                        break;
                                case 'name':
//FIXME: label the way
                                        break;
                                default:
//                                      alert('unknown ' + trk[i].childNodes[j].nodeName);
                                        break;
                        }
                }
        }
	this.addFeatures(featureTRK);
	/* search and display route */
//	var rte = OpenLayers.Ajax.getElementsByTagNameNS(doc, gpxns, "", "rte");
  var rte = doc.getElementsByTagName("rte");		
	var featureRTE = [];
	for (var i = 0; i< rte.length; i++) {
		var color = this.icolor;
		var style_green = {
			strokeColor: color,
			strokeOpacity: 1,
			strokeWidth: 4,
			pointRadius: 6,
			pointerEvents: "visiblePainted"
		};
		var pointList = [];
		for (var j = 0; j < rte[i].childNodes.length; j++) {
			switch (rte[i].childNodes[j].nodeName)
			{
				case 'rtept':
					var feature = this.parseFeature(rte[i].childNodes[j]);
					if (feature) {
						pointList.push(feature);
					}
					break;
				default:
					break;
			}
                }
		featureRTE.push(new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(pointList),null,style_green));
        };
	this.addFeatures(featureRTE);
 
	/* search and display waypoint */
//	var wpt = OpenLayers.Ajax.getElementsByTagNameNS(doc, gpxns, "", "wpt");
  var wpt = doc.getElementsByTagName("wpt");		
        var featuresWPT = [];
        for (var i = 0; i< wpt.length; i++) {
		var data = {}; 
		var point = this.setToMercator(wpt[i].getAttribute('lon'),wpt[i].getAttribute('lat'));
		var location =  new OpenLayers.LonLat(point[0], point[1]);
		/* Provide defaults for title and description */
		var title = "Untitled";
		try {
			title = OpenLayers.Util.getNodes(wpt[i], 
				'name')[0].firstChild.nodeValue;
		}
		catch (e) { title="Untitled"; }
 
		/* GPX descriptions */
		var description = "No description.";
		try {
			description = OpenLayers.Util.getNodes(wpt[i],
				'desc')[0].firstChild.nodeValue;
		}catch (e) {
			var description = "No description.";
		}
		data.icon = OpenLayers.Marker.defaultIcon();
//		data.popupSize = new OpenLayers.Size(250, 120);
		if ((title != null) && (description != null)) {
//                if (link) contentHTML += '<a class="link" href="'+link+'" target="_blank">';
//			contentHTML += '<p>' + title + '</p>';
//                if (link) contentHTML += '</a>';
			contentHTML = '<p><strong>' + title + '</strong><br />' + description + '</p>';
			data['popupContentHTML'] = contentHTML;
		}
		var featureWPT = new OpenLayers.Feature(this, location, data);
            featuresWPT.push(featureWPT);
              var marker = featureWPT.createMarker();
   	     marker.events.register('click', featureWPT, this.markerClick);
              this.addMarker(marker);
        }
 
//        for (var i = 0; i < itemlist.length; i++) {
//---
//
//            /* If no link URL is found in the first child node, try the
//               href attribute */
//            try {
//              var link = OpenLayers.Util.getNodes(itemlist[i], "link")[0].firstChild.nodeValue;
//            } 
//            catch (e) {
//              try {
//                var link = OpenLayers.Util.getNodes(itemlist[i], "link")[0].getAttribute("href");
//              }
//              catch (e) {}
//            }
//        }
    },
    markerClick: function(evt) {
        sameMarkerClicked = (this == this.layer.selectedFeature);
        this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;
        for(var i=0; i < this.layer.map.popups.length; i++) {
            this.layer.map.removePopup(this.layer.map.popups[i]);
        }
        if (!sameMarkerClicked) {
            var popup = this.createPopup(true);
            OpenLayers.Event.observe(popup.div, "click",
            function() { 
              for(var i=0; i < this.layer.map.popups.length; i++) { 
                this.layer.map.removePopup(this.layer.map.popups[i]); 
              } 
            }.bindAsEventListener(this));
            this.layer.map.addPopup(popup); 
        }
        OpenLayers.Event.stop(evt);
    },
    addLineGPX: function(xmlNode, color) {
        var style_green = {
                strokeColor: color,
                strokeOpacity: 0.6,
                strokeWidth: 5,
                pointRadius: 6,
                pointerEvents: "visiblePainted"
        };
        var pointList = [];
        for (var i = 0; i < xmlNode.childNodes.length; i++) {
//	for (var i = 0; i < 4; i++) {
                if (xmlNode.childNodes[i].nodeName == "trkpt")
                {
                        var feature = this.parseFeature(xmlNode.childNodes[i]);
                        if (feature) {
                                pointList.push(feature);
                        }
                }
        };
        return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(pointList),null,style_green);
    },
 
     /**
      * This function is the core of the GPX parsing code in OpenLayers.
      * It creates the geometries that are then attached to the returned
      * feature, and calls parseAttributes() to get attribute data out.
      * @param DOMElement xmlNode
      */
     parseFeature: function(xmlNode) {
        if (xmlNode.getAttribute('lat') && xmlNode.getAttribute('lon')) {
		var point = this.setToMercator(xmlNode.getAttribute('lon'),xmlNode.getAttribute('lat'));
		return new OpenLayers.Geometry.Point(point[0], point[1]);
        }
        return false;
    },
    setToMercator: function(lon, lat) {
    	x = parseFloat(lon);
	y = parseFloat(lat);
	var PI = 3.14159265358979323846;
	x = x * 20037508.34 / 180;
	y = Math.log (Math.tan ((90 + y) * PI / 360)) / (PI / 180);
	y = y * 20037508.34 / 180;
	return new Array(x,y);
    },
    /**
     * 
     */
    clearFeatures: function() {
        if (this.features != null) {
            while(this.features.length > 0) {
                var feature = this.features[0];
                OpenLayers.Util.removeItem(this.features, feature);
                feature.destroy();
            }
        }        
    },
    requestFailure: function(request) {
    },
    moveTo:function(bounds, zoomChanged, dragging) { 
	OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
//	OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
        if (!dragging) {
            this.div.style.left = - parseInt(this.map.layerContainerDiv.style.left) + "px";
            this.div.style.top = - parseInt(this.map.layerContainerDiv.style.top) + "px";
            var extent = this.map.getExtent();
            this.renderer.setExtent(extent);
	    for(i=0; i < this.markers.length; i++) {
		marker = this.markers[i];
		lonlat = this.map.getLayerPxFromLonLat(marker.lonlat);
                if (marker.icon.calculateOffset) {
                    marker.icon.offset = marker.icon.calculateOffset(marker.icon.size);
                }
                var offsetPx = lonlat.offset(marker.icon.offset);
		marker.icon.imageDiv.style.left = offsetPx.x+parseInt(this.map.layerContainerDiv.style.left) + "px";
		marker.icon.imageDiv.style.top = offsetPx.y+parseInt(this.map.layerContainerDiv.style.top) + "px";
	    }
 
        }
        if (!this.drawn || zoomChanged) {
            this.drawn = true;
            for(var i = 0; i < this.features.length; i++) {
                var feature = this.features[i];
                this.drawFeature(feature);
            }
        }
 
    },
    setMap: function(map) {
//		OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);
        OpenLayers.Layer.prototype.setMap.apply(this, arguments);
 
        if (!this.renderer) {
            this.map.removeLayer(this);
        } else {
            this.renderer.map = this.map;
            this.renderer.setSize(this.map.getSize());
        }
 
    },
    /** @final @type String */
    CLASS_NAME: "OpenLayers.Layer.GPX"
});

