﻿//
// ********************************************************
//
// basic map drawing functionality
//
// ********************************************************
//


var startLat;
var startLon;

//layers - we can turn these off and off as we need
routelayer = new VEShapeLayer();
poilayer = new VEShapeLayer();

var layerstoload = 0;


//keeps ajax happy if loaded via script manager
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

addLoadEvent(MapLoad);

function addLoadEvent(func) {
    var oldonload = window.onload;
    if (typeof window.onload != 'function')
    { window.onload = func; }
    else {
        window.onload = function()
        { oldonload(); func(); }
    }
}

//page has loaded so we can talk to the map
function MapLoad() {

    //make the toggle control visible
    $get("toggleLayers").style.display = "inline";
    
    
    // If the browser is Firefox get the version number
    var ffv = 0;
    var ffn = "Firefox/"
    var ffp = navigator.userAgent.indexOf(ffn);
    if (ffp != -1) ffv = parseFloat(navigator.userAgent.substring(ffp + ffn.length));
    // If we're using Firefox 1.5 or above override the Virtual Earth drawing functions to use SVG
    if (ffv >= 1.5) {
        Msn.Drawing.Graphic.CreateGraphic = function(f, b) { return new Msn.Drawing.SVGGraphic(f, b) }
    }

    map = new VEMap('myMap');

    //eval the dashboard size to make it into the structure
    if (legend != "")
        map.SetDashboardSize(eval(legend));

    //callback when it loads - if we don't do this we script stuff before the map loads    
    map.LoadMap(new VELatLong(startlat, startlon), 5, VEMapStyle.Shaded, false);

    //units
    if (units == 'metric')
        map.SetScaleBarDistanceUnit(VEDistanceUnit.Kilometers);

    map.onLoadMap = OnMapLoad();
}

//map has loaded - so we can play with it
function OnMapLoad() {

    ////points - we only bind onload as these don't change
    var request = new JsonRequest("pointdata", "/webservice/pointdata.ashx?lngrouteid=" + routeid);
    //add the callback
    request.doRequest("OnGetPointsRequestComplete");
    
    //add points of interest
    //rtn = ShareMyRoutes.webservice.mapData.GetPOI(routeid, OnGetPOIRequestComplete, OnTimeout, OnError);

    map.AttachEvent("onstartzoom", _HidePopup);
    map.AttachEvent("onstartpan", _HidePopup);

    map.AttachEvent("onchangemapstyle", StyleChangeHandler);


    //only if we force resize
    if (fullscreen == true) {
        //resize it when we load
        MapResize();
        //cant add handler via ajax so do it this way
        //$addHandler($get("widebody"), "resize", MapResize);
        document.body.onResize = MapResize;
    }

}

//deals with the 3d shading for road maps
function StyleChangeHandler(e) {
    if (map.GetMapStyle() == VEMapStyle.Road) {
        map.SetMapStyle(VEMapStyle.Shaded);
    }
}



//replace with more friendly message in time
function OnError(result) {

    //trap empty error
    if (result == undefined) {
        alert("Error.\n\n");
        return false;
    }

    if (gTestMode == true)
        alert("Error.\n\n" + result.get_message() + "\n" + result.get_stackTrace());
    else
        alert("Sorry, but something has gone wrong.\nIf you continue to experience problems please get in touch.");
}


function OnTimeout(result) {

    alert("Error or timed out: " + result._message);
}




function OnGetPointsRequestComplete(myCompactRoutePoints) {
    //bomb out if nothing comes back - this happens sometimes
    if (myCompactRoutePoints == undefined) {
        debugalert("result == undefined");

        return false;
    }

    //tell them the list is empty
    if (myCompactRoutePoints.length == 0) {
        debugalert("empty")
        return false;
    }

    //get the first point
    start = myCompactRoutePoints.start.split(",");

    startLat = parseFloat(start[0]);
    startLon = parseFloat(start[1]);
    var startAlt = parseInt(start[2]);

    points = new Array();   //store the points in

    //add the first point
    if (isFlight == true)
        myPoint = new VELatLong(startLat, startLon, startAlt);
    else
        myPoint = new VELatLong(startLat, startLon);
      
    points.push(myPoint);

    //now loop the rest adding points as we go
    rawpoints = myCompactRoutePoints.points.split(";");

    //initalise the values
    var lastLat = startLat;
    var lastLon = startLon;
    var lastAlt = startAlt;

    //loop around them
    for (i = 0; i < rawpoints.length-1; i++) {

        //parse the string
        point = rawpoints[i].split(",");

        //only add if there's some points to add
        if (point.length > 3) {
        
            var currentLatDelta = parseFloat(point[0]);
            var currentLonDelta = parseFloat(point[1]);
            var currentAltDelta = parseInt(point[2]);

            //add the point
            if (isFlight == true)
                var myPoint = new VELatLong(trimPosition(lastLat + (currentLatDelta / multiplier)), trimPosition(lastLon + (currentLonDelta / multiplier)), lastAlt + currentAltDelta);
            else
                var myPoint = new VELatLong(trimPosition(lastLat + (currentLatDelta / multiplier)), trimPosition(lastLon + (currentLonDelta / multiplier)));
            
            points.push(myPoint);

            //grab the last one
            lastLat = lastLat + (currentLatDelta / multiplier);
            lastLon = lastLon + (currentLonDelta / multiplier);
            lastAlt = lastAlt + currentAltDelta;

        }
        
    }

    //draw the pretty poly
    poly = new VEShape(VEShapeType.Polyline, points)
    if (isFlight == true)
        poly.SetAltitudeMode(VEAltitudeMode.Absolute);
    
    poly.SetLineWidth(6);
    poly.SetLineColor(new VEColor(255, 153, 0, 0.57));
    //poly.SetZIndex(8); 
    
    poly.HideIcon()

    //add to a layer
    routelayer.AddShape(poly);
    map.AddShapeLayer(routelayer);
    
    map.SetMapStyle(VEMapStyle.Hybrid);
    map.SetMapView(points);

    BindLayers();
    
    map.AttachEvent("onstartcontinuouspan", _HidePopup);
    map.AttachEvent("onstartzoom", _HidePopup);

}

//bind all additional layers
function BindLayers() {


    //count of layers left to load
    layerstoload = 0;
    Sys.UI.DomElement.toggleCssClass($get("layersControl"), "layersControlLoading");
 
    //delete existing shapes
    //poilayer.DeleteAllShapes();
    map.DeleteShapeLayer(poilayer);
    poilayer = new VEShapeLayer();

    if ($get("chkPOI").checked == true) {
        //start of route
        AddPin(startLat, startLon, "Start of " + routetitle, routestart, 0, "start16x16.png", 0);
        //get the POI
        rtn = ShareMyRoutes.webservice.mapData.GetPOI(routeid, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }
    
    //build the bounding box
    var myCoords = new ShareMyRoutes.webservice.Coords();
    myCoords = GetMapBounds("myMap");

    //AddPin(myCoords.bottomRightLat, myCoords.bottomRightLon, "bottom right", "x16x16.png", "", "", "", "", "");
    //AddPin(myCoords.topLeftLat, myCoords.topLeftLon, "top left", "x16x16.png", "", "", "", "", "");

    //build the other params
    var myRouteQueryParameters = new ShareMyRoutes.webservice.RouteQueryParameters();

    myRouteQueryParameters.Coords = myCoords;

    if ($get("ckhNearbyRoutes").checked == true) {
        //nearby routes
        myRouteQueryParameters.routeID = routeid;
        rtn = ShareMyRoutes.webservice.mapData.GetRoutesAsPOIinBox(myRouteQueryParameters, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }
    
    if ($get("chkBoxWiki").checked == true) {
        //now we have the map view set - get wiki entries
        rtn = ShareMyRoutes.webservice.mapData.GetWikiEntriesInBox(myRouteQueryParameters, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }

    if ($get("chkFlickr").checked == true) {
        //flickr
        rtn = ShareMyRoutes.webservice.mapData.GetFlickrEntriesInBox(myRouteQueryParameters, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }


    if ($get("chkPano").checked == true) {
        //pano
        rtn = ShareMyRoutes.webservice.mapData.GetPanoramioEntriesInBox(myRouteQueryParameters, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }


    if ($get("chkSummits").checked == true) {
        //additional POI
        myRouteQueryParameters.POItypeID = 2;
        rtn = ShareMyRoutes.webservice.mapData.GetAdditionalPOIinBox(myRouteQueryParameters, OnGetPOIRequestComplete, OnTimeout, OnError);
        layerstoload++;
    }
  
    map.AddShapeLayer(poilayer);
    
}

//turn on and off the control to show layers
function ToggleLayersControl() {

    if ($get("layersControl").style.display == "none") {
        $get("layersControl").style.display = "block";

        //move out of the way if 3d
        if( map.GetMapMode() == VEMapMode.Mode3D)
            $get("layersControl").style.top = '-140px';
        else
            $get("layersControl").style.top = '0px';
    }
    else
    {
        $get("layersControl").style.display = "none"
    }
    
}

function OnGetPOIRequestComplete(result) {

    //bomb out if nothing comes back - this happens sometimes
    if (result == undefined) {
        return false;
    }

    for (i = 0; i < result.length; i++) {
        var objItem = result[i];
        AddPin(objItem.lat, objItem.lon, objItem.title, objItem.description, objItem.imageid, objItem.mapicon, objItem.id, objItem.thumbnailURL, objItem.fullsizeURL);
    }

    layerstoload--; //decrease the layers count

    if (layerstoload == 0)
        Sys.UI.DomElement.toggleCssClass($get("layersControl"), "layersControlLoading");

}

function AddPin(lat, lon, title, description, imageid, icon, id, thumbnailURL, fullsizeURL) {

    var html = "<div id='waypointpopup'>";

    //customise the html
    if (imageid != '') {

        var photoLink = "";
        if (id != 0)
            photoLink = "image.aspx?lngpoiid=" + id;

        var popupPhotoLink = "/common/showimage.ashx?lngimageid=" + imageid;

        var photoPopup = "javascript:ShowImage(\"" + popupPhotoLink + "\", \"" + unescape(title) + "\",\"" + photoLink + "\", \"" + stripHTML(description) + "\")";

        var thumbnaiilLink = "/common/showthumbnail.ashx?lngimageid=" + imageid

        html += "<div id='photo'><a href='" + photoPopup + "'><img alt='click for full size image' src='" + thumbnaiilLink + "' /></a></div>";
        html += "<div id='text'>" + unescape(description) + "</div>";

        //the link to the fullsize popup
        html += "<div class='btns'>";
        //html += "<a href='javascript:ShowImage(\"" + popupPhotoLink + "\", \"" + unescape(title) + "\",\"" + photoLink + "\", \"" + unescape(description) + "\")'>View Photo</a></div>";
        html += "<a href='" + photoPopup + "'>View Photo</a></div>";
     
    }
    else {

        if (thumbnailURL != '' && thumbnailURL != undefined ) {

            //build a flickr URL for big images
            var popupPhotoLink = thumbnailURL.replace("_s", "");

            //build a panoramio URL for big images
            popupPhotoLink = popupPhotoLink.replace("square/", "medium/");

            var photoPopup = "javascript:ShowImage(\"" + popupPhotoLink + "\", \"" + unescape(title) + "\",\"" + fullsizeURL + "\", \"\")";

            html += "<div id='photo'><a href='" + photoPopup + "'><img alt='click for bigger image' src='" + thumbnailURL + "' /></a></div>";
            html += "<div id='text'>" + unescape(description) + "</div>";

            //the link to the fullsize popup
            html += "<div class='btns'>";
            html += "<a href='" + photoPopup + "'>View Photo</a></div>";

 
            }
         else
            {
             html += "<div id='textwide'>" + unescape(description) + "</div>";
            }
        
    }

    //get the right icon or a sensible default
    if (icon != undefined && icon != '')
        icon = serverpath + "/icons/" + icon;
    else
        icon = serverpath + "/icons/x16x16.png";     //default for x marks the spot

    html += "</div>";

    //set using the new shape method
    var pin = new VEShape(VEShapeType.Pushpin,  new VELatLong(lat, lon) );
    
    pin.SetCustomIcon(icon);
    pin.SetDescription(html);
    pin.SetTitle("<span id='waypointpopuptitle'>" + unescape(title) + "</span>");

    //add to the POI layer
    poilayer.AddShape(pin);

    pinID++;
}


function AddSimplePin(lat, lon, title, description, icon) {
    var html = "<div id='popupbody'>";

    //customise the html

    var pin = new VEPushpin(pinID,
            new VELatLong(lat, lon),
            icon,
            title,
            html,
            'pinicon',
            'title',
            'textdescription'
            );

    poilayer.AddPushpin(pin);
    
    pinID++;
}


//hides the popup
function _HidePopup() {
    //hides the info popup
    map.HideInfoBox();
}


function debugalert(msg) {
    //alert("debugging message: " + msg);
}

function ShowImage(photoURL, title, morelink) 
{
    ShowImage(photoURL, title, morelink, null)
}

//when passed an imageid overlays the image over the map
function ShowImage(photoURL, title, morelink, description) {

    
    //hides the info popup
    map.HideInfoBox();

    if (photoURL == null)
        return false;

    //hide the map container if in 3d mode
    if (map.GetMapMode() == VEMapMode.Mode3D) {
        $get("myMap").style.display = "none";
    }

    if (description != '' || description != null) {
        $get("imgdescription").innerHTML = description;
        $get("imgdescription").style.display = "block";
    }
    else {
        $get("imgdescription").innerHTML = '';
        $get("imgdescription").style.display = "none";
    }
    
    
    $get("popupimage").style.display = "none";
    $get("loadingmessage").style.display = "block";

    //set the url
    $get("popupimage").src = photoURL;

    //display
    //position it centered etc
    var elementBounds = Sys.UI.DomElement.getBounds($get("popupimage"));
    var body = document.getElementsByTagName("body")[0];

    var bodyelementBounds = Sys.UI.DomElement.getBounds(body);

    //do the fade over the rest
    $get("cover").style.display = '';
    //size it as well
    $get("cover").style.width = "100%";

    $get("popupimagetitle").innerHTML = title;

    if (morelink != '' && fullscreen != true) {
        $get("hypMoreLink").style.display = '';
        $get("hypMoreLink").href = morelink;
    }
    else {
        $get("hypMoreLink").style.display = 'none';
    }


    $addHandler($get("popupimagediv"), "click", _HidePopupImage);
 
     //add handler to get img load and force sizing
    $addHandler($get("popupimage"), "load", SizePopup);

    $get("popupimagediv").style.display = 'block';
    $get("popupimagediv").style.background = 'white';

}

function _HidePopupImage() {
    $get("cover").style.display = 'none';
    $get("popupimagediv").style.display = 'none';

    //unhide the map container
    $get("myMap").style.display = "";

}

function SizePopup() {
    
    //position it centered etc
    var elementBounds = Sys.UI.DomElement.getBounds($get("popupimage"));
    var body = document.getElementsByTagName("body")[0];    //get the body
    //var body = $get("body");    //get the body
    var bodyelementBounds = Sys.UI.DomElement.getBounds(body);

    var contentXOffset = 0;
    var contentYOffset = 40;
    if (fullscreen == false) {
        //used to position for stuff which is in centre of page
        var contentelementBounds = Sys.UI.DomElement.getBounds($get("pagebody"));
        contentXOffset = contentelementBounds.x;
        contentYOffset = 240;
    }

    if (elementBounds.width > 0 && elementBounds.height > 0) {
        //position in centre - remember the offset between page edge and the content

        $get("popupimagediv").style.left = (((bodyelementBounds.width / 2) - (elementBounds.width / 2)) - contentXOffset) + "px";
        $get("popupimagediv").style.width = (elementBounds.width + 10) + "px";

        $get("popupimagediv").style.top = contentYOffset + "px";
    }
    else {
        //work around image firing event before loaded properly
        $get("popupimagediv").style.left = (((bodyelementBounds.width / 2) - (640 / 2)) - contentXOffset) + "px";

        $get("popupimagediv").style.top = contentYOffset + "px";

    }

    //make visible
    $get("popupimagediv").style.display = 'block';
    $get("popupimage").style.display = 'block';
    
    $get("loadingmessage").style.display = "none";
 
}

//from http://www.viavirtualearth.com/Wiki/fullscreen.ashx
//make map fill the screen 
function MapResize() //resize
{

    //figure out where the map starts
    var bodyelementBounds = Sys.UI.DomElement.getBounds($get("myMap"));
    var headerOffsetHeight = bodyelementBounds.y + 5;
    var headerOffsetWidth = 15;

    if (map != null) {
        if (typeof (window.innerWidth) == 'number') {
            //Non-IE
            map.Resize(window.innerWidth - headerOffsetWidth, window.innerHeight - headerOffsetHeight);
        }
        else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
            //IE 6+ in 'standards compliant mode'
            map.Resize(document.documentElement.clientWidth - headerOffsetWidth, document.documentElement.clientHeight - headerOffsetHeight);
        }
    }
}
//cuts off the least significant digits on a lat/lon to save some memory
function trimPosition(myNumber) {
    return Math.round(myNumber * 10000) / 10000
}
