/////// COPYRIGHT 2009 by icomedias gmbh, All rights reserved ////////

MapView = function(config){
    //if (config.canvasId) this.canvasId=config.canvasId;
    
    if (config) {
        for (var p in config) {
            this[p] = config[p];
        }
    }
    
};

MapView.prototype = {
    translations: {
        from_here: 'Von hier',
        to_here: 'Hierher',
        go: 'Los!',
        source_address: 'Startadresse',
        target_address: 'Zieladresse',
        calculate_route: 'Route berechnen',
        back: 'Zurück',
        address_not_found: 'Adresse konnte nicht gefunden werden!'
    },
    numberColor: 'ffffff',
    defaultMarkerWidth: 23,
    defaultMarkerHeight: 26,
    defaultLat: 47,
    defaultLng: 15,
    defaultZoom: 5,
    routePlanning: true,
    customControls: [],
    canvasId: 'map_canvas',
    datalistId: 'datalist',
    data: null,
    map: null,
    markers: [],
    standardMarker: 'detail.png',
    standardMarkerNumber: 'Marker-rot.png',
    standardMarkerHighlight: '_detail.png',
    standardMarkerNumberHighlight: 'Marker-gruen.png',
    overlays: null,
    highlightMarker: null,
    markerMapping: {},
    directions: null,
    selected_marker_glatlng: null,
    geocoder: null,
    mapTypeControl: 'NORMAL', // MENU | NORMAL | null,
    center: null, // {lat:NUMBER,lng:NUMBER} , if null: center will be calculated
    zoom: null, // if null zoom will be calculated
    bubbleMaxWidth: '400',
    bubbleMaxHeight: '300',
    showBubble: true,
    listeners: {}, // marker_click | marker_create | map_mouseenter | map_mouseout | map_mousemove | map_load 
    numberMarker: false,
    path: '/georss/geo/',
    cluster: true,
    retry: false,
    showShadow: true,
    imgCache: {}, // for fast finding width and height
    getCoordinates: function(data){
        if (!data) 
            return;
        
        var coordinates = {
            lat_center: 0.0,
            lng_center: 0.0,
            lat_min: 90,
            lat_max: -90,
            lng_min: 180.0,
            lng_max: -180.0
        }
        
        for (var i = 0; i < data.length; i++) {
        
            var lat = parseFloat(data[i].lat);
            var lng = parseFloat(data[i].lng);
            
            if (lat < coordinates.lat_min) 
                coordinates.lat_min = lat;
            if (lng < coordinates.lng_min) 
                coordinates.lng_min = lng;
            if (lat > coordinates.lat_max) 
                coordinates.lat_max = lat;
            if (lng > coordinates.lng_max) 
                coordinates.lng_max = lng;
            
        }
        coordinates.lat_center = (coordinates.lat_max - coordinates.lat_min) / 2 + coordinates.lat_min;
        coordinates.lng_center = (coordinates.lng_max - coordinates.lng_min) / 2 + coordinates.lng_min;
        
        return coordinates;
    },
    
    mapMarkers: function(){
        // markerMapping matches the marker ids with the indexes of the marker array for faster searching
        for (var i = 0; i < this.markers.length; i++) 
            this.markerMapping[this.markers[i].id] = '' + i + '';
    },
    
    getMarker: function(id){
        // markerMapping maps the marker ids with the indexes of the marker array for faster searching
        if (!this.markerMapping[id]) 
            this.mapMarkers();
        return this.markers[this.markerMapping[id]];
    },
    
    createMarkers: function(data){
        var markers = [];
        for (var i = 0; i < data.length; i++) {
            var marker = this.createMarker(data[i]);
            markers.push(marker);
        }
        return markers;
    },
    
    resetHighlights: function(){
        var entrydivs = jQuery("div#" + this.datalistId).find('div');
        entrydivs.removeClass('item_highlight');
    },
    
    removeHighlight: function(){
        jQuery('div#entry' + this.highlightMarker.id).removeClass('item_highlight');
        this.map.removeOverlay(this.highlightMarker);
    },
    
    highlightFromMarker: function(id){
        this.highlight(id);
    },
    
    highlightFromList: function(id, click){
        if (!this.map) 
            return;
        
        this.highlight(id);
        
        if (!this.getMarker(id)) 
            return; // marker not found
        this.map.panTo(this.highlightMarker.getLatLng());
        this.map.panTo(this.highlightMarker.getLatLng());
        var marker = this.getMarker(id);
        if (click && marker.description) {
        
            var description = marker.description;
            if (this.routePlanning) 
                description += this.getRouteHtmlCode(marker);
            
            selected_marker_glatlng = marker.getLatLng(); //new GLatLng(marker.lat, marker.lng); 
            this.highlightMarker.openInfoWindowHtml("<b>" + marker.title + "</b><br/><br/>" + description, {
                maxWidth: this.bubbleMaxWidth,
                maxHeight: this.bubbleMaxHeight,
                autoScroll: true
            });
        }
    },
    
    highlight: function(id){
    
        if (!this.map) 
            return;
        // removing old highlight
        if (this.highlightMarker) 
            this.removeHighlight();
        
        var marker = this.getMarker(id);
        
        if (!marker) 
            return;
        jQuery('div#entry' + id).addClass('item_highlight');
        this.highlightMarker = this.createHighlightMarker(marker);
        this.map.addOverlay(this.highlightMarker, {
            zIndexProcess: function(){
                return 1000;
            }
        });
    },
    
    initDataList: function(){
        for (var i = 0; i < this.data.length; i++) {
            var output = '<div onClick="highlightFromList(' + this.data[i].id + ',true)" onMouseover="highlightFromList(' + this.data[i].id + ', false)" id="entry' + this.data[i].id + '" class="item">'
            output += this.data[i].num + " ";
            output += this.data[i].title;
            output += "</div>";
            jQuery("div#" + this.datalistId).append(output);
            //        console.debug(data[i]);
            //        html = "<b>" + data[i].title + "</b><br/><br/>" + data[i].description;
            //        $("div#entry" +  data[i].id).bind('click', function (e) { highlightMarker.openInfoWindowHtml(html) });
        }
    },
    
    initDataFromUrl: function(url){
        var scope = this;
        $.getJSON(url, function(response){
            data = response.items;
            if (!data && !this.retry) { // one retry to init cache on server
                this.retry = true;
                $.get(document.location.href, function(response){
                    $.getJSON(url, function(response){
                        data = response.items;
                        if (data) {
                            if (response.overlays) 
                                overlays = response.overlays;
                            if (data.length > 0) {
                                scope.data = data;
                                scope.initGMap();
                                scope.initDataList();
                            }
                        }
                    });
                });
            }
            if (!data) 
                return;
            if (response.overlays) 
                overlays = response.overlays;
            if (data.length > 0) {
                scope.data = data;
                scope.initGMap();
                scope.initDataList();
            }
        });
    },
    
    initList: function(url){
        setData(url);
    },
    
    initData: function(data){
    
        // search canvas
        var canvas = jQuery("div#" + this.canvasId);
        if (!canvas || canvas.length == 0) 
            return;
        
        if (data.overlays) 
            this.overlays = data.overlays;
        this.data = data.items;
        
        this.initGMap();
        if (this.data) 
            this.initDataList();
			
        if (this.listeners.map_load) {
            this.listeners.map_load(this);
        }
    },
    
    getImgSize: function(imgPath){
    
        var img = null;
        var width = null;
        var height = null;
        var size = null;
        if (this.imgCache[imgPath]) {
            img = this.imgCache[imgPath];
            width = img.width;
            height = img.height;
            size = new GSize(width, height);
        }
        else {
            img = new Image();
            img.src = imgPath;
            var width = 0;
            var height = 0;
            width = img.width;
            height = img.height;
            size = new GSize(width, height);
            this.imgCache[imgPath] = img;
        }
        
        return size;
        
    },
    
    createHighlightMarker: function(marker){
    
        if (!marker) 
            return;
        var data = marker.data;
        
        var latlng = marker.getLatLng();
        var icon = new GIcon(G_DEFAULT_ICON);
        if (!this.showShadow) 
            icon.shadow = this.path + "marker/transparent.png";
        
        var text = marker.num;
        
        var iconImg = this.standardMarkerHighlight;
        
        if (this.numberMarker && marker.num) 
            iconImg = this.standardMarkerNumberHighlight;
        
        if (data.icon) 
            iconImg = data.icon;
        if (data.iconOver) 
            iconImg = data.iconOver;
        
        if (this.numberMarker && marker.num != false) {
            icon.image = this.path + "marker.php?text=" + text + "&image=" + iconImg + "&color=" + this.numberColor;
        }
        else {
            icon.image = this.path + "marker/" + iconImg;
        }
        
        var size = this.getImgSize(icon.image);
        if (size.width == 0 && size.height == 0) 
            size = new GSize(this.defaultMarkerWidth, this.defaultMarkerHeight);
        
        //console.log(icon.image);
        
        icon.iconSize = size;
        icon.shadowSize = new GSize(size.width * 2, size.height);
        icon.iconAnchor = new GPoint(size.width / 2, size.height);
        
        
        highlightMarker = new google.maps.Marker(latlng, {
            icon: icon,
            title: marker.title,
            zIndexProcess: function(){
                return 5000;
            }
        });
        highlightMarker.id = '' + marker.id + '';
        highlightMarker.num = marker.num;
        highlightMarker.link = marker.link;
        highlightMarker.data = data;
        
        if (marker.description) 
            highlightMarker.description = marker.description;
        
        
        var scope = this;
        
        if (this.listeners.marker_click) {
            google.maps.Event.addListener(highlightMarker, "click", function(){
                scope.listeners.marker_click(highlightMarker)
            });
        }
        
        if (highlightMarker.description && this.showBubble) {
        
            var description = highlightMarker.description;
            
            if (this.routePlanning) 
                description += this.getRouteHtmlCode(highlightMarker);
            
            google.maps.Event.addListener(highlightMarker, "click", function(){
                selected_marker_glatlng = latlng;
                highlightMarker.openInfoWindowHtml('<b>' + marker.title + "</b><br/><br/>" + description + '', {
                    maxWidth: scope.bubbleMaxWidth,
                    maxHeight: scope.bubbleMaxHeight,
                    autoScroll: true
                });
            });
        }
        
        return highlightMarker;
    },
    
    createMarker: function(data){
    
        var latlng = new google.maps.LatLng(data.lat, data.lng);
        var icon = new GIcon(G_DEFAULT_ICON);
        if (!this.showShadow) 
            icon.shadow = this.path + "marker/transparent.png";
        
        var text = data.num;
        
        var iconImg = this.standardMarker;
        
        if (this.numberMarker && data.num) 
            iconImg = this.standardMarkerNumber;
        
        if (data.icon) 
            iconImg = data.icon;
        
        if (this.numberMarker && data.num != false) {
            icon.image = this.path + "marker.php?text=" + text + "&image=" + iconImg + "&color=" + this.numberColor;
        }
        else {
            icon.image = this.path + "marker/" + iconImg;
        }
        
        var size = this.getImgSize(icon.image);
        if (size.width == 0 && size.height == 0) 
            size = new GSize(this.defaultMarkerWidth, this.defaultMarkerHeight);
        
        icon.iconSize = size;
        icon.shadowSize = new GSize(size.width * 2, size.height);
        icon.iconAnchor = new GPoint(size.width / 2, size.height);
        
        var config = {
            icon: icon,
            title: data.title
        };
        if (data.hidden && data.hidden == true) 
            config.hide = true;
        
        var marker = new google.maps.Marker(latlng, config);
        
        
        marker.title = data.title;
        marker.id = data.id;
        marker.num = data.num;
        marker.link = data.link;
        
        marker.data = data;
        
        scope = this;
        
        if (data.description && this.showBubble) {
        
            marker.description = data.description;
            
            var description = data.description;
            if (this.routePlanning) 
                description += this.getRouteHtmlCode(marker);
            
            
            google.maps.Event.addListener(marker, "click", function(){
                selected_marker_glatlng = latlng;
                marker.openInfoWindowHtml("<b>" + data.title + "</b><br/><br/>" + description, {
                    maxWidth: scope.bubbleMaxWidth,
                    maxHeight: scope.bubbleMaxHeight,
                    autoScroll: true
                });
            });
            
        }
        
        var scope = this;
        google.maps.Event.addListener(marker, "mouseover", function(marker){
            scope.highlightFromMarker(this.id);
        });
        
        if (this.listeners.marker_create) {
            this.listeners.marker_create(marker);
        }
        
        return marker;
    },
    
    getRouteHtmlCode: function(marker){
        var code = '<br/><br/>'
        code += '<div id="direction_get_link_' + marker.id + '"><a href="#" onclick="jQuery(\'#direction_get_link_' + marker.id + '\').hide(); jQuery(\'#direction_saddr_' + marker.id + '\').show();">' + this.translations.calculate_route + '</a></div>';
        
        code += '<div id="direction_saddr_' + marker.id + '" style="display: none;">';
        code += this.translations.calculate_route + ': <b>' + this.translations.to_here + '</b> - <a href="#" onclick="jQuery(\'#direction_saddr_' + marker.id + '\').hide(); jQuery(\'#direction_daddr_' + marker.id + '\').show();">' + this.translations.from_here + '</a>';
        code += '<br/>' + this.translations.source_address + ': <br/><input onkeyup="if (event.keyCode==13) mapView.getDirectionAddress(jQuery(\'#saddr_' + marker.id + '\').val(), false);" id="saddr_' + marker.id + '" name="saddr" type="text" style="width: 13.45em" />';
        code += '<input type="button" value="' + this.translations.go + '" onclick="mapView.getDirectionAddress(jQuery(\'#saddr_' + marker.id + '\').val(), false)" /><br/>';
        //code += '<a href="#" onclick="jQuery(\'#direction_saddr_'+marker.id+'\').hide(); jQuery(\'#direction_get_link_'+marker.id+'\').show();">'+this.translations.back+'</a>';
        code += '</div>';
        
        code += '<div id="direction_daddr_' + marker.id + '" style="display: none;">';
        code += this.translations.calculate_route + ': <a href="#" onclick="jQuery(\'#direction_daddr_' + marker.id + '\').hide(); jQuery(\'#direction_saddr_' + marker.id + '\').show();">' + this.translations.to_here + '</a> - <b>' + this.translations.from_here + '</b>';
        code += '<br/>' + this.translations.target_address + ': <br/><input onkeyup="if (event.keyCode==13) mapView.getDirectionAddress(jQuery(\'#daddr_' + marker.id + '\').val(), true);"  id="daddr_' + marker.id + '" name="daddr" type="text" style="width: 13.45em" />';
        code += '<input type="button" value="' + this.translations.go + '" onclick="mapView.getDirectionAddress(jQuery(\'#daddr_' + marker.id + '\').val(), true)" /><br/>';
        //code += '<a href="#" onclick="jQuery(\'#direction_daddr_'+marker.id+'\').hide(); jQuery(\'#direction_get_link_'+marker.id+'\').show();">'+this.translations.back+'</a>';
        code += '</div>';
        
        code += '<br/><br/><br/>';
        return code;
    },
    getClippingDistance: function(coordinates){
        var lat_distance = coordinates.lat_max - coordinates.lat_min;
        var lng_distance = coordinates.lng_max - coordinates.lng_min;
        var distance = Math.sqrt(lat_distance * lat_distance + lng_distance * lng_distance);
        return distance;
    },
    
    getMapCanvasSize: function(){
        return {
            width: jQuery("div#" + this.canvasId).css("width"),
            height: jQuery("div#" + this.canvasId).css("height")
        };
    },
    
    getZoomLevel: function(distance){
    
        //var mapCanvasSize=getMapCanvasSize();
        //var factor=parseInt(mapCanvasSize.width);
        //if (mapCanvasSize.width>mapCanvasSize.height) factor=parseInt(mapCanvasSize.height);
        var add = 0;
        var factor = 1;
        //if (distance < 0.005*factor)
        //  return 17+add;
        //if (distance < 0.007*factor)
        //  return 16+add;
        if (distance < 0.01 * factor) 
            return 15 + add;
        if (distance < 0.03 * factor) 
            return 14 + add;
        if (distance < 0.06 * factor) 
            return 13 + add;
        if (distance < 0.1 * factor) 
            return 12 + add;
        if (distance < 0.15 * factor) 
            return 11 + add;
        if (distance < 0.3 * factor) 
            return 10 + add;
        if (distance < 0.8 * factor) 
            return 9 + add;
        if (distance < 2 * factor) 
            return 8 + add;
        if (distance < 2.4 * factor) 
            return 7 + add;
        if (distance < 4.7 * factor) 
            return 6 + add;
        if (distance < 9 * factor) 
            return 5 + add;
        if (distance < 17 * factor) 
            return 4 + add;
        if (distance < 30 * factor) 
            return 3 + add;
        
        return 2 + add;
    },
    
    zoomIn: function(){
        map.zoomIn();
        contextmenu.style.visibility = "hidden";
    },
    
    zoomOut: function(){
        map.zoomOut();
        contextmenu.style.visibility = "hidden";
    },
    
    centreMapHere: function(){
        var point = this.map.fromContainerPixelToLatLng(clickedPixel)
        this.map.setCenter(point);
        contextmenu.style.visibility = "hidden";
    },
    
    centerMap: function(lat, lng){
        this.map.setCenter(new GLatLng(lat, lng));
    },
    
    getDirectionAddress: function(address, swap_direction){
        scope = this;
        this.geocoder.getLatLng(address, function(point){
        
            if (!point) {
                alert(scope.translations.address_not_found);
                return;
            }
            scope.directions.clear();
            if (swap_direction) {
                scope.directions.loadFromWaypoints(new Array(selected_marker_glatlng, point));
                google.maps.Event.addListener(scope.directions, 'addoverlay', function(){
                    scope.directions.getMarker(0).hide();
                    scope.directions.getMarker(1).show();
                });
            }
            else {
                scope.directions.loadFromWaypoints(new Array(point, selected_marker_glatlng));
                google.maps.Event.addListener(scope.directions, 'addoverlay', function(){
                    scope.directions.getMarker(0).show();
                    scope.directions.getMarker(1).hide();
                });
            }
            
            scope.highlightMarker.closeInfoWindow();
        });
    },
    
    getDirection: function(swap_direction){
    
        if (!this.selected_marker_glatlng) {
            alert('Bitte wählen Sie zuerst Objekt aus.');
            return;
        }
        
        selected_point = map.fromContainerPixelToLatLng(clickedPixel);
        this.directions.clear();
        
        if (swap_direction) {
            this.directions.loadFromWaypoints(new Array(selected_marker_glatlng, selected_point));
            google.maps.Event.addListener(this.directions, 'addoverlay', function(){
                this.directions.getMarker(0).hide();
                this.directions.getMarker(1).show();
            });
        }
        else {
            this.directions.loadFromWaypoints(new Array(selected_point, selected_marker_glatlng));
            google.maps.Event.addListener(this.directions, 'addoverlay', function(){
                this.directions.getMarker(0).show();
                this.directions.getMarker(1).hide();
            });
        }
        
        contextmenu.style.visibility = "hidden";
    },
    
    highlight_context: function(obj){
        var entrydivs = jQuery("div#contextmenu").find('div');
        entrydivs.removeClass('item_highlight');
        jQuery(obj).addClass('item_highlight');
    },
    
    createContextMenu: function(map){
        return;
        contextmenu = document.createElement("div");
        contextmenu.id = 'contextmenu';
        contextmenu.style.visibility = "hidden";
        contextmenu.style.background = "#ffffff";
        contextmenu.style.border = "1px solid #8888FF";
        mapscope = this;
        contextmenu.innerHTML = '<!--<div class="item" onmouseover="mapscope.highlight_context(this)" onclick="mapscope.getDirection(false)"> Route von hier </div>' +
        '<div class="item" onmouseover="mapscope.highlight_context(this)" onclick="mapscope.getDirection(true)"> Route hierher </div>-->' +
        '<div class="item" onmouseover="mapscope.highlight_context(this)" onclick="mapscope.zoomOut()"> Verkleinern  </div></a>' +
        '<div class="item" onmouseover="mapscope.highlight_context(this)" onclick="mapscope.zoomIn()"> Vergrößern </div></a>' +
        '<div class="item" onmouseover="mapscope.highlight_context(this)" onclick="mapscope.centreMapHere()"> Karter hier zentrieren  </div></a>';
        
        map.getContainer().appendChild(contextmenu);
        GEvent.addListener(map, "singlerightclick", function(pixel, tile){
            clickedPixel = pixel;
            var x = pixel.x;
            var y = pixel.y;
            if (x > map.getSize().width - 120) {
                x = map.getSize().width - 120
            }
            if (y > map.getSize().height - 100) {
                y = map.getSize().height - 100
            }
            
            var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(x, y));
            pos.apply(contextmenu);
            contextmenu.style.visibility = "visible";
        });
        GEvent.addListener(map, "click", function(){
            contextmenu.style.visibility = "hidden";
        });
    },
    
    zoomIn: function(){
        this.map.zoomIn();
        contextmenu.style.visibility = "hidden";
    },
    
    zoomOut: function(){
        this.map.zoomOut();
        contextmenu.style.visibility = "hidden";
    },
    
    initGMap: function(){
    
        if (!GBrowserIsCompatible()) {
            return;
        }
        
        // default
        var lat = this.defaultLat;
        var lng = this.defaultLng;
        var zoom = this.defaultZoom;
        
        if (this.data && this.data.length != 0) {
            // list of coordinates of all items
            var coordinates = this.getCoordinates(this.data);
            
            
            if (!this.center) {
                // calc center of all items	
                this.center = {
                    lat: coordinates.lat_center,
                    lng: coordinates.lng_center
                };
            }
            
            if (!this.zoom) {
                // calc zoom
                var clippingDistance = this.getClippingDistance(coordinates);
                this.zoom = this.getZoomLevel(clippingDistance);
            }
            lat = this.center.lat;
            lng = this.center.lng;
            zoom = this.zoom;
        }
        
        
        var canvas = document.getElementById(this.canvasId);
        
        
        this.map = new google.maps.Map2(canvas);
        
        this.map.setCenter(new GLatLng(lat, lng), zoom);
        
        this.map.addControl(new GLargeMapControl());
        
        
        
        var scope = this;
        if (this.listeners.map_mouseover) {
            google.maps.Event.addListener(this.map, "mouseover", function(){
                scope.listeners.map_mouseover();
            });
        }
        
        if (this.listeners.map_mouseout) {
            google.maps.Event.addListener(this.map, "mouseout", function(){
                scope.listeners.map_mouseout();
            });
        }
        
        if (this.listeners.map_mousemove) {
            google.maps.Event.addListener(this.map, "mousemove", function(){
                scope.listeners.map_mousemove();
            });
        }
        
        if (this.listeners.map_drag) {
            google.maps.Event.addListener(this.map, "drag", function(){
                scope.listeners.map_drag();
            });
        }
        
        
        if (this.mapTypeControl == "MENU") 
            this.map.addControl(new GMenuMapTypeControl());
        else 
            if (this.mapTypeControl == "NORMAL") 
                this.map.addControl(new GMapTypeControl());
        
        
        // custom controls
        for (var i = 0; i < this.customControls.length; i++) {
            this.map.addControl(this.customControls[i]);
        }
        
        this.map.enableScrollWheelZoom();
        
        if (!this.data || this.data.length == 0) 
            return;
        
        
        this.geocoder = new GClientGeocoder();
        this.directions = new GDirections(this.map);
        
        var markers = this.createMarkers(this.data);
        this.addMarkers(markers);
        //for (var i=0; i<markers.length; i++) this.markers.push(markers[i]);
        
        if (this.cluster) 
            var markerClusterer = new MarkerClusterer(this.map, markers);
        else {
            for (var i = 0; i < markers.length; i++) 
                this.map.addOverlay(markers[i]);
        }
        this.createContextMenu(this.map);
        
        if (this.overlays) {
            var circles = [];
            for (var i = 0; i < this.overlays.length; i++) {
                if (this.overlays[i].type = "circle") 
                    circles.push(this.overlays[i]);
            }
            
            if (circles.length > 0) 
                this.initCircles(this.map, circles);
        }
    },
    
    getDestLatLng: function(latLng, bearing, distance){
        var EARTH_RADIUS = 6378.137;
        var lat1 = latLng.latRadians();
        var lng1 = latLng.lngRadians();
        var brng = bearing * Math.PI / 180;
        var dDivR = distance / EARTH_RADIUS;
        var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dDivR) + Math.cos(lat1) * Math.sin(dDivR) * Math.cos(brng));
        var lng2 = lng1 + Math.atan2(Math.sin(brng) * Math.sin(dDivR) * Math.cos(lat1), Math.cos(dDivR) - Math.sin(lat1) * Math.sin(lat2));
        return new GLatLng(lat2 / Math.PI * 180, lng2 / Math.PI * 180);
    },
    
    getBoundaries: function(centrePt, radius){
        var hypotenuse = Math.sqrt(2 * radius * radius);
        var sw = getDestLatLng(centrePt, 225, hypotenuse);
        var ne = getDestLatLng(centrePt, 45, hypotenuse);
        return new GLatLngBounds(sw, ne);
    },
    
    drawCircle: function(map, centrePt, rangeValue){
        var boundaries = getBoundaries(centrePt, rangeValue);
        //var circle = new GGroundOverlay("geo/marker/circle"+rangeValue+".png", boundaries);
        var img = "geo/marker/circle" + rangeValue * 1000 + ".png";
        //console.log(img);
        var circle = EInsert.groundOverlay(img, boundaries, -1);
        map.addOverlay(circle);
    },
    
    initCircles: function(map, circles){
        for (var i = 0; i < circles.length; i++) {
            var latLng = new GLatLng(circles[i].lat, circles[i].lng);
            var distance = 25;
            
            if (circles[i].distance <= 0.5) 
                distance = 0.5;
            else 
                if (circles[i].distance <= 1) 
                    distance = 1;
                else 
                    if (circles[i].distance <= 2) 
                        distance = 2;
                    else 
                        if (circles[i].distance <= 10) 
                            distance = 10;
                        else 
                            if (circles[i].distance <= 25) 
                                distance = 25;
            
            drawCircle(map, latLng, distance);
        }
    },
    showItems: function(ids){
        if (!ids) 
            return;
        for (var u = 0; u < this.markers.length; u++) {
            var marker = this.getMarker
            for (var i = 0; i < ids.length; i++) {
                if (this.markers[u].id == ids[i]) 
                    this.markers[u].show();
            }
        }
    },
    hideItems: function(ids){
        if (!ids) 
            return;
        for (var i = 0; i < ids.length; i++) {
            var marker = this.getMarker(ids[i]);
            if (marker) 
                marker.hide();
            if (this.highlightMarker && this.highlightMarker.id == ids[i]) 
                this.highlightMarker.hide();
        }
    },
    removeItems: function(items){
        var existingMarkers = [];
        for (var i = 0; i < items.length; i++) {
            var marker = this.getMarker(items[i].id);
            if (marker) 
                existingMarkers.push(marker);
        }
        this.removeMarkers(existingMarkers);
    },
    addItems: function(items){
        var markers = this.createMarkers(items);
        this.addMarkers(markers);
    },
    addMarkers: function(markers){
        var existingMarkers = [];
        for (var i = 0; i < markers.length; i++) {
            var marker = this.getMarker(markers[i].id);
            if (marker) 
                existingMarkers.push(marker);
        }
        this.removeMarkers(existingMarkers);
        for (var i = 0; i < markers.length; i++) {
            this.markers.push(markers[i]);
            if (this.map) 
                this.map.addOverlay(markers[i]);
        }
        this.mapMarkers();
    },
    removeMarkers: function(markers){
        if (!this.markers || !this.markers.length) 
            return;
        for (var i = markers.length - 1; i >= 0; i--) {
            for (var u = this.markers.length - 1; u >= 0; u--) {
                if (this.markers[u].id == markers[i].id) {
                    if (this.map) 
                        this.map.removeOverlay(this.markers[u]);
                    this.markers.splice(u, 1);
                }
            }
        }
        this.mapMarkers();
    }
}

