function HubMapOverlay(latLng,title,content,address,city,country,url)
{
    this.latLng = latLng;
    this.title = title;
    this.content = content;
    this.address = address;
    this.city = city;
    this.country = country;
    this.url = url;
    this.prototype = new GOverlay();

    this.map = null;

    this.overlayElement = null;
    this.contentElement = null;
    this.footerElement= null;
    this.anchor = null;
    this.closeElement = null;

    this.initialize = function(map){

        this.map = map;

        this.overlayElement = new Element("div");
        this.overlayElement.addClass("HubMapOverlay");

        this.closeButton = new Element("div");
        this.closeButton.addClass("close");
        this.closeButton.inject(this.overlayElement);
        this.closeButton.instance = this;
        this.closeButton.addEvent("click",function(){
            this.instance.remove();
        });

        var content = "<div class=\"font\"><img src=\"http://www.hubfootwear.com/fonts/Puschkin.php?text=" + (this.title) + "/\" /></div>";
        content += "<div class=\"font\"><img src=\"http://www.hubfootwear.com/fonts/Puschkin.php?text=" + (this.city) + "/\" /></div><br />";
        if( this.content.length > 0 )
        {
            content += this.content + "<br /><br />";
        }
        content += "address:<br />" + this.address + "<br />" + this.city;

        this.contentElement = new Element("div");
        this.contentElement.addClass("OverlayContent");
        this.contentElement.inject(this.overlayElement);
        this.contentElement.innerHTML = content;

        this.footerElement = new Element("div");
        this.footerElement.addClass("OverlayFooter");
        this.footerElement.inject(this.overlayElement);

        if( this.url.length > 0 )
        {
            this.anchor = new Element("a");
            this.anchor.setAttribute("href",this.url);
            this.anchor.setAttribute("target","blank");
            this.anchor.innerHTML = this.url.replace("http://","");
            this.anchor.addEvent("click",function(e){
                e = new Event(e);
                e.stop();
                window.open(this.getAttribute("href"),"hubextsite");
                return false;
            });
            this.anchor.inject(this.footerElement);
        }

        var shadowLeft = new Element("div");
        shadowLeft.addClass("shadowleft");
        shadowLeft.inject(this.overlayElement);

        if(( Browser.Engine.trident ) && ( Browser.Engine.version == 5 ))
        {
            shadowLeft.setStyle("width","185px");
        }

        var shadowRight = new Element("div");
        shadowRight.addClass("shadowright");
        shadowRight.inject(this.overlayElement);

        this.overlayElement.inject(map.getPane(G_MAP_FLOAT_PANE));
    }

    this.remove = function(){
        this.overlayElement.dispose();
    }

    this.copy = function(){
        return new HubMapOverlay(this.latLng,this.title,this.content,this.url);
    }

    this.redraw = function(force){
        if( !force )
        {
            return;
        }
        
        var point = this.map.fromLatLngToDivPixel(this.latLng);

        this.overlayElement.setStyle("left",point.x-18);
        this.overlayElement.setStyle("top",point.y-this.overlayElement.offsetHeight+10);
    }
}

function HubMap(destinationElement,jsonDataURL)
{
    this.destinationElement = destinationElement;
    this.jsonDataURL = jsonDataURL;

    this.map = null;
    this.geoCoder = null;
    this.markerManager = null;
    this.lastInfoWindowLatLng = null;
    this.infoWindow = null;
    
    this.onLoad = function(){

        var defaultZoom = 15;

        if( this.destinationElement.getAttribute("minimumMapResolution") != null )
        {
            G_PHYSICAL_MAP.hubMinimumResolution = this.destinationElement.getAttribute("minimumMapResolution");
            G_PHYSICAL_MAP.getMinimumResolution = function () { return this.hubMinimumResolution };

            G_NORMAL_MAP.hubMinimumResolution = this.destinationElement.getAttribute("minimumMapResolution");
            G_NORMAL_MAP.getMinimumResolution = function () { return this.hubMinimumResolution };

            G_SATELLITE_MAP.hubMinimumResolution = this.destinationElement.getAttribute("minimumMapResolution");
            G_SATELLITE_MAP.getMinimumResolution = function () { return this.hubMinimumResolution };

            G_HYBRID_MAP.hubMinimumResolution = this.destinationElement.getAttribute("minimumMapResolution");
            G_HYBRID_MAP.getMinimumResolution = function () { return this.hubMinimumResolution };

            defaultZoom = parseInt(this.destinationElement.getAttribute("minimumMapResolution"))+3;
        }

        this.map = new GMap2(destinationElement);

        this.geoCoder = new GClientGeocoder();
        this.map.hubMapInstance = this;
        var mapType = null;
        if( (mapType = this.destinationElement.getAttribute("mapType")) != null )
        {
            if( mapType == "satellite" )
            {
                this.map.setMapType(G_SATELLITE_MAP);
            }
            else if( mapType == "map" )
            {
                this.map.setMapType(G_NORMAL_MAP);
            }
        }
        this.map.setUIToDefault();

        this.map.setCenter(new GLatLng(0,0),defaultZoom);
        this.map.enableDoubleClickZoom();
        this.markerManager = new MarkerManager(this.map);
        this.markerManager.show();

        GEvent.addListener(this.map,"click",function(overlay,latLng,overlayLatLng){
            if(( overlay != null ) && ( overlay.hubId != null ))
            {
                //this.openInfoWindowHtml(overlayLatLng,"<div class=\"hubmaploading\">Loading " + overlay.getTitle() + "</div>");
                this.hubMapInstance.lastInfoWindowLatLng = overlayLatLng;
                this.hubMapInstance.loadInfoWindowData(overlay.hubId); 
            }
        });

        GEvent.addListener(this.map,"moveend",function(){
            this.hubMapInstance.loadMapData();
        });
        
        this.loadMapData(true);
    }

    this.loadMapData = function(initial){

        var mapBounds = this.map.getBounds();
        var mapBoundsNe = mapBounds.getNorthEast();
        var mapBoundsSw = mapBounds.getSouthWest();
        var mapBoundsZoomLevel = this.map.getBoundsZoomLevel(mapBounds);

        var arguments = new Object();
        arguments.method = "loadMapData";
        arguments.neLat = mapBoundsNe.lat();
        arguments.neLng = mapBoundsNe.lng();
        arguments.swLat = mapBoundsSw.lat();
        arguments.swLng = mapBoundsSw.lng();
        arguments.initial = initial;
        
        var request = new Request.JSON({
            url: this.jsonDataURL,
            onSuccess: function(json){
                this.instance.processMapData(json);
            }
        });
        request.instance = this;
        request.send("json=" + JSON.encode(arguments));
    }

    this.loadInfoWindowData = function(hubId){
        var arguments = new Object();
        arguments.method = "loadInfoWindowData";
        arguments.hubId = hubId;
        
        var request = new Request.JSON({
            url: this.jsonDataURL,
            onSuccess: function(json){
                this.instance.renderInfoWindow(json.hubTitle,json.hubContent,json.address,json.city,json.country,json.url);
            }
        });
        request.instance = this;
        request.send("json=" + JSON.encode(arguments));
    }

    this.renderInfoWindow = function(title,content,address,city,country,url){
        if( this.infoWindow != null )
        {
            this.infoWindow.remove();
        }
        this.infoWindow = new HubMapOverlay(this.lastInfoWindowLatLng,title,content,address,city,country,url);
        this.map.addOverlay(this.infoWindow);
        //this.map.openInfoWindowHtml(this.lastInfoWindowLatLng,infoWindowContent);
    }

    this.processMapData = function(response){
        this.markerManager.clearMarkers();
        this.markerManager.refresh();
        
        if( response.viewCenter != null )
        {
            this.map.setCenter(new GLatLng(response.viewCenter.lat,response.viewCenter.lng),response.viewCenter.zoom);
        }
        if( response.marker != null )
        {
            for( var i = 0; i < response.marker.length; i++ )
            {
                var icon = new GIcon();
                icon.image = response.marker[i].icon.url;
                icon.iconAnchor = new GPoint(response.marker[i].icon.anchorX,response.marker[i].icon.anchorY);

                var marker = new GMarker(
                    new GLatLng(
                        response.marker[i].lat,
                        response.marker[i].lng
                    ),
                    {
                        icon: icon,
                        title: response.marker[i].title
                    }
                );
                marker.hubId = response.marker[i].id;

                this.markerManager.addMarker(
                    marker,
                    response.marker[i].minVisibleZoomLevel,
                    response.marker[i].maxVisibleZoomLevel
                );
            }
        }
        this.markerManager.refresh();
    }

    this.navigateToAddress = function(address){
        this.geoCoder.getLatLng(address,this.navigateToAddressFound.bind(this));
    }

    this.navigateToAddressFound = function(latLng){
        if( latLng == null )
        {
            alert("The specified address could not be found.");
        }
        else
        {
            this.map.setCenter(latLng);
        }
    }
}