﻿/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Stree/Map UI 


// Main SMUI object
var smui = null;

function initPage()
{
    smui = new SMUI();
    
    smui.m_detectBrowser();
    
    smui.m_mapPath = smui.e("verDiv").innerHTML;
    
    smui.e("controlWidth").value = smui.controlWidth;
    smui.e("controlHeight").value = smui.controlHeight;
    
    // Create location setting map
    smui.m_initMap();
}

function closePage()
{
    if (smui.m_panorama)
    {
        smui.m_panorama.remove();
    }
    GUnload();
}

function resizePage()
{
    if (smui.map)
    {
        smui.map.checkResize();
    }
    if (smui.m_panorama)
    {
        smui.m_panorama.checkResize();
    }
}



SMUI.prototype.m_detectBrowser = function()
{
    if (navigator.userAgent.indexOf("Firefox")!=-1)
    {
        this.m_browserType = 1;
    }
    else if (navigator.userAgent.indexOf("MSIE")!=-1)
    {
        this.m_browserType = 2;
    }
    else if (navigator.userAgent.indexOf("Safari")!=-1)
    {
        this.m_browserType = 3;
    }
    else if (navigator.userAgent.indexOf("Opera")!=-1)
    {
        this.m_browserType = 4;
    }
}




////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Street/Map Control User Interface (SMUI)
function SMUI()
{
    this.map = null;

    // map height in pixels - used only for iframe dimensions (not script)
    this.controlWidth = 640;
    this.controlHeight = 420;
    
    // default map settings
    this.x = -122.420156;
    this.y = 37.779172;
    this.zoom = 15;       

    this.mapType = 0;
    this.mapControlType = 1;
    this.scrollWheelOn = 1;
    
    // streetview settings
    this.bearing = 0;
    this.pitch = 0;
    this.magnify = 0;
    
    this.coordShow = 1;
    this.linkShow = 1;
    
    this.intialView = 1;    // 0=Map 1=Fullscreen streetview
    
    // set up street view overlay and client
    this.m_streetOverlay = null;
    this.m_streetviewClient = null;
    this.m_panorama = null;
    
    this.m_browserType = 0;
    
    var m_previewShown = false;
    
    // kml layer
    this.msid = "";
    this.kmlName = "";    
}

SMUI.prototype.e = function(a)
{
    return document.getElementById(a); 
}

SMUI.prototype.m_formatFloat = function(pFloat, pDp)
{
    var m = Math.pow(10, pDp);
    return parseInt(pFloat * m, 10) / m;
}

SMUI.prototype.locKeyPress = function(p_event)
{
    var l_keyCode = p_event.keyCode;
    
    if (l_keyCode == 13)
    {
        gotoLocation();
        return false;
    }
    return true;
}   

SMUI.prototype.gotoLocation = function()
{
    var x = parseFloat(this.e("xLoc").value);
    var y = parseFloat(this.e("yLoc").value);
    var z = parseFloat(this.e("zLoc").value);
    
    // update google map
    this.map.setCenter(new GLatLng(y,x), z);
} 
 
SMUI.prototype.geoKeyPress = function(p_event)
{
    var l_keyCode = p_event.keyCode;
    
    if (l_keyCode == 13)
    {
        this.geocodeFind();
        return false;
    }
    return true;
}      
    
SMUI.prototype.geocodeFind = function()
{
    var l_address = this.e("geocodeName").value;
    
    // Geocode the address
    var l_geocoder = new GClientGeocoder(new GGeocodeCache()); 

    l_geocoder.getLatLng(l_address, function(p_point)
    { 
        var l_geoError = [];

        l_geoError[G_GEO_SUCCESS]            = "Success";
        l_geoError[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
        l_geoError[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
        l_geoError[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
        l_geoError[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
        l_geoError[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
        l_geoError[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
        
        if (p_point)
        {
            // Successful - move map to the point
            smui.map.setCenter(p_point);
            
            // check if valid streetview exists at this point
            initPanorama(p_point);
        }
        else
        {
            // Error - Display error text
            var l_result = l_geocoder.getCache().get(l_address);
            var l_reason = "";
            if (l_result)
            {
                var l_reason = "Error " + l_result.Status.code + " : ";
                if (l_geoError[l_result.Status.code])
                {
                    l_reason += l_geoError[l_result.Status.code];
                }
                alert(l_reason);
            }
            
        }
    });
}


// Create Street View Marker (Once only)
SMUI.prototype.m_createMarker = function()
{
    var l_latLong = new GLatLng(this.y, this.x);
 
    var icon = new GIcon();
    icon.image = "http://maps.google.com/intl/en_us/mapfiles/cb/man_arrow-0.png";
    icon.iconSize = new GSize(49,52);
    icon.iconAnchor =  new GPoint(25,36);
    icon.infoWindowAnchor = new GPoint(25,6);        
    
    var l_marker = new GMarker(l_latLong , {"icon":icon, "draggable":true});
    this.m_marker = l_marker;
    this.map.addOverlay(l_marker);
    
    GEvent.addListener(l_marker, "dragend", function()
       {            
            var l_point = l_marker.getPoint();
            initPanorama(l_point);           
       }
    );              
}
        
// change marker image according to current bearing
SMUI.prototype.m_updateMarker = function()
{
    // update marker image
    var l_imageNum = Math.round(this.bearing/22.5) % 16;
    var l_imageUrl = "http://maps.google.com/intl/en_us/mapfiles/cb/man_arrow-" + l_imageNum + ".png";                
    this.m_marker.setImage(l_imageUrl);
}

SMUI.prototype.m_initMap = function()
{
    var l_mapDiv = this.e("mapDiv");
    var l_latLong = new GLatLng(this.y, this.x);
    
    var map = new GMap2(l_mapDiv);
    
    this.map = map;
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.enableDoubleClickZoom();
    map.enableContinuousZoom();
    
    map.setCenter(l_latLong, this.zoom);    
    map.setMapType(G_NORMAL_MAP); 
    
    var adManager = new GAdsManager(map, "ca-pub-5408854154696215", {channel:"5533804922"});
    adManager.enable();

    // set up street view overlay and client
    this.m_streetOverlay = new GStreetviewOverlay();
    map.addOverlay(this.m_streetOverlay);

    GEvent.addListener(map, "click", function(overlay, point)
    {
        if (point)
        {
            smui.pitch = 0;
            smui.magnify = 0;
            initPanorama(point);
        }
    });

    // change displayed zoom as map zoom changes
    GEvent.addListener(map, "zoomend", function()
    {
        var z = map.getZoom();        
        smui.e("zMap").value = z;
    });
    
    this.m_streetviewClient = new GStreetviewClient();
    
    var panorama = new GStreetviewPanorama(this.e("panDiv"));    
    this.m_panorama = panorama; 
    this.m_panorama.hide();
    
    // listen for changes in bearing and latlng, then update marker accordingly
    GEvent.addListener(panorama,"yawchanged",function(a)
     {
        smui.bearing = parseFloat(a);
        smui.e("bearingText").value = smui.m_formatFloat(smui.bearing, 1);
        
        smui.m_updateMarker();
     });

    GEvent.addListener(panorama,"pitchchanged",function(a)
     {
        smui.pitch = parseFloat(a);
        smui.e("pitchText").value = smui.m_formatFloat(smui.pitch, 1);
     });

    GEvent.addListener(panorama,"zoomchanged",function(a)
     {
        smui.magnify = parseInt(a);
        smui.e("magnifyText").value = smui.magnify;
     });

    GEvent.addListener(panorama,"initialized",function(a)
     {
        var latlng = a.latlng;
        smui.m_marker.setPoint(latlng);
        
        smui.x = latlng.lng();
        smui.y = latlng.lat();

        smui.e("xMap").value = smui.x;
        smui.e("yMap").value = smui.y;
     }); 

    this.m_createMarker();
    
    initPanorama(l_latLong);
}

    // find nearest panorama
    function initPanorama(point)
    {        
        // change current point (note, if a nearby street view is found then the latlng will be updated to the latlng of the streetview)
        smui.m_streetviewClient.getNearestPanorama(point, initPanorama2);
    }

    // callback function for initPanorama() - change panorama view to specified latlong
    function initPanorama2(param)
    {
        var location;
        
        // validate new location
        var valid  = true;
        if (param == null)
        {
            valid = false;
        }
        else
        {
            location = param.location;

            if (location == null)
            {
                valid = false;
            }
        }
        
        if (valid)
        {
            smui.m_panorama.setLocationAndPOV(location.latlng, {"yaw":smui.bearing,"pitch":smui.pitch,"zoom":smui.magnify});
            smui.m_locationViewChanged(location.latlng, smui.map.getZoom());             
            smui.m_marker.setPoint(location.latlng);    // update marker
            
            if (!smui.m_previewShown )
            {
                smui.m_previewShown = true;
                smui.previewClick();
            }
        }
    }


/////////////////////////

SMUI.prototype.m_locationViewChanged = function(p_point, z)
{
    var x = p_point.lng();
    var y = p_point.lat();    
    
    smui.e("xMap").value = this.m_formatFloat(x, 7);
    smui.e("yMap").value = this.m_formatFloat(y, 7);
    smui.e("zMap").value = z;
}

SMUI.prototype.xyzView = function()
{
    var x = parseFloat(this.e("xMap").value);
    var y = parseFloat(this.e("yMap").value);
    var z = parseInt(this.e("zMap").value);
    
    if (isNaN(x))
    {
        alert("invalid x value : " + this.e("xMap").value);
    }
    else if (isNaN(y))
    {
        alert("invalid y value : " + this.e("yMap").value);
    }
    else if (isNaN(z))
    {
        alert("invalid z value : " + this.e("zMap").value);
    }
    else
    {    
        var l_point = new GLatLng(y,x);
        this.map.setCenter(l_point, z);
        
        this.m_locationViewChanged(l_point, z);
    }
}

// set up IFramed dual map
SMUI.prototype.previewClick = function()
{
    // First get map input properties and validate each
    this.x = parseFloat(this.e("xMap").value);
    this.y = parseFloat(this.e("yMap").value);
    this.zoom = parseInt(this.e("zMap").value); 
    this.mapType = this.e("mapType").selectedIndex;  
    this.mapControlType = this.e("mapControlSelect").selectedIndex;
    
    this.controlWidth = parseInt(this.e("controlWidth").value);  
    this.controlHeight = parseInt(this.e("controlHeight").value);  

    this.bearing = parseInt(this.e("bearingText").value);  
    this.pitch = parseInt(this.e("pitchText").value);  
    this.magnify = parseInt(this.e("magnifyText").value);  
    this.linkShow = this.e("linkShowSelect").selectedIndex;
    this.coordShow = this.e("coordShowSelect").selectedIndex;
    this.scrollWheelOn = this.e("scrollWheelSelect").selectedIndex;

    this.initialView = this.e("initialViewSelect").selectedIndex;

    // kml layer
    this.msid = this.e("MSIDText").value;
    this.kmlName = this.e("KMLNameText").value;    
    
    // validate x,y and zoom
    if (isNaN(this.x))
    {
        alert("Invalid x value : " + this.e("xMap").value);
        this.e("xMap").focus();
        return;
    }
    if (isNaN(this.y))
    {
        alert("Invalid y value : " + this.e("yMap").value);
        this.e("yMap").focus();
        return;
    }
    if (isNaN(this.zoom))
    {
        alert("Invalid zoom value : " + this.e("zMap").value);
        this.e("zMap").focus();
        return;
    }

    if (isNaN(this.controlWidth) || (this.controlWidth < 480))
    {
        alert("invalid width value : " + this.e("controlWidth").value);
        this.e("controlWidth").focus();
        return;
    }
    if (isNaN(this.controlHeight) || (this.controlHeight < 280))
    {
        alert("invalid height value : " + this.e("controlHeight").value);
        this.e("controlHeight").focus();
        return;
    }
    
    // base url
    var l_url = 
        this.m_mapPath + "?x=" + this.x + "&y=" + this.y + "&z=" + this.zoom  + 
        "&t=" + this.mapType + "&c=" + this.mapControlType +  "&s=" + this.scrollWheelOn +
        "&b=" + this.bearing + "&p=" + this.pitch + "&m=" + this.magnify +
        "&j=" + this.coordShow + "&k=" + this.linkShow +"&v=" + this.initialView;
        
    if (this.msid != "")
    {
        l_url += "&msid=" + this.msid;
        if (this.kmlName != "")
        {
            l_url += "&name=" + this.kmlName;
        }
    }
        
    // Generate html script now
    var l_scriptHtml = 
        "<iframe style=\"width:" + this.controlWidth + "px;height:" + this.controlHeight + "px;padding:0;border:solid 1px black\" " +
        "src=\"" + l_url + "\" " +
        "marginwidth=\"0\" marginheight=\"0\" frameborder=\"0\" scrolling=\"no\"></iframe>";

    this.e("scriptText").value = l_scriptHtml;

    // and preview
    this.e("previewDiv").innerHTML = l_scriptHtml;
}

