/**
 * FÃ¼gt einen Marker mit Popup der Markerliste und Karte hinzu.
 * ll:      Der Marker
 * markers: Die Liste der Marker
 * map:     Die Karte, auf der der Marker dargestellt werden soll
**/
function addMarker(ll, markers, map) {
    // Wenn gar kein Text angegeben wurde, zeige den Marker nicht an.
    if(ll[3] == undefined)
        return;

    var feature = new OpenLayers.Feature(markers, ll[0]);
    setMarkerImg(feature, ll[4]);
    var marker = feature.createMarker();

    // Wurde nur leerer Text angegeben, erstelle keine leere Sprechblase
    if(ll[3] != "") {
        feature.closeBox = false;
        feature.popupClass = OpenLayers.Class(
            OpenLayers.Popup.FramedCloud,
            // Gibt die GrÃ¶ÃŸe der Sprechblasen an
            {'maxSize': new OpenLayers.Size(500,300), 'minSize': new OpenLayers.Size(95,0)}
        );

        // Ggf. hier den Stil fÃ¼r den Sprechblasentext Ã¤ndern
        feature.data.popupContentHTML = ll[3];

        // Diese Funktion toggelt das Popup mit jedem Aufruf
        var markerClick = function (evt) {
            if (this.popup == null) {
                this.popup = this.createPopup(this.closeBox);
                map.addPopup(this.popup);
                this.popup.show();
            } else this.popup.toggle();
            currentPopup = this.popup;
            OpenLayers.Event.stop(evt);
        };
        marker.events.register("mouseover", feature, markerClick);
        marker.events.register("mouseout", feature, markerClick);
    }
    markers.addMarker(marker);
}

/**
 * Setzt die Farbe fÃ¼r den gegebenen Marker auf die angegebene Farbe. Da
 * jede Farbe ihre eigene Grafik ist, ist die Auswahl zur Zeit begrenzt.
 * feature: der Marker dessen Farbe geÃ¤ndert werden soll
 * color:   die zu setztende Farbe
 */
function setMarkerImg(feature, color) {
    switch(color) {
        case "green":
        case "gold":
        case "blue":
            break;
        // For default case do nothing
        case "red":
        default:
            return;
    }
    // Other icons
    var s = new OpenLayers.Size(21,25);
    var o = new OpenLayers.Pixel(-(s.w/2), -s.h);
    var icon = new OpenLayers.Icon("http://www.openlayers.org/api/img/marker-" + color + ".png", s, o);
    feature.data.icon=icon;
}

/**
 * Dies ist die Funktion, die beim Start aufgerufen wird.
 * zoomTo: der Identifier von einem Ort, siehe test.html. Dort wird
 *         standardmÃ¤ÃŸig hin gezoomt.
 * defmap: wÃ¤hlt die standardmÃ¤ÃŸig angezeigte Karte aus. Zur Zeit gibt
 *         es folgende MÃ¶glichkeiten: mapnik, osma, cycle, opnv
 *         Kann man aber auch einfach weglassen.
**/
function init(zoomTo, defmap) {
    if(defmap == null)
        defmap = "";

    var places = getPlaces();

    document.getElementById("map").innerHTML='';

    var proj4326  = new OpenLayers.Projection('EPSG:4326');
    var projmerc  = new OpenLayers.Projection('EPSG:900913');
    var resExt = new OpenLayers.Bounds(-30,30,45,75).transform(proj4326, projmerc);
    var maxExt = new OpenLayers.Bounds(-20037508,-20037508,20037508,20037508);

    var map = new OpenLayers.Map ("map", {
        controls:[
                // Entfernen, wenn kein Platz ist um die Lizenz unten
                // rechts anzuzeigen
                new OpenLayers.Control.Attribution(),
                new OpenLayers.Control.Navigation(),
                new OpenLayers.Control.ZoomPanel(),
                new OpenLayers.Control.PanPanel(),
                new OpenLayers.Control.LayerSwitcher()
        ],
        // wird von der Ã–PNV Karte benÃ¶tigt, da diese nicht welt-
        // weit verfÃ¼gbar ist
        numZoomLevels: 19,
        maxExtent: maxExt,
        maxResolution: 156543,
        restrictedExtent: resExt,
        projection: projmerc,
        displayProjection: proj4326
    });

    var defattr = 'Daten <a href="http://creativecommons.org/licenses/'
                    +' by-sa/2.0/deed.de">CC-BY-SA</a> von <a href="'
                    + 'http://www.openstreetmap.org">OpenStreetMap</a>';
    var mapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik (wenig Details)");
    mapnik.addOptions({transitionEffect: "resize", attribution: defattr});
    var osma = new OpenLayers.Layer.OSM.Osmarender("Osmarender (viel Details)");
    osma.addOptions({transitionEffect: "resize", attribution: defattr});
    var cycle = new OpenLayers.Layer.OSM.CycleMap("Fahrradkarte");
    cycle.addOptions({transitionEffect: "resize", attribution: defattr});
    var opnv = new OpenLayers.Layer.OSM("Nahverkehrskarte",
        "http://tile.xn--pnvkarte-m4a.de/tilegen/${z}/${x}/${y}.png",
        {numZoomLevels: 19, transitionEffect: "resize", attribution:
            '<a href="http://creativecommons.org/licenses/by-sa/2.0/'
            + 'deed.de">CC-BY-SA</a>; <a href="http://www.xn--pnvkarte'
            + '-m4a.de">ÖPNV-Karte von Melchior Moos</a>'}
    );
    var hill = new OpenLayers.Layer.WMS("H&ouml;henschattierung",
	"http://services.giub.uni-bonn.de/hillshade?",
	{layers: 'europe_wms:hs_srtm_europa', srs: 'EPSG:900913', 
	format: 'image/JPEG', transparent: 'true', numZoomLevels: 19,
	transitionEffect: "resize"},
	{buffer: 1});
    hill.setOpacity(0.23);
    // StandardmÃ¤ÃŸig aus, da nur fÃ¼r grÃ¶ÃŸere Zoomstufen sinnvoll
    hill.setVisibility(false);

    // Der Layer, der die ganzen Marker enthalten wird.
    var markers = new OpenLayers.Layer.Markers("Wichtige Orte");
    // Er sollte nicht abschaltbar sein, um Verwirrung zu vermeiden
    markers.addOptions({displayInLayerSwitcher: false});

    // Wenn hier die Reihenfolge geändert wird, dann muss auch die
    // updateMapLink() Funktion aktualisiert werden
    map.addLayers([mapnik, osma, cycle, // opnv, 
	hill, markers]);
    // WÃ¤hle Standardkarte
    switch(defmap.toLowerCase()) {
        default:
        case "mapnik":
            map.setBaseLayer(mapnik);
            break;
        case "osma":
            map.setBaseLayer(osma);
            break;
        case "cycle":
            map.setBaseLayer(cycle);
            break;
        case "opnv":
            map.setBaseLayer(opnv);
            break;
    }


    // FÃ¼gt alle Marker der Karte hinzu und zoomt auf die eingestellte
    var zoom=-1;
    var backup=[places[0][0].clone(), places[0][1]];
    for(var i=0; i < places.length; i++) {
        if(zoomTo.toLowerCase() == places[i][2].toLowerCase()) {
            zoom=i;
            backup=[places[i][0].clone(), places[i][1]];
        }
        places[i][0].transform(proj4326, map.getProjectionObject());
        addMarker(places[i], markers, map);

    }
    if(zoom == -1) zoom=0;

    map.setCenter (places[zoom][0], places[zoom][1]);

    map.addControl(permalink=new OpenLayers.Control.Permalink());
    map.events.register('moveend', map, updateMapLink);

    // FÃ¼gt einen Link zur OpenStreetMap ein sowie einen "grÃ¶ÃŸere Version"
    // Link, der den aktuellen Bereich auf openstreetmap.org anzeigt
    updateMapLink();
}

/**
 * Erstellt mit Hilfe der Permalink-Funktion einen Link der auf
 * openstreetmap.org bzw. Öpnvkarte.de führt, wo man die Karte dann fast
 * im Vollbild betrachten kann.
**/
function updateMapLink() {
    var maptext=document.getElementById("showLargerVersion");
    if(!maptext || !permalink) return;

    var p = permalink.createParams();

    var url = "http://www.openstreetmap.org/index.html";
    var lay = "";
    // ÖPNV Karte
    if(p.layers[3] == "B") {
        url = "http://www.xn--pnvkarte-m4a.de";
        lay = "BT";
    } else {
        // Ansonsten einfach die One-Hot-Kodierung übernehmen (bis auf
        // das Häkchen bei "Orte", da das auf der OpenStreetMap eine
        // andere Bedeutung hat)
        lay = (p.layers).substring(0, 4);
    }

    maptext.innerHTML='<a href="'+url+'?lat='+p.lat+'&lon='+p.lon
        +'&zoom='+p.zoom+'&layers='+lay+'">Größere Version anzeigen</a>';
}

