﻿/*........ Javascript used for Route planner.........*/

//Variables declaration
var mapviewer, route_finder, route, loading, startloc, endloc;
var smallMapViewer, small_route_finder, small_route;
var max_zindex = 1000,totalStepCount,stepClickedNumber;
var locations = new Array(),smallMarkers = new Array(),routeMarkers = new Array();
var routeMapPage,routeStepsPage, startLocation,endLocation, previousMapPosition;

//add pointer references for the most used functions
// in order to increase the performance
var getStepMarker = createStepMarker;
var getSmallStepMarker = createSmallStepMarker;

//On load method for route planner page
function RouteMapLoad() { 
    routeMapPage = document.getElementById("routemapwrapper");
    routeStepsPage = document.getElementById("listingContainer");
    if (!routeMapPage) { 
        return false;
    }
    
    //for property details page to disable next previous
    dragSearch=true;
    
    mapviewer = MMFactory.createViewer( document.getElementById( 'dvMapViewer' ) );
    previousMapPosition = getQueryStringValue("map");
    breadCrumContainer = document.getElementById("dvBreadCrum");
    mapResultDiv.className = "mapwrapper mapwrapper_border";
    addCustomTilesOverlay(); 
    addMapTypes();    
    addCommonEventHandlers();
    mapviewer.setOption ('mousewheel:wheelup', 'zoomin' );
    mapviewer.setOption ('mousewheel:wheeldown', 'zoomout' ); 
    var funcRef = resultsLoaded;
    route_finder = MMFactory.createRouteRequester( funcRef, mapviewer );
    loadingStatus( false );
    var queryString = window.location.search;
    if(queryString && queryString != "") {
        callRoute(); 
    }
}

function CheckFirstTimePageLoading() { 
  //check if location for search is empty
  if(!checkIsNullOrEmpty(getQStringValue("sloc")) || !checkIsNullOrEmpty(getQStringValue("eloc"))) { 
      //changes for the font style for error msg
      errorMsgDiv.className = "defaultmsgdetails";
      errorMsgDetails.className = "defaultmsg";
      errorImage.style.display = "none";
      showMap(false);  
      showErrorMessage("Plan your driving route by speed, scenery or distance or your walking route.", true);
      pageHeaderTitle.innerHTML  = "Get directions with MSN Local";
      return false;
  }
   return true;
}

//This method gets called once the results are loaded on map and small map starts 
//loading after this.
function mapLoaded(type,target ) { 
      mapviewer.removeEventHandler( 'tilesLoaded', mapLoaded );
      loadingStatus( true );
      if(checkIsNullOrEmpty(queryStringPoi)) {
         getAmenitiesOnMapDragged();
         SearchVEAmenitiesWithinMapbounds();
      }
      if(checkIsNullOrEmpty(queryStringLocalInfo)) {
         searchLocalInformationWithinMapBounds();             
      }
      if(checkIsNullOrEmpty(queryStringSchools)){
         getSchoolResultsOnMapDragged();
      }
      if(checkIsNullOrEmpty(queryStringOverlays)){    
          isMapChanged = true;   
          displayConstituencyOverlay(queryStringOverlays);
      }
      if (checkIsNullOrEmpty(queryStringBusinessCategory) ) {
           SearchBusinessResultsWithinMapbounds();
      }
      if (isPTrendsVisible == "1" ) {
            searchTrendsDataWithinMapBoundaries();
      }
      if(isPropertyVisible == "1")  {
           SearchPropertiesInBoundaries();
      }
      if(currentHeatMap != null){
            showHeatMapTypeMsg(currentHeatMap,true);
            displayPricesAndTrendsOverlays();
            showHideTrendHeatmapsLegend(currentHeatMap);
      }
      loadingStatus( false );
}
 
/* Method to create a marker at each route step location */
function createStepMarker(location, instruction, text, zindex) {
    var marker = mapviewer.createMarker(location, {zIndex: zindex, 'text' : text});
    marker.setInfoBoxContent('<p>' + instruction + '<' + '/p>');
    routeMarkers.push(marker);
} 

/*Method to intialize the route requester object*/
function callRoute () {
    cleanUp();
    addLocation(Start_Location,locations);
    if(Via_Location && Via_Location != "" && Via_Location != null) {
        addLocation(Via_Location,locations);
    }
    addLocation(End_Location,locations);
    route = new MMRoute( locations );
    if (Shortest == "true") {
        route.optimize_for = 'distance';
    }  else {
        route.optimize_for = 'time';
    } 

    if (Walking == "true") {
        route.mode = 'walking';
    }   else {
        route.mode = 'driving'; 
    } 
    route_finder.request(route);
}

/* Remove any existing route and directions, in preparation for displaying a new one */
function cleanUp() {
    var stepsContainer = routeStepsPage;
    while (stepsContainer.firstChild) {
        stepsContainer.removeChild(stepsContainer.firstChild);
    }
    mapviewer.removeAllOverlays();
}

/* Method used to clear the route map */
function clearRoutemap()
{
     for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
          mapviewer.removeOverlay(route.polyLine[i]);
        }
        for(var j=0; j < routeMarkers.length; j++){
            mapviewer.removeOverlay(routeMarkers[j]);
        }
        route.polyLine = new Array();
        routeMarkers = new Array();
}

/* Method to create an array of all the locations given by the user */
function addLocation(location,locations) {
    var address = new MMAddress();
	address.qs = location;

    // Country hardcoded as it cant be changed by user
	address.country_code = "UK";
    locations.push(new MMLocation(address));
}

/* Call back method of map when results are loaded */
function resultsLoaded() { 
    document.getElementById('mapHeaderShad').style.visibility = "visible";
    if (route.error_code) {
        isErrorPage = true;
        mapviewer.goToPosition(new MMLocation(new MMLatLon(51.5145, -0.1085), 15));
        if (route.error_code == 'MM_ROUTE_GEOCODING_ERRORS') {
            // Handle geocoding errors by displaying a user message
            processGeocodingErrors (route.geocoding_errors);
        } else {
            // Display an error message, if applicable:
            document.getElementById("dvErrorDetails").style.display = "block";
            document.getElementById("divErrorMsg").innerHTML = route.error_explanation;
        }
        pageHeaderTitle.innerHTML = "Directions from " + startLocation + " to " + endLocation;
        document.getElementById("resultsBrief").innerHTML = "<strong>"+ startLocation + "</strong> to <strong>"
                                                          + endLocation + "</strong>";
    } else {
        document.getElementById("ViewLink").style.display = "block";
        displayStages(route);
        //Display only first feild, if it has multiple feilds in the address
        if(startloc.areas) {
            startloc = startloc.areas[0];
        }
        if(endloc.areas) {
            endloc = endloc.areas[0];
        }
        pageHeaderTitle.innerHTML = "Directions from " + startloc + " to " + endloc;
        document.getElementById("resultsBrief").innerHTML = "<strong>"+ startloc + "</strong> to <strong>"
                                                          + endloc + "</strong>";
        // incase of link shared either by email or share it , imit                                                          
        if(checkIsNullOrEmpty(previousMapPosition))  {
             var mapProperties = previousMapPosition.split('|')
             if(mapProperties.length > 0) {
                   //set the map type
                   var latlon= mapProperties[0].split(',');
                   var latitude = parseFloat(latlon[0]) ;  
                   var longitude = parseFloat(latlon[1]);
                   if(checkIsNullOrEmpty(latitude)&& !isNaN(latitude) && checkIsNullOrEmpty(longitude) && !isNaN(longitude)) {
                     var zoomLevel = parseInt(mapProperties[1]);
                     mapviewer.setMapType( Number(mapProperties[2]));
                     mapviewer.goToPosition(new MMLocation(new MMLatLon(latitude,longitude),zoomLevel));
                   }  else {
                       mapviewer.goToPosition( mapviewer.getAutoScaleLocation( route.bounds ) );
                   }  
             }   
        } else {
            mapviewer.goToPosition( mapviewer.getAutoScaleLocation( route.bounds ) );
        }                                          
                        
        // Show the route on the map with PolyLines, by adding each polyline returned:
        for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
          mapviewer.addOverlay(route.polyLine[i]);
        }
    }
}

/* Method to change the distane units from miles to km and vice versa*/
function onDistanceUnitsChange() {
    if(document.getElementById("showDistance")) {
           var dropdownIndex =document.getElementById("showDistance").selectedIndex;
    }
    if(dropdownIndex == 1) {
            document.getElementById("miledistance").style.display = "none";
            document.getElementById("kmdistance").style.display = "";
            for(var i=1 ; i < totalStepCount; i++) {
                document.getElementById("stepmiledistance"+i).style.display = "none";
                document.getElementById("stepkmdistance"+i).style.display = "";
            }
    } else if(dropdownIndex == 0) {
             document.getElementById("kmdistance").style.display = "none";
            document.getElementById("miledistance").style.display = "";
            
            for(var i=1 ; i < totalStepCount; i++) {
                document.getElementById("stepkmdistance"+i).style.display = "none";
                document.getElementById("stepmiledistance"+i).style.display = "";
            }
    }
}

/* Method to create the route steps page Html string */
function displayStages(route) {
   var curr_step = 1;
   var stages = route.stages; 
   var container = routeStepsPage;
   var text,zindex,instruction,roadname,roadnumber;
   var milesDistance = new StringBuilder();
   var kmDistance = new StringBuilder();
   var infotext = new StringBuilder();
   var routeStepsHtml = new StringBuilder();
   startloc = stages[0].start_address;
   endloc = stages[stages.length - 1].end_address;
   routeStepsHtml.clear();
   routeStepsHtml.append("<div id='listingsContent'>");
   if(ShowDistance == "miles") {
     routeStepsHtml.append("<div id='resultsTitle'><h2>Distance:"+ " " +"<strong><span id='miledistance'>"
                    + route.distance.miles +" miles</span><span id='kmdistance' style='display:none;'>" 
                    + route.distance.km +" Km</span>, about ");
   }
   if (route.duration.days > 0) {
        routeStepsHtml.append(route.duration.days + ' day(s) '); 
   }
   if (route.duration.hours > 0) {
        routeStepsHtml.append(route.duration.hours + ' hour(s) '); 
   }
   if (route.duration.minutes > 0) {
        routeStepsHtml.append(route.duration.minutes + ' minute(s) '); 
   }
   routeStepsHtml.append("</strong></h2>"
       + "<div id='distancePreferences'><label for='showDistance' >show in:</label>"
       + "<select id='showDistance' name='distance'>"
       + "<option selected='selected' value='miles'>miles </option>"
       + "<option value='km'>km </option></select>"                     
       + "<input type='button' value='OK' name='OK' class='button' onclick='onDistanceUnitsChange();' "
       + "style='margin-left:5px;' /></div></div>"                 
       + "<div class='dClear'></div><div class='rightColumn'>"
       + "<div id='scrollDiv' class='searchMapContainer' style='margin-top: 0;'><p class='openInLargeMap'>"                    
       + "<a href='javascript:void(0)' id='openInLarge' onclick='showRouteMap();'>"
       + "open in large map</a>"
       + "<a href='javascript:void(0)' class='dn' id='showWholeRoute' onclick='getRouteBounds();'>"
       + "show route</a></p>"   
       + "<div style='width:250px;height:250px;' id='samllMapViewer'></div>"  
       + "</div></div>"
       + "<div class='leftColumn'>"
       + "<ol id='resultsList'>");
    
    // The route will be returned in stages. Each stage goes from one specified 'location' to the next:
    for (var count=0; count < stages.length; count++) {
     routeStepsHtml.append("<li class='resultsItem expanded'> <h3>"); 
     if(count == "0") {
        routeStepsHtml.append("<img height='25' width='25' class='component icon' alt='Start' src='"
                        + ImagePath + "ico-dir_a.png '/>");
     } else {
        routeStepsHtml.append("<img height='25' width='25' class='component icon' alt='Start' src='"
                        + ImagePath + "ico-dir_via.png '/>");
     }
     routeStepsHtml.append("<strong>"+stages[count].start_address+"</strong> </h3>" 
                     + "<div class='itemContent'> <ol class='legItems'>"); 
 
     var steps = stages[count].steps;
        
     // Now we will display each step instruction within this stage:
     for (var stepCount=0; stepCount < steps.length; stepCount++) {
     
         // Label the current marker with the step number:
         text = curr_step;
         
         // Make the higher numbered step markers appear 'on top of' lower ones:
         zindex = undefined;
            
            // Use 'A' as marker text if this is the first step of the entire route:
            if( count == 0 && stepCount == 0 ) {
                text = 'A'; 
                zindex = '1001';
            }
            // Use 'V' as marker text if this is the via step of the route:
            if( count != 0 && stepCount == 0) {
                text = 'V';
                zindex = '1001';
            }
            // Use 'B' as marker text if this is the last step of the entire route:
            if (count == stages.length - 1 && stepCount  == steps.length - 1) {
                text = 'B';
                 zindex = '1001';
            }                
            // Create a written 'instruction' using the roadname and/ or roadnumber:
            instruction = steps[stepCount].instruction;
            roadname = steps[stepCount].road_name;
            roadnumber = steps[stepCount].road_number;
            infotext.clear();
            infotext.append(instruction); 
            if (roadname && roadnumber) {
                infotext.append(' ' + roadname + ' (' + roadnumber + ') ');
            }  else if (roadname) {
                infotext.append(' ' + roadname + ' ');
            } else if (roadnumber) {
                infotext.append(' ' + roadnumber + ' ');
            }
           
            // Show the distance of this particular step:
            milesDistance.clear();
            kmDistance.clear();
            if (steps[stepCount].distance.miles > 0) {
                milesDistance.append(steps[stepCount].distance.miles + ' mile(s) '); 
            }
            if (steps[stepCount].distance.km > 0) {
                kmDistance.append(steps[stepCount].distance.km + ' km '); 
            }
            routeStepsHtml.append("<li id='legItem_"
                    + curr_step +"' class='legItem' onmouseover='makeStepActive(" 
                    + curr_step +");' onmouseout='makeStepInActive(" 
                    + curr_step + ");' onmousedown='makeCurrentStep(" + curr_step + ");' >"
                    + "<div class='brief'><span class='component marker'><em>"
                    + curr_step +"</em></span> <span class='component stepdetails'>"+ instruction +" ");
            if(roadname && roadname != "") {
                routeStepsHtml.append("<strong>"+ roadname +"</strong>");
            }
            if(roadnumber && roadnumber != "") {
                routeStepsHtml.append(" " + "<strong class='component sign secondaryRoad'>"
                                + "<span class='roadNumber'>"+ roadnumber +"</span></strong>");
            } 
            routeStepsHtml.append("</span><span class='component distance'><span id='stepmiledistance"
                            + curr_step +"'>"+ milesDistance.toString() +"</span>"
                            + "<span id='stepkmdistance"+ curr_step +"' style='display:none;'>"
                            + kmDistance.toString() +"</span></span></div></li> ");
            // Create the step marker, using the instruction and marker text we previously created:
            getStepMarker(steps[stepCount].start_point, infotext.toString(), text, zindex);
            ++curr_step;
        }
        routeStepsHtml.append("</ol></div></li>");
        totalStepCount = curr_step;
    }
    routeStepsHtml.append("<li class='resultsItem expanded destination'>"
             + "<h3><img height='25' width='25' class='component icon' alt='End' src='"
             + ImagePath + "ico-dir_b.png" +"'/>"
             + "<strong>"+stages[stages.length - 1].end_address+"</strong></h3></li>"
             + "</ol></div></div>");     
    // Append the route steps html string to the container
    container.innerHTML = routeStepsHtml.toString();     
}

/* Highlight the step item on mouse over in route steps view */
function makeStepActive(stepCount) {
    if(smallMapViewer && smallMapViewer!= null) {
        document.getElementById("legItem_" + stepCount).className = "legItem active";
        if(smallMarkers.length > 0) {
          smallMarkers[stepCount-1].setVisibility(true);
        }
      }
}

/*Reset the step item style on mouse out in route steps view*/
function makeStepInActive(stepCount) {
    if(smallMarkers.length > 0 && smallMapViewer) {
       if(stepCount != stepClickedNumber) {
           document.getElementById("legItem_" + stepCount).className = "legItem";
           smallMarkers[stepCount-1].setVisibility(false);
       } else {
            document.getElementById("legItem_" + stepCount).className = "legItem current";
       }
    }
}

/* Highlight the step item on mouse click in route steps view */
function makeCurrentStep(stepCount) {
    if(smallMapViewer) {
        document.getElementById("legItem_" + stepCount).className = "legItem current";
        document.getElementById("showWholeRoute").style.display = "block";
        if(stepClickedNumber && stepClickedNumber != stepCount ) {
            document.getElementById("legItem_" + stepClickedNumber).className = "legItem";
            smallMarkers[stepClickedNumber-1].setVisibility(false);
        }
        stepClickedNumber = stepCount;
        if(smallMarkers[stepCount]) {
          smallMarkers[stepCount-1].setVisibility(true);
          smallMapViewer.goToPosition(smallMapViewer.getAutoScaleLocation(smallMarkers[stepCount-1]));
        }  
    }
}

/* Get autoscale location to show all the route points on map  */
function getRouteBounds() {
     smallMapViewer.goToPosition( smallMapViewer.getAutoScaleLocation( small_route.bounds) );
     document.getElementById("showWholeRoute").style.display = "none";
     smallMarkers[stepClickedNumber-1].setVisibility(false);
}

/* Show geocoding error messages */
function processGeocodingErrors (errors) { 
    for (var i = 0; i < errors.length; i++) {
        if (errors[i].error_code == 'MM_GEOCODE_NO_MATCHES') { 
            document.getElementById("dvErrorDetails").style.display = "block";
            document.getElementById("divErrorMsg").innerHTML = "No results found for the location " + "'" 
                                                             +errors[i].address.qs + "'";
        } else if (errors[i].error_code == 'MM_GEOCODE_MULTIPLE_MATCHES') {
            document.getElementById("dvErrorDetails").style.display = "block";
            document.getElementById("divErrorMsg").innerHTML = "Multiple matches found. "
                                                             +"Please refine your search.";
        }
    }
}

/* Method to load the small map on route steps page */
function smallMapLoad() {
    if (!document.getElementById("samllMapViewer")) {
        return false;
    }
    smallMapViewer = MMFactory.createViewer( document.getElementById( "samllMapViewer" ) );
    smallMapViewer.goToPosition(new MMLocation(new MMLatLon(51.5145, -0.1085), 15));
    small_route_finder = MMFactory.createRouteRequester(smallMapResultsLoaded, smallMapViewer );
    loadingStatus( false );
    callSmallRoute();
}

/* Call back method for small map results loaded */
function smallMapResultsLoaded() {
    if (small_route.error_code) {
        if (small_route.error_code == 'MM_ROUTE_GEOCODING_ERRORS') {
            // Handle geocoding errors by displaying disambiguation dropdowns
            processGeocodingErrors (small_route.geocoding_errors);
        } else {
            // Display an error message, if applicable:
            document.getElementById("dvErrorDetails").style.display = "block";
            document.getElementById("divErrorMsg").innerHTML = route.error_explanation;
        }
    }  else {
        // use getAutoScaleLocation to show the entire route on the map, with the route bounds:
        smallMapViewer.goToPosition( smallMapViewer.getAutoScaleLocation( small_route.bounds) );
        displayStages_smallMap(small_route);
        // Show the route on the map with PolyLines, by adding each polyline returned:
        for( var i = 0, l = small_route.polyLine.length; i < l; ++i ) {
          smallMapViewer.addOverlay(small_route.polyLine[i]);
        }
    }
    
    loadingStatus( false );
    window.onscroll=SetScrollPosition;
}

/* Method to create markers on small map */
function displayStages_smallMap(smallroute) {
     var curr_step = 1;
     var stages = smallroute.stages;
     var text,zindex;
     for (var count=0; count < stages.length; count++) {
        var steps = stages[count].steps;
         for (var stepCount=0; stepCount < steps.length; stepCount++) {
            text = curr_step;
            
            // Make the higher numbered step markers appear 'on top of' lower ones:
            zindex = max_zindex - curr_step + 1;
            
            // Use 'A' as marker text if this is the first step of the entire route:
            if( count == 0 && stepCount == 0 ) {
                smallMapViewer.createMarker(steps[stepCount].start_point, {'text' : 'A'});
            }
            
            // Use 'V' as marker text if this is the Via step of the entire route:
            if( count != 0 && stepCount == 0) {
                smallMapViewer.createMarker(steps[stepCount].start_point, {'text' : 'V'});
            }
            
            // Use 'B' as marker text if this is the last step of the entire route:
            if (count == stages.length - 1 && stepCount  == steps.length - 1) {
                smallMapViewer.createMarker(steps[stepCount].start_point, {'text' : 'B'}); 
            }  
            getSmallStepMarker(steps[stepCount].start_point, text);
            smallMarkers[curr_step-1].setVisibility(false);
            ++curr_step;
        }
     }
}

/* Method to create markers on small map and push them into an array */
function createSmallStepMarker(location,text) {
    var marker = smallMapViewer.createMarker(location, {'text' : text});
    smallMarkers.push(marker);
}

/* Method to initiate route requester object for small map */
function callSmallRoute () {
    small_route = new MMRoute( locations );
    if (Shortest == "true") {
        small_route.optimize_for = 'distance';
    } else {
        small_route.optimize_for = 'time';
    } 
    if (Walking == "true") {
        small_route.mode = 'walking';
    } else {
        small_route.mode = 'driving'; 
    } 
    small_route_finder.request(small_route);
}

/* Method used to set the focus on the text box for start location and the end location */
function setDirectionsInputBoxesFocus(){
  startLocation= getQStringValue("sloc");
  endLocation= getQStringValue("eloc");
  if(IsNullOrEmpty(startLocation) && (!IsNullOrEmpty(endLocation))  ) {
     document.getElementById("endLocation").focus();
  } else if( (!IsNullOrEmpty(startLocation) ) && IsNullOrEmpty(endLocation))  {
     document.getElementById("startLocation").focus();
  }
}