var map, geocoder;

function makeGmap(on_o) {
    if (GBrowserIsCompatible()) {
        on_o.style.display = 'block';
        map = new GMap2(on_o);
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
        GEvent.addListener(map, "dblclick", function(overlay,point) { map.panTo(point); });
                
        return map;
    } else return false;
}

function mapType(i) {
    return G_DEFAULT_MAP_TYPES[i-1];
}

function mapIType(s) {
    switch(s) {
        case 'Hybrid': return 3; break;
        case 'Satellite': return 2; break;
        case 'Map': default: return 1; break;
    }
}

function defaultIcon() {
    var icon = new GIcon(G_DEFAULT_ICON);
    icon.image = '/media/images/markers/ppin.png';
    icon.shadow = '/media/images/markers/shdw.png';
    icon.iconSize = new GSize(32,32);
    icon.shadowSize = new GSize(59,32);
    return icon;
}

function firePoints(map,points,minZoom) {
    var bounds = new GLatLngBounds(), zl=1;
    map.setCenter(new GLatLng(0,0),0);
    map.clearOverlays();
    var mt = mapType(0);
    var mgr = new GMarkerManager(map);
    var baseIcon = new GIcon();
    baseIcon.shadow = "";
    baseIcon.iconSize = new GSize(29, 46);  
    baseIcon.iconAnchor = new GPoint(29, 0);
    baseIcon.infoWindowAnchor = new GPoint(29,0);
    
    for(var i=0;i<points.length;i++) {
        var point = points[i];
        if (point.icon) {
            var icon = new GIcon(baseIcon);
            icon.image = '/media/images/markers/lightblue'+point.icon+'.png';
        } else {
            var icon = defaultIcon();
        }
        var marker = new GMarker(new GLatLng(point.lat,point.lng),icon);
        marker._infoHtml = '<a href="'+point.url+'">' + point.title +'</a>';
        marker._contentUrl = point.contenturl;
        marker._zl = point.zoom;
        marker._mm = point.mode;
        
        bounds.extend(marker.getPoint());
        if (point.url && point.title) {
            marker._hash = point.url.slice(1);
            if (point.url.slice(0,1) == '#') {
                GEvent.addListener(marker, "click", function() {
                    location.hash = this._hash;
                });
            } else {
                GEvent.addListener(marker, "click", function() {
                    map.savePosition();
                    map.setCenter(this.getPoint(), this._zl, mapType(this._mm));
                    if (this._contentUrl) { 
                        var m = this;
                        $.get(this._contentUrl, function(c){ m.openInfoWindowHtml(c); });
                    } else { 
                        this.openInfoWindowHtml(this._infoHtml);
                    }
                });
                GEvent.addListener(marker,'infowindowclose',function() {  map.returnToSavedPosition(); map.setMapType(mapType(1)); });
            }
        }
        if (point.zoom) { zl = point.zoom; }
        if (point.mode && points.length == 1) { 
            mt = mapType(point.mode); 
        } else {
            mt = mapType(1);
        }
        //mgr.addMarker(marker,Math.floor(i/10),17);
        map.addOverlay(marker);
    }
    map.setMapType(mt);
    map.setCenter(bounds.getCenter());
    if (points.length > 1) {
        zl = map.getBoundsZoomLevel(bounds);
        if (zl > minZoom) zl = minZoom;
    }
    map.setZoom(zl);
};

function savePoint(target,country) {
    var lat = map.getCenter().lat(), 
        lng = map.getCenter().lng(),
        zoom = map.getZoom(),
        type = mapIType(map.getCurrentMapType().getName());
    var grp =  lat + '|' +  lng +'|'+ type +'|'+ zoom +'|' + country;
    target.value=grp;
}

function initMap(o, callback) {
    var mapdiv = document.getElementById('mapdiv') || document.createElement('div');
    mapdiv.id ="mapdiv";
    
    o.parentNode.insertBefore(mapdiv, o.nextSibling);
    if (GBrowserIsCompatible()) {
        mapdiv.style.display = 'block';
        mapdiv.style.height='375px';
        map = makeGmap(mapdiv);
        var ll;
        if (o.value && (ll = o.value.split('|'))) {
            var point0 = new GLatLng(ll[0],ll[1]);
            mode = (ll[2] ? parseInt(ll[2]):10);
            zoom = (ll[3] ? parseInt(ll[3]):1);
            map.setCenter(point0, zoom, mapType(mode));
        } else {
            var point0 = new GLatLng(46.8601910156703,8.876953125);
            map.setCenter(point0, 4, mapType(1));
        }
        marker = new GMarker(point0, {'icon':defaultIcon(), 'draggable':true});
        var sp = function() {
            if (callback) {
                callback();
            }
            savePoint(o,'');
        }
        GEvent.addListener(map, "dblclick", function(overlay,point) {
            marker.setPoint(point)
            map.panTo(point);
            savePoint(o,'');
        });
        GEvent.addListener(map,'zoomend', sp);
        GEvent.addListener(map,'maptypechanged', sp);
        GEvent.addListener(marker, "dragstart", function() { if(callback) {callback();} map.closeInfoWindow(); });
        GEvent.addListener(marker, "dragend", function() {
            p = marker.getPoint();
            map.panTo(p);
            sp();
            crossDomainCallOnGeoNames(p);
        });
        map.addOverlay(marker);
        savePoint(o,'');
      }
}

function destinations(o,data) {
    if ((map = makeGmap(o)) != false) {
        var points = [];
        for(var i=0;i<data.length;i++) {
            var p = { 'lat': data[i][0], 'lng':data[i][1], 'mode':data[i][2], 'zoom': parseInt(data[i][3]), 'url': data[i][4], 'title':data[i][5], 'contenturl':data[i][6] };
            points.push(p);
        }
        firePoints(map,points,10);    
    }
}

function tb_destinations(o, data) {
    if ((map = makeGmap(o)) != false) {
        var points = [];
        for(var i=0;i<data.length;i++) {
            var p = { 'lat': data[i][0], 'lng':data[i][1], 'mode':data[i][2], 'zoom': parseInt(data[i][3]), 'url': data[i][4], 'title':data[i][5], 'contenturl':null, 'icon':data[i][6] };
            points.push(p);
        }
        firePoints(map,points,100);
        map.setMapType(mapType(points[0].mode));
    }    
}

function gcCCode(langCode) {
    switch(langCode){
        case 'de': case 'it': case 'fr': return langCode; break;
        default: return 'us';
    }
}

function crossDomainCallOnGeoNames(p) {
    var newScript = document.createElement("script");
    newScript.setAttribute('src', 'http://ws.geonames.org/findNearbyPlaceNameJSON?lat='+p.lat()+'&lng='+p.lng()+'&callback=foundPlace');
    document.getElementsByTagName('body')[0].appendChild(newScript);
}

function foundPlace(json){ 
    places = eval(json)
    if(places.geonames[0]) {
        var place = places.geonames[0];
        $('#id_destination').val(place['name']+', '+place['countryName']);
    }
}

function gcBind(o, target, cCode, initStatus) {
    var STATUS_INVALID = 0, STATUS_VALID = 1, STATUS_VOID = 2;
    var status=STATUS_VALID, timeout = 750, oTimeout, 
    setStatusVoid = function() {
        status = STATUS_VOID;
        $('#destination_name_status').attr('class','');
    }, setStatusValid = function() {
        status = STATUS_VALID;
        $('#destination_name_status').html('<a class="pick" href="#">'+gettext('or pick on map...')+'</a>').attr('class','valid');
        var mapdiv = document.getElementById('mapdiv') || document.createElement('div');
        mapdiv.id = 'mapdiv';
        $(mapdiv).empty().hide();
        $('#maphelp').hide();
        hideSuggest();        
        $('#destination_name_status a.pick').click(function(){
            hideSuggest();
            initMap(target.get(0),initMapCB);
            mapHelp();
            return false
        });
    }, setStatusInvalid = function() {
        status = STATUS_INVALID;
        $('#destination_name_status').html('<a class="button" href="#">'+gettext('SAVE')+'</a>').attr('class','invalid');
        $('#destination_name_status a.button').click(function(){
            if (o.val().length > 2) {
                hideSuggest();
                savePoint(target.get(0),'');
                setStatusValid();
            }
            return false;
        });
    }, mkClick = function(place) {
        return function() {
            target.val(place.Point.coordinates[1]+'|'+place.Point.coordinates[0]+'|1|10|'+place.AddressDetails.Country.CountryNameCode);
            o.val($(this).html());
            setStatusValid();
            return false;
        }
    }, mkPickClick = function() {
        return function() {
            o.val('');
            setStatusValid();
            initMap(target.get(0),initMapCB);
            mapHelp();
            initMapCB();
            return false;
        }
    }, initMapCB = function() {
        setStatusInvalid();
        hideSuggest();
        o.val('');
        return false; 
    }, hideSuggest=function() {
        $('#gsr ul').empty();
        $('#gsr').css({display:'none'});  
    }, setStatus = function(status) {
        switch(status) {
            case STATUS_INVALID: return setStatusInvalid(); break;
            case STATUS_VALID: return setStatusValid(); break;
            case STATUS_VOID: return setStatusVoid(); break;
        }
        return false;
    }, mapHelp = function(hlp) {
        hlp = hlp || $('#maphelp').html();
        $('#maphelp').html(hlp).show();
    }
    
    $('#gsr a.pick').click(mkPickClick());
    
    if (o.val().length) {
        setStatusValid();
    } else if (initStatus !== undefined) {
        setStatus(initStatus);
    }
    
    o.keyup(function(e) {
        if (status == STATUS_VALID || status == STATUS_VOID) {
            clearTimeout(oTimeout);
            oTimeout = setTimeout(function() {
                if (o.val().length > 2) {
                    $('#gsr').css({display:'block'});
                    geocoder = geocoder || new GClientGeocoder();
                    geocoder.setBaseCountryCode(cCode);
                    geocoder.getLocations(o.val(), function(response){
                        if (response && response.Status.code == 200) {
                            $('#gsr ul').empty();
                            for (var i=0;i<response.Placemark.length;i++) {
                                var place = response.Placemark[i];
                                $('#gsr ul').append(
                                        $('<li></li>').append(
                                            $('<a href="#"></a>').html(place.address).click(mkClick(place))
                                        )
                                ).show();
                            }
                        }
                    });
                }
            }, timeout);
        } else {
            setStatusInvalid();
        }
    });
}

function showMap(div, callback) {
    var lat = $('.latitude',div.parent()).html(),
        lng = $('.longitude',div.parent()).html(),
        ctry = $('.country',div.parent()).html(),
        mode = $('.mode',div.parent()).html(),
        zoom = $('.zoom',div.parent()).html();
    div.css({display:'block'});
    destinations(div.get(0), [[lat,lng,mode,zoom,'','',false]]);
    if (callback)
        callback();
}
function showMainMap(div) {
    tb_destinations(div.get(0), mainmapdata());
}

