var map;
var icons = [];
var clusterer;
var markers = [];
var markersLoaded = [];
var client;
var marker;
var lastMarkerLocation;
var pano;

function initialize()
{
    // Streetview action setup
    StreetviewControl.prototype.createStreetviewClient = createStreetviewClient;
    StreetviewControl.prototype.onShowStreetview = onShowStreetview;
    StreetviewControl.prototype.onHideStreetview = onHideStreetview;
    
    // Map initialization
    map = new GMap2(document.getElementById("htmap"));
    map.addControl(new GLargeMapControl());
    map.addControl(new GScaleControl());
    
    var bounds = getInitialBounds();
    var zoomLevel = map.getBoundsZoomLevel(bounds);
    map.setCenter(bounds.getCenter(), zoomLevel);
    
    // Streetview initialization
    initializeStreetview();
    
    // Add neighborhoods
    var labelManager = new MarkerManager(map);

    var jsonNeighborhoods = getNeighborhoods();
    for (var i = 0; i < jsonNeighborhoods["neighborhoods"].length; i++)
    {
        var n = jsonNeighborhoods["neighborhoods"][i];
        map.addOverlay(new GPolygon.fromEncoded(n["geometry"]));
        if (n["point"] != null)
            labelManager.addMarker(new ELabel(n["point"], n["link"], "label_neighborhood"), 12);
    }
    if (jsonNeighborhoods["point"] != null)
        labelManager.addMarker(new ELabel(jsonNeighborhoods["point"], jsonNeighborhoods["link"], "label_neighborhood"), 10, 11);

    var jsonSurroundings = getSurroundingNeighborhoods();
    for (var i = 0; i < jsonSurroundings["neighborhoods"].length; i++)
    {
        var n = jsonSurroundings["neighborhoods"][i];
        labelManager.addMarker(new ELabel(n["point"], n["name"], "label_adjacent"), 12);
    }
    for (var i = 0; i < jsonSurroundings["areas"].length; i++)
    {
        var ca = jsonSurroundings["areas"][i];
        labelManager.addMarker(new ELabel(ca["point"], ca["name"], "label_adjacent"), 10, 11);
    }
    
    // Prepare to add amenities
    initializeIcons();
    
    clusterer = new Clusterer(map);
    clusterer.SetMaxVisibleMarkers(50);
    clusterer.SetMaxLinesPerInfoBox(5);
    clusterer.SetIcon(icons["_position"]);
    
    enableCheckboxes();
}

function initializeIcons()
{
    var kmlIconBase = new GIcon();
    kmlIconBase.iconSize = new GSize(20,20);
    kmlIconBase.iconAnchor = new GPoint(10,10);
    kmlIconBase.infoWindowAnchor = new GPoint(10,10);
    kmlIconBase.infoShadowAnchor = new GPoint(10,10);
    kmlIconBase.shadow = "images/shadow.png";
    kmlIconBase.printShadow = "images/shadow.gif";
    kmlIconBase.shadowSize = new GSize(22,22);

    initializeIcon(kmlIconBase, "coffee", "images/coffeeshop.png", "images/coffeeshop.gif");
    initializeIcon(kmlIconBase, "daycare", "images/childcare.png", "images/childcare.gif");
    initializeIcon(kmlIconBase, "fire", "images/firestation.png", "images/firestation.gif");
    initializeIcon(kmlIconBase, "grocery", "images/grocerystore.png", "images/grocerystore.gif");
    initializeIcon(kmlIconBase, "gym", "images/healthclub.png", "images/healthclub.gif");
    initializeIcon(kmlIconBase, "hospital", "images/hospital.png", "images/hospital.gif");
    initializeIcon(kmlIconBase, "library", "images/library.png", "images/library.gif");
    initializeIcon(kmlIconBase, "movie", "images/movietheater.png", "images/movietheater.gif");
    initializeIcon(kmlIconBase, "park", "images/dogpark.png", "images/dogpark.gif");
    initializeIcon(kmlIconBase, "school", "images/school.png", "images/school.gif");
    initializeIcon(kmlIconBase, "restaurant", "images/restaurant.png", "images/restaurant.gif");
    initializeIcon(kmlIconBase, "bar", "images/bar.png", "images/bar.gif");
    initializeIcon(kmlIconBase, "usps", "images/postoffice.png", "images/postoffice.gif");

    initializeIcon(kmlIconBase, "_position", "images/location.png", "images/location.gif");
}

function initializeIcon(base, name, image, printImage)
{
    var newIcon = new GIcon(base);
    newIcon.image = image;       
    newIcon.printImage = printImage;
    newIcon.mozPrintImage = printImage;     
    icons[name] = newIcon;
}

function zoomAndCenter(bounds)
{
    var zoomLevel = map.getBoundsZoomLevel(bounds);
    map.setCenter(bounds.getCenter(), zoomLevel);
}

function initializeStreetview()
{
    map.addControl(new StreetviewControl());
    
    var guyIcon = new GIcon(G_DEFAULT_ICON);
    guyIcon.image = "http://maps.google.com/intl/en_us/mapfiles/cb/man_arrow-0.png";
    guyIcon.transparent = "http://maps.google.com/intl/en_us/mapfiles/cb/man-pick.png";
    guyIcon.imageMap = [
        26,13, 30,14, 32,28, 27,28, 28,36, 18,35, 18,27, 16,26,
        16,20, 16,14, 19,13, 22,8
    ];
    guyIcon.iconSize = new GSize(49, 52);
    guyIcon.iconAnchor = new GPoint(25, 35);  // near base of guy's feet
    guyIcon.infoWindowAnchor = new GPoint(25, 5);  // top of guy's head
    
    marker = new GMarker(map.getCenter(), { icon: guyIcon, draggable: true });
	lastMarkerLocation = map.getCenter();
	
	GEvent.addListener(marker, "dragend", onDragEnd);
	GEvent.addListener(marker, "click", openPanoramaBubble);
}

function createStreetviewClient()
{
    client = new GStreetviewClient();
    return client;
}

function onShowStreetview()
{
    map.addOverlay(marker);
}

function onHideStreetview()
{
    map.removeOverlay(marker);
}

function onDragEnd()
{
    var location = marker.getLatLng();
    if (pano)
    {
        client.getNearestPanorama(location, onResponse);
    }
}

function onResponse(response)
{
    if (response.code != 200)
    {
        marker.setLatLng(lastMarkerLocation);
    }
    else
    {
        var latlng = new GLatLng(response.Location.lat, response.Location.lng);
        marker.setLatLng(latlng);
        lastMarkerLocation = latlng;
        openPanoramaBubble();
    }
}

function openPanoramaBubble()
{
    var contentNode = document.createElement('div');
    contentNode.style.textAlign = 'center';
    contentNode.style.width = '650px';
    contentNode.style.height = '250px';
    contentNode.innerHTML = 'Loading panorama';
    marker.openInfoWindow("<div id='pano' style='width:500px;height:250px;'></div>");

    pano = new GStreetviewPanorama(document.getElementById("pano"));
    pano.setLocationAndPOV(marker.getLatLng(), null);
    GEvent.addListener(pano, "initialized", onInitialized);
    GEvent.addListener(pano, "yawchanged", onYawChange);
}

function onYawChange(newYaw)
{
    var GUY_NUM_ICONS = 16;
    var GUY_ANGULAR_RES = 360/GUY_NUM_ICONS;
    if (newYaw < 0)
    {
        newYaw += 360;
    }

    var guyImageNum = Math.round(newYaw/GUY_ANGULAR_RES) % GUY_NUM_ICONS;
    var guyImageUrl = "http://maps.google.com/intl/en_us/mapfiles/cb/man_arrow-" + guyImageNum + ".png";
    marker.setImage(guyImageUrl);
}

function onInitialized(location)
{
    if (location)
    {
        marker.setLatLng(location.latlng);
    }
}

function onClick(checkbox, category)
{
    onAmenityLoad = function(response, httpCode)
    {
        try
        {    
            var json = eval("("+response+")");
            var category = json["category"];
            
            for (var i = 0; i < json["amenities"].length; i++)
            {
                var a = json["amenities"][i];
                var marker = new GMarker(new GLatLng(a["y"],a["x"]), {icon:icons[category]});
                marker.bindInfoWindowHtml(a["infoHtml"]);
                
                marker.amenityCategory = category;
                marker.clusterInfoEntry = a["name"];
                markers.push(marker);
                clusterer.AddMarker(marker, a["name"]);
            }
            markersLoaded[category] = true;
        }
        catch (err)
        {
            markersLoaded[category] = false;
        }
        
        enableCheckboxes();
    }
    
    disableCheckboxes();
        
    if (checkbox.checked)
    {
        if (markersLoaded[category] == null)
        {
            var url = getCallID()+"-"+category+".json";
            try 
            {
                GDownloadUrl(url, onAmenityLoad); 
            }
            catch (err) 
            {
                markersLoaded[category] = false;
                enableCheckboxes();
            }
        }
        else
        {
            for (var i = 0; i < markers.length; i++)
            {
                if (markers[i].amenityCategory == category)
                    clusterer.AddMarker(markers[i], markers[i].clusterInfoEntry);
            }
            enableCheckboxes();
        }
    }
    else
    {
        for (var i = 0; i < markers.length; i++)
        {
            if (markers[i].amenityCategory == category)
                clusterer.RemoveMarker(markers[i]);
        }
        enableCheckboxes();
    }
}

