var map;
var mgr;
var highlight;
var bounds;

var mapElem;
var panelElem;

var areas;

var areaIcon = new GIcon();
areaIcon.image = "/maps/images/area.png";
areaIcon.shadow = "/maps/images/area-shadow.png";
areaIcon.iconSize = new GSize(32, 32);
areaIcon.shadowSize = new GSize(59, 32);
areaIcon.iconAnchor = new GPoint(16, 16);
areaIcon.infoWindowAnchor = new GPoint(13, 6);

var nhoodIcon = new GIcon();
nhoodIcon.image = "/maps/images/house.png";
nhoodIcon.shadow = "/maps/images/house-shadow.png";
nhoodIcon.iconSize = new GSize(32, 32);
nhoodIcon.shadowSize = new GSize(59, 32);
nhoodIcon.iconAnchor = new GPoint(16, 16);
nhoodIcon.infoWindowAnchor = new GPoint(13, 6);

var Base = Class.create();

Base.prototype = {
    
    getIcon: function() { return areaIcon; },
    
    mouse_over: function() {
        var z = map.getZoom();
        if (z>= this.minZoom && z <= this.maxZoom) {
            this.highlight();
        }
        this.getNameDiv().className = 'highlight';
    },
    
    mouse_out: function() {
        highlight.style.visibility = 'hidden';
        this.getNameDiv().className = '';
    },
    
    highlight: function() {
        marker = this.marker;
        var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
        var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
        var anchor=marker.getIcon().iconAnchor;
        var width=32;
        var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x - 16, offset.y - point.y -anchor.y - 16)); 

        pos.apply(highlight);
        highlight.style.visibility = 'visible';
    }
};

var Area = Class.create();
Object.extend(Object.extend(Area.prototype, Base.prototype), {
    initialize: function(info, mgr) {
        this.id = info.id;
        this.name = info.name;
        this.x = info.x;
        this.y = info.y;
        this.marker = new GMarker(new GLatLng(this.x, this.y), 
                                  {icon:this.getIcon(), title:this.name});
        
        GEvent.addListener(this.marker, "click", function() {
            this.mouse_click();}.bind(this));
        GEvent.addListener(this.marker, "mouseover", function() {
            this.mouse_over();}.bind(this));
        GEvent.addListener(this.marker, "mouseout", function() {
            this.mouse_out();}.bind(this));
            
        mgr.addMarker(this.marker, 1, 8);
        
        this.neighborhoods = $H();
        
        var xMin, xMax, yMin, yMax;
        
        for (var i=0; i<info.neighborhoods.length; i++) {
            var n = new Neighborhood(info.neighborhoods[i], this.id);
            mgr.addMarker(n.marker, 9);
            
            var p = n.marker.getPoint();
            xMin = (xMin && xMin < p.lat()) ? xMin : p.lat();
            xMax = (xMax && xMax > p.lat()) ? xMax : p.lat();
            yMin = (yMin && yMin < p.lng()) ? yMin : p.lng();
            yMax = (yMax && yMax > p.lng()) ? yMax : p.lng();
            
            this.neighborhoods[n.id] = n;
        }
        this.bounds = new GLatLngBounds(
            new GLatLng(xMin, yMin),
            new GLatLng(xMax, yMax));
            
        this.minZoom = 1;
        this.maxZoom = 8;
    },
    
    getNameDiv: function() {
        return $(this.id + "_name");
    },
    
    mouse_click: function() {
            zoomArea(this.id);
    }
});

var Neighborhood = Class.create();
Object.extend(Object.extend(Neighborhood.prototype, Area.prototype), {

    initialize: function(info, area_id) {
        this.id = info.id;
        this.area_id = area_id;
        this.name = info.name;
        this.url = info.url;
        this.desc = info.desc;
        this.x = info.x;
        this.y = info.y;
        this.marker = new GMarker(new GLatLng(this.x, this.y), 
                                  {icon:this.getIcon(), title:this.name});
        
        GEvent.addListener(this.marker, "click", function() {
            this.mouse_click();}.bind(this));
        GEvent.addListener(this.marker, "mouseover", function() {
            this.mouse_over();}.bind(this));
        GEvent.addListener(this.marker, "mouseout", function() {
            this.mouse_out();}.bind(this));
            
        this.minZoom = 9;
        this.maxZoom = 20;
        
    },
    
    getNameDiv: function() {
        return $(this.area_id + '_' + this.id + "_name");
    },
    
    getIcon: function() { return nhoodIcon; },
    
    mouse_click: function() {
        if (map.getZoom() >= this.minZoom) {
            var html = '<b>'+this.name+'</b>';
            if (this.desc) {
                html += '<div class="popup_div">' + this.desc + '</div>';
            }

            if (this.url) {
                if (!this.desc) { html += '<br />'; }
                html +=
                    '<a href="' + this.url + '" target="_blank">' +
                    'view</a>';
            }

            this.marker.openInfoWindowHtml(html, {maxWidth:250});
        } else {
            this._handle = GEvent.addListener(map, "zoomend", function() {
                this.zoom_end(); }.bind(this));
            zoomArea(this.area_id);
        }
    },
    
    zoom_end: function() {
        GEvent.removeListener(this._handle);
        //
        map.panTo(this.marker.getPoint());
        var cmd = "areas['" + this.area_id + "'].neighborhoods['" + this.id + "'].mouse_click();";
        setTimeout(cmd, 500);
    }
});

function zoomArea(id) {
    var area = areas[id];
    var z = area.neighborhoods.keys().length > 1 ?
        map.getBoundsZoomLevel(area.bounds) : 9;
    map.setZoom(z);
    var cmd = 'map.panTo(areas["'+id+'"].bounds.getCenter());';
    setTimeout(cmd, 500);
    
    var iw = map.getInfoWindow();
    if (!iw.isHidden())
        iw.hide();
}

    function load() {
        areas = $H();
        mapElem = $('map');
        panelElem = $('panel');
      if (GBrowserIsCompatible()) {
        resizeApp();
        
        bounds = new GLatLngBounds(
            new GLatLng(30.35628642525117, -85.60821533203125),
            new GLatLng(34.986128262717195, -80.81680297851562));
        
        map = new GMap2(document.getElementById("map"));
        
        map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
        map.addControl(new GSmallMapControl());
        map.addControl(new GMapTypeControl());
        
        mgr = new GMarkerManager(map);

        for (var a=0; a<info.length; a++) {
            var area = new Area(info[a], mgr);
            areas[area.id] = area;
        }

        mgr.refresh();

        highlight = document.createElement('div');
        map.getPane(G_MAP_MARKER_SHADOW_PANE).appendChild(highlight);
        highlight.style.visibility="hidden";
        png_browser();
        highlight.innerHTML=od_displayImage("glow", "/maps/images/glow", 60, 60, " ", " ")

      }
    }

function getWindowHeight() {
    if (window.self && self.innerHeight)
        {return self.innerHeight;}
    if (document.documentElement && document.documentElement.clientHeight) 
        {return document.documentElement.clientHeight;}
    return 0;
}

function resizeApp() {
    var offsetTop = 0;
    for (var elem = mapElem; elem != null; elem = elem.offsetParent) {
        offsetTop += elem.offsetTop;
    }
    
    var height = getWindowHeight() - offsetTop - 10;
    if (height > 0) {
        mapElem.style.height = height+'px';
        panelElem.style.height = height+'px';
    }
}

function getArea(name) {
    var parts = name.split('_');
    var elem = areas[parts[0]];
    if (parts[1]) {
        elem = elem.neighborhoods[parts[1]];
    }
    
    return elem;
}

function list_mouse_over(name) {
    getArea(name).mouse_over();
}

function list_mouse_out(name) {
    getArea(name).mouse_out();
}

function list_mouse_click(name) {
    var a = getArea(name);
    map.panTo(a.marker.getPoint());
    a.mouse_click();
}
