
/**
 * Diese Datei enthält einige Funktionen für den Umgang mit GoogleMaps.
 *
 * - Funktionen für benutzerdefinierte Marker
 * - Handhabung (Erstellung) von Markern
 * - Eventbehandlung
 * - Kartensteuerung (Zoomen auf ein Objekt)
 * - Schnittstelle zwischen ImmoFlow (AS) und GoogleMaps (JS)
 *
 * @modified 01.06.2009
 * @author Mathias Kahl
 */

// Globaler Handler für die GoogleMaps-Karte (es kann nur eine geben)
var map;

// Verwaltet die Marker auf der Karte
var markers = new Object();

// Tabelle, welche den String "$lat $lang" auf die ID eines Objekts abbildet
var idTable = [];

// Der zuletzt angefasste Marker
var lastRecentMarkerKey = false;

// Legt ein Ziel für ein Einzoomen fest (Zoomstufe und Koordinaten)
var zoomDestination = {zoomLevel : 0, latitude : 0, longitude : 0};

// Gibt an, ob Events abgefangen werden sollen
var catchEvents = false;

// Einige benutzerdefinierte Marker-Icons (werden in maps_init initialisiert)
var stdMarkerIcon = false;
var bigMarkerIcon = false;
var chipMarkerIcon = false;

// Marker für das aktuelle Objekt
var bigMarker = false;

var mapLoaded = false;

var ImmoFlowReady = false;

// Lädt GoogleMaps asynchron nach
function loadGM_async() {
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "http://maps.google.com/maps?file=api&amp;v=2&amp;key="+gmApiKey+"&async=2&callback=loadGoogleMap";
  alert("GM: " + script.src);
  document.body.appendChild(script);
}

// Erstellt einen Marker in Form eines S&M-Logos (klein)
function getMarkerSmallLogo()
{
    var myIcon = new GIcon();
    myIcon.image = 'markers/small-logo/image.png';
    myIcon.shadow = 'markers/small-logo/shadow.png';
    myIcon.iconSize = new GSize(32,34);
    myIcon.shadowSize = new GSize(49,34);
    myIcon.iconAnchor = new GPoint(0,34);
    myIcon.infoWindowAnchor = new GPoint(16,0);
    myIcon.printImage = 'markers/small-logo/printImage.gif';
    myIcon.mozPrintImage = 'markers/small-logo/mozPrintImage.gif';
    myIcon.printShadow = 'markers/small-logo/printShadow.gif';
    myIcon.transparent = 'markers/small-logo/transparent.png';
    myIcon.imageMap = [31,0,31,1,31,2,31,3,31,4,26,5,26,6,26,7,31,8,31,9,31,10,31,11,31,12,31,13,31,14,31,15,31,16,31,17,31,18,11,19,10,20,10,21,9,22,8,23,8,24,7,25,6,26,6,27,5,28,4,29,4,30,4,31,4,32,3,33,0,33,0,32,0,31,0,30,1,29,3,28,3,27,4,26,5,25,6,24,6,23,7,22,8,21,9,20,9,19,10,18,11,17,11,16,11,15,11,14,11,13,11,12,11,11,11,10,11,9,11,8,11,7,11,6,11,5,11,4,11,3,11,2,11,1,11,0];

    return myIcon;
}

function getMapIcon(name)
{
    var myIcon;

    if(name == "v2-klein") {
        myIcon = new GIcon();
        myIcon.image = 'markers/v2-klein/image.png';
        myIcon.shadow = 'markers/v2-klein/shadow.png';
        myIcon.iconSize = new GSize(32,34);
        myIcon.shadowSize = new GSize(49,34);
        myIcon.iconAnchor = new GPoint(0,34);
        myIcon.infoWindowAnchor = new GPoint(16,0);
        myIcon.printImage = 'markers/v2-klein/printImage.gif';
        myIcon.mozPrintImage = 'markers/v2-klein/mozPrintImage.gif';
        myIcon.printShadow = 'markers/v2-klein/printShadow.gif';
        myIcon.transparent = 'markers/v2-klein/transparent.png';
        myIcon.imageMap = [31,0,31,1,31,2,31,3,31,4,27,5,27,6,27,7,27,8,31,9,31,10,31,11,31,12,31,13,31,14,31,15,31,16,31,17,31,18,11,19,10,20,10,21,9,22,8,23,8,24,7,25,6,26,5,27,5,28,4,29,3,30,3,31,3,32,3,33,0,33,0,32,0,31,0,30,3,29,3,28,4,27,5,26,5,25,6,24,7,23,8,22,8,21,9,20,10,19,10,18,11,17,11,16,11,15,11,14,11,13,11,12,11,11,11,10,11,9,11,8,11,7,11,6,11,5,11,4,11,3,11,2,11,1,11,0];
    } else if(name == "v2-gross") {
        myIcon = new GIcon();
        myIcon.image = 'markers/v2-gross/image.png';
        myIcon.shadow = 'markers/v2-gross/shadow.png';
        myIcon.iconSize = new GSize(55,59);
        myIcon.shadowSize = new GSize(85,59);
        myIcon.iconAnchor = new GPoint(0,59);
        myIcon.infoWindowAnchor = new GPoint(28,0);
        myIcon.printImage = 'markers/v2-gross/printImage.gif';
        myIcon.mozPrintImage = 'markers/v2-gross/mozPrintImage.gif';
        myIcon.printShadow = 'markers/v2-gross/printShadow.gif';
        myIcon.transparent = 'markers/v2-gross/transparent.png';
        myIcon.imageMap = [54,0,54,1,54,2,54,3,54,4,54,5,54,6,54,7,46,8,46,9,46,10,46,11,46,12,46,13,46,14,54,15,54,16,54,17,54,18,54,19,54,20,54,21,54,22,54,23,54,24,54,25,54,26,54,27,54,28,54,29,54,30,54,31,54,32,19,33,18,34,18,35,17,36,16,37,15,38,15,39,14,40,13,41,13,42,12,43,11,44,11,45,10,46,9,47,9,48,8,49,7,50,7,51,6,52,7,53,7,54,7,55,7,56,7,57,6,58,1,58,0,57,0,56,0,55,0,54,0,53,0,52,1,51,6,50,7,49,7,48,8,47,9,46,9,45,10,44,11,43,11,42,12,41,13,40,13,39,14,38,15,37,15,36,16,35,17,34,17,33,18,32,19,31,19,30,19,29,19,28,19,27,19,26,19,25,19,24,19,23,19,22,19,21,19,20,19,19,19,18,19,17,19,16,19,15,19,14,19,13,19,12,19,11,19,10,19,9,19,8,19,7,19,6,19,5,19,4,19,3,19,2,19,1,19,0];
    }

    return myIcon;
}

function getMarkerChipLogo()
{
    var myIcon = new GIcon();
    myIcon.image = 'markers/chip-logo/image.png';
    myIcon.shadow = 'markers/chip-logo/shadow.png';
    myIcon.iconSize = new GSize(65,67);
    myIcon.shadowSize = new GSize(99,67);
    myIcon.iconAnchor = new GPoint(65,67);
    myIcon.infoWindowAnchor = new GPoint(33,0);
    myIcon.printImage = 'markers/chip-logo/printImage.gif';
    myIcon.mozPrintImage = 'markers/chip-logo/mozPrintImage.gif';
    myIcon.printShadow = 'markers/chip-logo/printShadow.gif';
    myIcon.transparent = 'markers/chip-logo/transparent.png';
    myIcon.imageMap = [40,1,43,2,45,3,47,4,49,5,50,6,52,7,53,8,54,9,55,10,56,11,57,12,57,13,58,14,59,15,59,16,60,17,60,18,61,19,61,20,62,21,62,22,62,23,63,24,63,25,63,26,63,27,63,28,63,29,63,30,63,31,63,32,63,33,63,34,63,35,63,36,63,37,63,38,63,39,62,40,62,41,62,42,61,43,61,44,61,45,60,46,59,47,59,48,58,49,57,50,57,51,56,52,55,53,53,54,54,55,55,56,56,57,57,58,58,59,59,60,64,61,64,62,64,63,64,64,64,65,64,66,60,66,59,65,59,64,27,63,22,62,19,61,17,60,15,59,14,58,12,57,11,56,10,55,9,54,8,53,7,52,6,51,6,50,5,49,4,48,4,47,3,46,3,45,2,44,2,43,2,42,1,41,1,40,2,39,2,38,1,37,1,36,1,35,1,34,0,33,0,32,0,31,0,30,0,29,0,28,0,27,0,26,0,25,1,24,1,23,1,22,1,21,2,20,2,19,2,18,3,17,3,16,4,15,4,14,5,13,6,12,6,11,7,10,8,9,9,8,10,7,12,6,13,5,14,4,16,3,19,2,22,1];

    return myIcon;
}

function getMarkerNewLogo()
{
    var myIcon = new GIcon();
    myIcon.image = 'markers/logo-neu/image.png';
    myIcon.shadow = 'markers/logo-neu/shadow.png';
    myIcon.iconSize = new GSize(55,59);
    myIcon.shadowSize = new GSize(85,59);
    myIcon.iconAnchor = new GPoint(0,59);
    myIcon.infoWindowAnchor = new GPoint(28,0);
    myIcon.printImage = 'markers/logo-neu/printImage.gif';
    myIcon.mozPrintImage = 'markers/logo-neu/mozPrintImage.gif';
    myIcon.printShadow = 'markers/logo-neu/printShadow.gif';
    myIcon.transparent = 'markers/logo-neu/transparent.png';
    myIcon.imageMap = [54,0,54,1,54,2,54,3,54,4,54,5,54,6,54,7,46,8,46,9,46,10,46,11,46,12,46,13,46,14,54,15,54,16,54,17,54,18,54,19,54,20,54,21,54,22,54,23,54,24,54,25,54,26,54,27,54,28,54,29,54,30,54,31,20,32,19,33,18,34,18,35,17,36,16,37,16,38,15,39,14,40,14,41,13,42,12,43,12,44,11,45,10,46,9,47,9,48,8,49,7,50,7,51,6,52,6,53,6,54,6,55,6,56,6,57,5,58,0,58,0,57,0,56,0,55,0,54,0,53,1,52,5,51,6,50,6,49,7,48,8,47,8,46,9,45,10,44,10,43,11,42,12,41,12,40,13,39,14,38,14,37,15,36,16,35,17,34,17,33,18,32,19,31,19,30,19,29,19,28,19,27,19,26,19,25,19,24,19,23,19,22,19,21,19,20,19,19,19,18,19,17,19,16,19,15,19,14,19,13,19,12,19,11,19,10,19,9,19,8,19,7,19,6,19,5,19,4,19,3,19,2,19,1,19,0];

    return myIcon;
}

// Initialisiert die benutzerdefinierten Marker
function setupCustomMarkers()
{
    if(!stdMarkerIcon) {
        //stdMarkerIcon = getMarkerSmallLogo();
        stdMarkerIcon = getMapIcon("v2-klein");
    }
    if(!bigMarkerIcon) {
        //bigMarkerIcon = getMarkerNewLogo();
        bigMarkerIcon = getMapIcon("v2-gross");
    }
    if(!chipMarkerIcon) chipMarkerIcon = getMarkerChipLogo();
}

/*
 * Alias für setupCustomMarkers()
 * @legacy Zwecks Kompatibilität zu alten Client-Versionen
 */
function setupCustomMarker()
{
    setupCustomMarkers();
}

/*
 * Liefert die aktuelle ImmoFlow-Instanz im Dokument
 */
function getImmoFlow()
{
    var isIE = navigator.appName.indexOf("Microsoft") != -1;
    var isOpera = navigator.appName.indexOf("Opera") != -1;

    if(isOpera) {
        return document.getElementById("ImmoFlow");
    } else if(!isIE) {
        return document.ImmoFlow;
    } else {
        return document.getElementById("ImmoFlowObj");
    }
}

/**
 * Verwaltet das Eventhandling
 */
function mapEvents() {
    GEvent.addListener(map, "zoomend", onMapZoomed );
}

// Zoomt auf die gewünschte Position ein
function mapZoomIn(dest) {
    zoomDestination = dest;
    map.zoomIn(new GLatLng(dest.latitude, dest.longitude), true, true);
}

// Wünscht auf die gewünschte Position aus
function mapZoomOut(dest) {
    zoomDestination = dest;
    map.zoomOut(new GLatLng(dest.latitude, dest.longitude), true);
    map.setCenter(new GLatLng(dest.latitude, dest.longitude));
}

// Event-Behandlung für Zooms, führt Animationen aus
function onMapZoomed(before, now) {
    if(!catchEvents) return;
    var direction = now - before;
    if(direction < 0) { // Zoom Out
        if(now > zoomDestination.zoomLevel) {
            mapZoomOut(zoomDestination);
        } else catchEvents = false;
    } else { // Zoom In
        if(now < zoomDestination.zoomLevel) {
            mapZoomIn(zoomDestination);
        } else catchEvents = false;
    }
}

// Event-Behandlung für Klicks, zeigt das angeklickte Objekt im ImmoFlow
function onMarkerClick(latlng) {

    if(false) {
        var keys = latlng.lat() + " " + latlng.lng();
        maps_focusObject(keys);
        return;
    }

    //getImmoFlow().showid(108);
    printLog("onMarkerClick(" + latlng + ")");

    getImmoFlow().showcoord(latlng.lat(), latlng.lng());
    var key = latlng.lat() + " " + latlng.lng();
    maps_setCurrentMarker(key);
    maps_selectResultSlot([latlng.lat(),latlng.lng(), idTable[key]]);

    // Auf diesen Marker zentrieren
    catchEvents = true;
    var zoomTo = 11; //12;
    if(map.getZoom() < zoomTo) mapZoomIn( {zoomLevel:zoomTo, latitude:latlng.lat(), longitude:latlng.lng()} );
    else map.panTo(new GLatLng(latlng.lat(), latlng.lng())); 
}

// Erhöht die Zoomstufe um 1
function mapZoomInc() {
    var zoom = map.getZoom();
    if(zoom < 17) map.setZoom(zoom+1);
}

// Erniedrigt die Zoomstufe um 1
function mapZoomDec() {
    var zoom = map.getZoom();
    if(zoom > 11) map.setZoom(zoom-1);
}

// Erstellt einen Standardmarker mit Infofenster. Der Inhalt entspricht 'html'.
function createMarker(point,html, icon) {
    if(!stdMarkerIcon) setupCustomMarker();
    if(icon == undefined) icon = stdMarkerIcon;
    var marker = new GMarker(point,{icon:icon, title:'Marker X'});
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(html);
    });
    return marker;
}

// Erstellt einen einfachen Marker ohne Infofenster und Click-Event
function createPlainMarker(point, icon, title) {
	if(!stdMarkerIcon) setupCustomMarker();
    if(icon == undefined) icon = stdMarkerIcon;
	var marker = IE6() ? new GMarker(point) : new GMarker(point, {icon:icon, title:title});
	return marker;
}

// Erstellt einen einfachen Marker, der bei Klick auf 'url' weiterleitet
function createLinkMarker(point, url, icon) {
	if(!stdMarkerIcon) setupCustomMarker();
    if(icon == undefined) icon = stdMarkerIcon;

	var marker = IE6() ? new GMarker(point) : new GMarker(point,icon);
	GEvent.addListener(marker, "click", function() {
		document.location.href = url;});
	return marker;
}

var currentSlot = "";

function ImmoFlow_ShowCoords(key)
{
    var params = key.toString().split(" ");
    getImmoFlow().showcoord(params[0], params[1]);
}

// ActionScript-Javascript-Schnittstelle
function ImmoFlow_DoFSCommand(action,param) {

    printLog("ImmoFlow_DoFSCommand(" + action + "," + param + ")");

    if(!mapLoaded && false) {
        var call = "ImmoFlow_DoFSCommand('" + action + "', '" + param + "')";
        printLog("delay 500 (map not loaded): " + call);
        window.setTimeout(call, 500);
        return;
    }
    
    switch(action) {
        case 'show': // zeigt ein Objekt auf der Karte
            catchEvents = true;
            var params = param.toString().split(" ");
            var zoomTo = 11; //12;

            printLog("show [" + params[0] + "," + params[1] + "]");
            
            if(map.getZoom() < zoomTo)
            {
                mapZoomIn( {zoomLevel:zoomTo, latitude:parseFloat(params[0]),
                    longitude:parseFloat(params[1])} );
            }
            else
            {
                map.panTo(new GLatLng(parseFloat(params[0]), parseFloat(params[1])));
            }

            printLog("selectResultSlot...");
            maps_selectResultSlot(params);

            printLog("setCurrentMarker...");
            maps_setCurrentMarker(param);

            break;
    }
}

function maps_selectResultSlot(params)
{
    if(currentSlot != "") $(currentSlot).removeClass("currentSlot");

    printLog("selectResultSlot: " + params[0] + ", " + params[1] + ", " + params[2]);
    if(params[2] == undefined) {
        var key = params[0] + " " + params[1];
        params[2] = idTable[key];
        printLog("params[2] = idTable[" + key + "] = " + params[2]);
    }
    var resultSlot = "#r" + params[2];

    $(resultSlot).addClass("currentSlot");
    currentSlot = resultSlot;

    if(numResultPages > 1)
    {
        // Seite anzeigen
        if(numResultPages == undefined) numResultPages = 10;
        var i = 0;
        for(;i<numResultPages;i++) if( $(resultSlot).hasClass("page"+(i+1)) ) break;
        showResultPage(i+1,numResultPages);
    }
}

function maps_focusObject(key)
{
    ImmoFlow_DoFSCommand('show', key);
}

function maps_setCurrentMarker(key)
{
    printLog("maps_setCurrentMarker(" + key + ")");
    if(lastRecentMarkerKey != false) maps_showMarkers(lastRecentMarkerKey);
    maps_hideMarkers(key);
    var latlng = key.toString().split(" ");
    printLog("bigMarker: " + bigMarker + "(" + latlng[0] + "," + latlng[1] + ")");
    bigMarker.setLatLng(new GLatLng(latlng[0],latlng[1]));    
    lastRecentMarkerKey = key;
}

function maps_getPoint(key)
{
    var latlng = key.toString().split(" ");
    return new GLatLng(latlng[0],latlng[1]);
}

function maps_addMarker(key,marker)
{
    if(markers[key] == undefined) {
        markers[key] = new Array();
        markers[key].push(marker);
    } else {
        markers[key].push(marker);
    }
}

function maps_getMarkers(key)
{
    return markers[key];
}

function maps_hideMarkers(key)
{    
    var parts = key.split(" ");
    key = parts[0] + " " + parts[1];

    if(markers[key] == undefined) {
        key = parts[0].substr(0, parts[0].length-1) + " " + parts[1];
    }

    if(markers[key] == undefined) {
        return;
    }

    for(var i=0;i<markers[key].length;i++) {
        markers[key][i].hide();
    }
}

function maps_showMarkers(key)
{
    var parts = key.split(" ");
    key = parts[0] + " " + parts[1];
    if(markers[key] == undefined) {
        key = parts[0].substr(0, parts[0].length-1) + " " + parts[1];
    }
    if(markers[key] == undefined) {
        return;
    }

    for(var i=0;i<markers[key].length;i++) {
        markers[key][i].show();
    }
}

// Initialisiert die Map-Funktionalitäten
function maps_init()
{
    mapEvents();
    setupCustomMarkers();
}

function maps_postinit()
{
    bigMarker = IE6() ? new GMarker(new GLatLng(0,0)) : new GMarker(new GLatLng(0,0), bigMarkerIcon);
    map.addOverlay(bigMarker);
}

function maps_addPlainMarkers(positions, callback)
{
    for(var i=0;i<positions.length;i++) {
        var point = new GLatLng(positions[i][0], positions[i][1]);
        var marker = createPlainMarker(point, undefined, positions[i][3]);
        GEvent.addListener(marker, "click", onMarkerClick);

        var key = positions[i][0] + " " + positions[i][1];

        idTable[key] = positions[i][2];

        maps_addMarker(key, marker);
        map.addOverlay(marker);
    }

    if(callback != undefined)
        callback();
}

function maps_addLinkMarkers(positions, callback)
{
    for(var i=0;i<positions.length;i++) {
        var point = new GLatLng(positions[i][0], positions[i][1]);
        var marker = createLinkMarker(point, baseUrl + positions[i][2], stdMarkerIcon);
        var key = positions[i][0] + " " + positions[i][1];
        maps_addMarker(key, marker);
        map.addOverlay(marker);
    }

    if(callback != undefined)
        callback();
}

var g_mapData;
var g_activeKey;
var g_searchArgs;

function maps_selectSearch(args)
{
    g_searchArgs = args;
}

function maps_loadPlainMarkers(callback)
{
    var url = "/factory.php?output=JSON&request=RealtyCoords&" + g_searchArgs;
    $.getJSON(url,
            function(data){
              g_mapData = data;
              maps_addPlainMarkers(data, callback);
              maps_placeActiveMarker();
            });
}

function maps_loadLinkMarkers(callback)
{
    var url = "/factory.php?output=JSON&request=RealtyCoords&" + g_searchArgs;
    $.getJSON(url, null,
            function(data){
              g_mapData = data;
              maps_addLinkMarkers(data, callback);
              maps_placeActiveMarker();
            });
}

function maps_selectActive(key)
{
    g_activeKey = key;
}

function maps_placeActiveMarker()
{
    if(g_activeKey == undefined) return;
    var coords = g_activeKey.toString().split(" ");
    maps_hideMarkers(g_activeKey);
    var current = createPlainMarker(new GLatLng(coords[0],coords[1]), bigMarkerIcon);
    map.addOverlay(current);
    printLog("Big Marker added (" + coords + ")");
}
