API Docs for:
Show:

File: Geo\positioningTool.js

/*================================================================================================================\
+
+ Project     : GODATA-VCEV
+ Filename    : positioningTool.js
+ Module Name : Positioning Tool + Blind Spot
+ Purpose     : To show all Vans and their respective reachable points geographically. And draw paths between them.
+               One can move van and its points and save that state.
+               Blind Spot - Show blind spot geographically and suggest new van on map to cover all the area.
+               One is able to put a dummy van on the map to check if the path strech is covered or not.
+ Coded By    : Pankaj Khandal
+
+================================================================================================================*/


/**
* To show position of vans, reposition them and generate BlindSpot on a path.
* @module  Geo
*/


/**
* To show position of vans, reposition them and generate BlindSpot on a path.
* @class PositioningTool
* @constructor
*/


//================= Global variables===============================
/**
* Global References: Initializing global stores for markers, images, icons, enable/disable bits etc.
* @for PositioningTool
*/
var vanImagePath = "../../Content/css/images/avil-van.png",
    vanReachablePointImagePath = "../../Scripts/map_api/icons/red_circle.png",
    bs_vanImagePath = "../../Content/css/images/avil-van.png",
    bs_waypointImagePath = "../../Scripts/map_api/icons/green_circle.png",
    bs_vanToolImagePath = "../../Content/css/images/avil-van-pointing.png",
    bs_waypointToolImagePath = "../../Scripts/map_api/icons/green_circle-pointing.png",
    bs_downArrowImagePath = "../../Scripts/map_api/icons/arrow01.png",
    markerTransImgPath = "../../Scripts/map_api/icons/red_blink.gif",
    defaultLat = 26.912285124827,
    defaultLng = 75.7873203125;
var SecurityToken, utcMinutes, UserId;
var map = null; // to store map object globally
var directionService;   // to store Direction-Service object globally
var geoCoder;   // to store Geo-Coder object globally
var distanceMatrixService;  // to store Distance-Matrix Service object globally
var MARKERS = [];   // To store Marker objects globally
var POLYGONS = [];  // To store Polygon object globally
var POSITIONING_JSON = [];  // To store Exiting Positionig JSON globally
var UPDATED_POSITIONING_JSON = [];  // To store updated coverage Objects
var ROUTES = [];    // To store route objects globally
var MOVED_VAN_ROUTES = [];  // To store dragged Van route object globally

var distanceTimeObj = new Object(); // To store the callback result of Distance Matrix.
var directionMatrixTime = 0;    // To hold new reachable time when we drag a reachable point

var directionObj = {};  // To store Route-Direction Objects
var directionsRenderer; // To store direction display renderer on map
var latlngbounds;   // To store lat long bounds to center the map

var pointAngle = 30;   // Angle on which we want a point from a sorce point (Degree)
var bs_pointAngle = 30; // Angle on which we want a point from a sorce point (Degree)
var radiusIncrement = 15;  // constant increament in radius to get optimal reachable point from a van
var radiusAccToSlaObj = { '90': 55, '120': 75 };    // Van's reachable point's minimum distance (KMs) for diffrent SLAs in minutes

var slaTimeInMin = 0;   // To store SLA time in minutes globally
var coverageMultiplier = 1.6;   // Coverage enhancer
var enableCoverageDesign = true;    // To enable/disable coverage.
var coverageDesiged = false;    // To check if coverage is designed once

//-------------- BLIND SPOT Global variables ----------------------
var BS_WAYPOINDID = 0;  // Initialize the waypoint Id
var BS_VAN_ID = 0;  // Initialize the Van Id
var disable_map_click_Listener = true;  // To disable/enable map click
var disable_map_mousemove_Listener_waypoint = true; // To disable/enable mouse move on map
var disable_map_click_Listener_waypoint = true; // To disable/enable map click for a waypoint
var disable_map_click_Listener_van = true;  // To disable/enable map click for a van
var disable_map_mousemove_Listener_van = true;  //To disable/enable mouse move on map for van
var enableBlindSpotGenerator = true;    // To disable/enable Blind spot generation
var bs_enableCoverageDesign = true; // To disable/enable coverage designer
var bs_popTheVanOut = true; // To disable/enable removing the last van marker, when no response from goole
var bs_coverageMultiplier = 1.6;    // covearge enhancer
var bs_coverageDesiged = false; // To disable/enable if coverage is designed

var BS_MARKERS = [];    // To Store Blind Spot markers globally
var BS_VAN_MARKERS = [];    // To Store Blind Spot Van markers globally
var BS_WAYPOINTS = [];  // To Store Blind Spot waypoints globally
var BS_WAYPOINTS_reverse = [];  // To Store Blind Spot waypoints in reverse order of plotting
var BS_ENDS = [];   // To Store Blind Spot region End points
var BS_STARTS = []; // To Store Blind Spot region start points
var BS_CIRCLES = [];    // To Store Blind Spot region circles
var BS_MID_MARKERS = [];    // To Store Blind Spot region mid points
var BS_MOVED_VAN_ROUTES = [];   // To Store Blind Spot moved van route object
var BS_POLYGONS = [];   // To Store Blind Spot polygons
var bs_directionObj = {};   // To Store Blind Spot Van's routes to their reachable points
var BS_ARROW_MARKERS = [];  // To Store Blind Spot region arrow markers
var BS_VAN_REACHABLE_POINT = [];    // To Store Blind Spot Van's reachable points
var BS_ROUTES = []; // To Store Blind Spot Van's routes
//--------------------------------------------
//=================================================================

/**
* To check state is entered or not.
* @method StateValid
* @for PositioningTool
*/
function StateValid() {
    var vResult = false;
    var State = $("#stateCombobox").val();
    $("#spanState1").hide();
    if (State == "") {
        $("#spanState1").show();
    }
    else {
        vResult = true;
    }
    return vResult;
}

/////============================= Getting Circular points which is some time away from a source point =====================
/**
* To convert a degrees into radians.
* @method Number.prototype.toRad
* @for PositioningTool
*/
Number.prototype.toRad = function () {
    return this * Math.PI / 180;
}

/**
* To convert a radians into degrees.
* @method Number.prototype.toDeg
* @for PositioningTool
*/
Number.prototype.toDeg = function () {
    return this * 180 / Math.PI;
}

/**
* To get a position at an angle and at a distance on google map.
* @method google.maps.LatLng.prototype.destinationPoint
* @param {Number} angle angle in Degrees
* @param {Number} dist distance in KMs
* @for PositioningTool
*/
google.maps.LatLng.prototype.destinationPoint = function (angle, dist) {
    dist = dist / 6371;
    angle = angle.toRad();
    var lat1 = this.lat().toRad(), lon1 = this.lng().toRad();
    var lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist) + Math.cos(lat1) * Math.sin(dist) * Math.cos(angle));
    var lon2 = lon1 + Math.atan2(Math.sin(angle) * Math.sin(dist) * Math.cos(lat1), Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2));
    if (isNaN(lat2) || isNaN(lon2)) return null;
    return new google.maps.LatLng(lat2.toDeg(), lon2.toDeg());
}

/**
* To get a position at an angle and at a distance on google map.
* @method findReachablePointsForVan
* @param {Object} sourcePosition position(lat-long object) of source
* @param {Number} pointAngle angle in Degrees
* @param {Number} radius distance in KMs
* @for PositioningTool
*/
function findReachablePointsForVan(sourcePosition, pointAngle, radius) {
    var reachablePoints = [];
    for (var i = 0; i <= 360; i = i + pointAngle) {
        var point = sourcePosition.destinationPoint(i, radius);
        reachablePoints.push(point);
    }
    return reachablePoints;
}
/////================================================================================================================


//================== FILTERS Section Start =========================
/**
* To populate state combobox.
* @method loadStateChoices
* @for PositioningTool
*/
function loadStateChoices() {
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;

    $.ajax({
        type: "POST",
        url: WCFRESTURL.GetStateListIdWise,
        data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId },
        dataType: "json",
        success: function (data) {
            $("#stateCombobox").kendoComboBox({
                placeholder: "State",
                dataTextField: "StateAlias",
                dataValueField: "StateId",
                filter: "contains",
                dataSource: data,
                change: function () {
                    // loading cities according to state id
                    //loadCityChoices($("#stateCombobox").val());
                    //loadDealerChoices($("#stateCombobox").data("kendoComboBox").text(), $("#cityCombobox").data("kendoComboBox").text());
                }
            });
        },
        complete: function () {
            //$("#stateCombobox").data('kendoComboBox').select(0);
        },
        error: function (jqXHR, textStatus, errorThrown) {
        }
    });
}

/**
* To populate city combobox.
* @method loadCityChoices
* @for PositioningTool
*/
function loadCityChoices(stateId) {
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;

    $.ajax({
        type: "POST",
        url: WCFRESTURL.GetCityListStateIdWise,
        data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId, StateId: stateId },
        dataType: "json",
        success: function (data) {
            $("#cityCombobox").kendoComboBox({
                dataTextField: "CityName",
                dataValueField: "CityId",
                filter: "contains",
                dataSource: data,
                change: function () {
                    loadDealerChoices($("#stateCombobox").data("kendoComboBox").text(), $("#cityCombobox").data("kendoComboBox").text());
                }
            });
        },
        complete: function () {
            $("#cityCombobox").data("kendoComboBox").text('');
        },
        error: function (jqXHR, textStatus, errorThrown) {
        }
    });
}

/**
* To populate city combobox.
* @method loadCityChoices
* @for PositioningTool
*/
function loadDealerChoices(state, city) {
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;

    $.ajax({
        type: "POST",
        url: WCFRESTURL.GetDealerStateCityWise,
        data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId, DealerStateParam: state, DealerCityParam: city },
        dataType: "json",
        success: function (data) {
            $("#dealerCombobox").kendoComboBox({
                dataTextField: "DealerDealerName",
                dataValueField: "DealerId",
                filter: "contains",
                dataSource: data,
            });
        },
        complete: function () {
            $("#dealerCombobox").data("kendoComboBox").text('');
        },
        error: function (jqXHR, textStatus, errorThrown) {
        }
    });
}

/**
* To populate SLA combobox.
* @method loadAllSla
* @for PositioningTool
*/
function loadAllSla() {
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;

    $.ajax({
        type: "POST",
        url: WCFRESTURL.GetAllSLA,
        data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId },
        dataType: "json",
        success: function (data) {
            $("#slaCombobox").kendoDropDownList({
                dataTextField: "SlaTime",
                dataValueField: "Id",
                dataSource: data,
                index: 0,
                change: function () {
                    // Getting curent SLA time and storing that globally
                    slaTimeInMin = $("#slaCombobox").data("kendoDropDownList").text();
                }
            });
        },
        complete: function () {
            // Getting curent SLA time and storing that globally
            slaTimeInMin = $("#slaCombobox").data("kendoDropDownList").text();
        },
        error: function (jqXHR, textStatus, errorThrown) {
        }
    });
}
//================== FILTERS Section End =========================




/**
* To create unique Van-JSON to update on the server.
* @method createUpdatedPOSITIONING_JSON
* @param {Object} van van-object contains van and its reachable point details.
* @for PositioningTool
*/
function createUpdatedPOSITIONING_JSON(van) {
    if (UPDATED_POSITIONING_JSON.length == 0) {
        UPDATED_POSITIONING_JSON.push(van);
    }
    else {
        for (var i = 0; i < UPDATED_POSITIONING_JSON.length; i++) {
            if (UPDATED_POSITIONING_JSON[i].VanId == van.VanId) {
                UPDATED_POSITIONING_JSON.splice(i, 1);
                UPDATED_POSITIONING_JSON.push(van);
            } else {
                UPDATED_POSITIONING_JSON.push(van);
            }
        }
    }
}

/**
* To update the Van coverage onto the server.
* @method updateVanCoverage
* @for PositioningTool
*/
function updateVanCoverage() {
    $("#div_load").show(); // Showing loading
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;
    var updatedVanCoverageData = JSON.stringify(UPDATED_POSITIONING_JSON);  // serializing the JSON before sending to the server

    $.ajax({
        url: WCFRESTURL.UpdateAllVansOnGeoView,
        type: "POST",
        data: { Token: "teramatrix", VanListJson: updatedVanCoverageData },
        dataType: "json",
        contentType: "application/x-www-form-urlencoded; charset=utf-8", // This is the content type when posting Plain Text to server.
        success: function (data) {
            $('#get_van_coverage').show();  // Showing the get-van-coverage button
            $('#update_van_coverage').hide();    // Hiding update-van-coverage button
            $('#reset_van_coverage').hide();    // Hiding update-van-coverage button

            jAlert(POSITIONING_MSG['coverage_update_success'], 'Message');
        },
        complete: function () {
            $("#div_load").hide();  // Hiding loading
            UPDATED_POSITIONING_JSON = [];  // Making the updated positioning JSON empty. so that it is less occupied next time when update is happening
        },
        error: function (jqXHR, textStatus, errorThrown) {
            jAlert(POSITIONING_MSG['coverage_update_error'], 'Message');
        }
    });
}

/**
* To Reset the Van server to earliar state.
* @method resetVanCoverage
* @for PositioningTool
*/
function resetVanCoverage() {
    getAllVansOnGeoView();
}

/**
* To get distance and time to raech to a point on google map and store that in a global object.
* @method getDistanceAndTime
* @param {Double} sourceLat source lattitude
* @param {Double} sourceLong source longitude
* @param {Double} destinationLat destination lattitude
* @param {Double} destinationLong destination longitude
* @for PositioningTool
*/
function getDistanceAndTime(sourceLat, sourceLong, destinationLat, destinationLong) {
    var sourceLocation = new google.maps.LatLng(sourceLat, sourceLong);
    var destinationLocation = new google.maps.LatLng(destinationLat, destinationLong);

    var request = {
        origins: [sourceLocation],
        destinations: [destinationLocation],
        travelMode: google.maps.TravelMode.DRIVING,
        //transitOptions: google.maps.TransitMode.BUS,
        unitSystem: google.maps.UnitSystem.METRIC,
        //durationInTraffic: Boolean, // consider traffice conditions //for work customers
        avoidHighways: false,
        avoidTolls: false
    }
    distanceMatrixService.getDistanceMatrix(request, function (response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK) {
            var result = response.rows[0].elements[0];
            var distance = result.distance.text;
            var duration = result.duration.value;
            // Setting the gloabal object to store the duration.
            distanceTimeObj.distance = distance;
            distanceTimeObj.durationInMin = parseInt(duration / 60);
            directionMatrixTime = parseInt(duration / 60);
        }
    });
}

/**
* To get circular points at a distance and at an angle.
* @method getCoverageForVan
* @param {Double} newLatOfVan marker's new lattitude
* @param {Double} newLongOfVan marker's new longitude
* @param {Int} slaTimeInMin SLA time in minutes
* @param {Int} minRadius minimum radius
* @for PositioningTool
*/
function getCoverageForVan(newLatOfVan, newLongOfVan, slaTimeInMin) {
    var vanLocation = new google.maps.LatLng(newLatOfVan, newLongOfVan);
    //minRadius = (slaTimeInMin == 90) ? (minRadius = minRadiusFor90min) : (minRadius = minRadiusFor120min);
    minRadius = radiusAccToSlaObj[slaTimeInMin];

    var radiusArray = [];
    radiusArray.push(minRadius);
    radiusArray.push(minRadius + radiusIncrement);
    radiusArray.push(minRadius + (2 * radiusIncrement));
    radiusArray.push(minRadius + (3 * radiusIncrement));

    var points = [];
    for (var angle = 0; angle < 360; angle += pointAngle) {
        for (var i = 0; i < radiusArray.length; i++) {
            var point = vanLocation.destinationPoint(angle, radiusArray[i]);
            points.push(point);
        }
    }
    return points;
}


/**
* To get circular points at a distance and at an angle.
* @method getCoverageForVanStatic
* @param {Double} newLatOfVan marker's new lattitude
* @param {Double} newLongOfVan marker's new longitude
* @param {Int} slaTimeInMin SLA time in minutes
* @param {Int} minRadius minimum radius
* @for PositioningTool
*/
function getCoverageForVanStatic(newLatOfVan, newLongOfVan, slaTimeInMin) {
    var vanLocation = new google.maps.LatLng(newLatOfVan, newLongOfVan);
    //minRadius = (slaTimeInMin == 90) ? (minRadius = minRadiusFor90min) : (minRadius = minRadiusFor120min);
    minRadius = radiusAccToSlaObj[slaTimeInMin];

    var radiusArray = [];
    radiusArray.push(minRadius);

    var points = [];
    for (var angle = 0; angle < 360; angle += pointAngle) {
        for (var i = 0; i < radiusArray.length; i++) {
            var point = vanLocation.destinationPoint(angle, radiusArray[i]);
            points.push(point);
        }
    }
    return points;
}


/**
* To get circular points at a distance and at an angle.
* @method bs_getCoverageForVan
* @param {Double} newLatOfVan marker's new lattitude
* @param {Double} newLongOfVan marker's new longitude
* @param {Int} slaTimeInMin SLA time in minutes
* @param {Int} minRadius minimum radius
* @for PositioningTool
*/
function bs_getCoverageForVan(newLatOfVan, newLongOfVan, slaTimeInMin) {
    var vanLocation = new google.maps.LatLng(newLatOfVan, newLongOfVan);
    //minRadius = (slaTimeInMin == 90) ? (minRadius = minRadiusFor90min) : (minRadius = minRadiusFor120min);
    minRadius = radiusAccToSlaObj[slaTimeInMin];

    var radiusArray = [];
    radiusArray.push(minRadius);
    radiusArray.push(minRadius + radiusIncrement);
    radiusArray.push(minRadius + (2 * radiusIncrement));
    radiusArray.push(minRadius + (3 * radiusIncrement));

    var points = [];
    for (var angle = 0; angle < 360; angle += bs_pointAngle) {
        for (var i = 0; i < radiusArray.length; i++) {
            var point = vanLocation.destinationPoint(angle, radiusArray[i]);
            points.push(point);
        }
    }
    return points;
}

/**
* To get circular points at a distance and at an angle.
* @method bs_getCoverageForVanStatic
* @param {Double} newLatOfVan marker's new lattitude
* @param {Double} newLongOfVan marker's new longitude
* @param {Int} slaTimeInMin SLA time in minutes
* @param {Int} minRadius minimum radius
* @for PositioningTool
*/
function bs_getCoverageForVanStatic(newLatOfVan, newLongOfVan, slaTimeInMin) {
    var vanLocation = new google.maps.LatLng(newLatOfVan, newLongOfVan);
    //minRadius = (slaTimeInMin == 90) ? (minRadius = minRadiusFor90min) : (minRadius = minRadiusFor120min);
    minRadius = radiusAccToSlaObj[slaTimeInMin];

    var radiusArray = [];
    radiusArray.push(minRadius);

    var points = [];
    for (var angle = 0; angle < 360; angle += bs_pointAngle) {
        for (var i = 0; i < radiusArray.length; i++) {
            var point = vanLocation.destinationPoint(angle, radiusArray[i]);
            points.push(point);
        }
    }
    return points;
}


/**
* To set the map center on the passed addess.
* @method setMapCenterToAddress
* @param {String} address address for the map
* @for PositioningTool
*/
function setMapCenterToAddress(address) {
    geoCoder = new google.maps.Geocoder();
    geoCoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            if (typeof results[0].geometry.bounds === 'undefined') {
                map.fitBounds(results[0].geometry.bounds);
            }
        }
    });
}


/**
* To draw the circle on the map.
* @method drawCircle
* @param {Object} center center of circle
* @param {Int} radius radius of circle
* @param {String} circleTitle title of circle
* @for PositioningTool
*/
function drawCircle(center, radius, circleTitle) {
    var circleOptions = {
        strokeColor: '#FF0000',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#FF0000',
        fillOpacity: 0.35,
        map: map,
        center: center,
        radius: radius,
        circleTitle: circleTitle
    };
    var circle = new google.maps.Circle(circleOptions);
    return circle;
}

/**
* To get the midpoint between two points at a distance.
* @method getMidpoint
* @param {Array} points source and destionation points
* @param {Int} midpointDistance midpoint distance from a point
* @for PositioningTool
*/
function getMidpoint(points, midpointDistance) {
    var tempDistance = midpointDistance;
    var midpointLatLng;

    // We go through each segment of the line
    for (var i = 0; i < points.length - 1; i++) {
        var segment = points.slice(i, i + 2);
        var length = google.maps.geometry.spherical.computeLength(segment);
        tempDistance = tempDistance - length;

        // If we're at zero or below, we've found the line where our midpoint exists
        if (tempDistance <= 0) {
            // We've gone past the midpoint so we need to back up.
            var midpointLength = tempDistance + length;

            // The proportion of the current segment where our midpoint exists
            var percentage = midpointLength / length;

            midpointLatLng = google.maps.geometry.spherical.interpolate(segment[0], segment[1], percentage);
            break;
        }
    }
    if (typeof midpointLatLng === 'undefined') {
        // we don't have a midpoint for this polyline, something went very wrong
        return false;
    } else {
        return midpointLatLng;
    }
}



////======================== Event / Action Handlers on Map Section Start ===========================
/**
* To plot van at new position and draw its coverage and paths
* @method dragEndHandlerForVan
* @param {Object} marker van marker object on map
* @for PositioningTool
*/
function dragEndHandlerForVanStatic(marker) {
    //$("#div_load").show();  // Showing loading
    //$('#get_van_coverage').hide();   // Hiding the get-van-coverage button
    //$('#update_van_coverage').show();   // Showing update-van-coverage button
    //$('#reset_van_coverage').show();    // Showing update-van-coverage button

    var vanId = marker.id;  // Getting Van id form the marker

    MOVED_VAN_ROUTES = [];  // Making the Moved-Van-Routes array empty.

    //enableCoverageDesign = true;    // enabling coverage design functionality

    var newLatOfVan = marker.position.lat();    // getting lat of dragged marker
    var newLongOfVan = marker.position.lng();   // getting long of dragged marker

    // Getting Van reachable points at a given radius
    var final_vanReachablePoints = getCoverageForVanStatic(newLatOfVan, newLongOfVan, slaTimeInMin);

    coverageDesiged = true; // Coverage is desgned now
    //---------------------------------------------------------------
    // Plotting van, paths and updating van object
    var sourceVan = new google.maps.LatLng(newLatOfVan, newLongOfVan);
    // Plotting VAN's reachable points
    $.each(POSITIONING_JSON, function (index, van) {
        if (van.VanId == vanId) {
            deletePolygon(vanId);   // Deleting the dragged Polygon 
            polyCoordinates = [];   // taking empty array to store polygon coordinates

            van.VanDefaultLatitude = newLatOfVan;   // setting new lat to the Global JSON
            van.VanDefaultLongitude = newLongOfVan; // setting new long to the Global JSON

            // Remove previous polygon basis on "title"
            for (var i = 0; i < POLYGONS.length; i++) {
                if (POLYGONS[i].title == van.VanId) {
                    POLYGONS[i].setMap(null);
                    POLYGONS.splice(i, 1);
                }
            }
            // Plotting VAN's reachable points
            $.each(van.VanPostionList, function (point_index, point) {
                var vanReachablePointId = point.VanPositionCoverageVanId + '_' + point.VanPositionCoverageId;
                // One by one deleting route associated to this Van
                deleteRoute(vanReachablePointId);
                // One by one deleting VanReachable Points
                deleteMarker(vanReachablePointId);

                // if no point is there then set lat long to null
                if (typeof final_vanReachablePoints[point_index] === 'undefined') {
                    // updating the Lat-Long of dragged item
                    point.VanPositionCoverageVanLatitude = null;
                    point.VanPositionCoverageVanLongitude = null;
                }
                else {
                    // updating the Lat-Long of dragged item
                    point.VanPositionCoverageVanLatitude = final_vanReachablePoints[point_index].lat();
                    point.VanPositionCoverageVanLongitude = final_vanReachablePoints[point_index].lng();

                    var reachablePointId = point.VanPositionCoverageVanId + '_' + point.VanPositionCoverageId;
                    var vanPointInfoWindow = '<div>' + reachablePointId + '</div>';
                    putMarkerOnMap(map, vanPointInfoWindow, point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude, '', reachablePointId, vanReachablePointImagePath, true, false, false)

                    // Storing Point Cordinaates to draw a polygon
                    var reachablePoint = new google.maps.LatLng(point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude);
                    polyCoordinates.push(reachablePoint);

                    // craeting Route Object and storing that globally.
                    var routeObj = new Object({ 'routeId': reachablePointId, 'source': sourceVan, 'destination': reachablePoint });
                    MOVED_VAN_ROUTES.push(routeObj);
                }
            });
            // Draw polygon and storing them globally
            var polygon = drawPolygon(polyCoordinates, van.VanId);
            POLYGONS.push(polygon);

            // Drawing path for moved Van.
            drawPathManagerForMovedVan();

            // Creating Updated POSITIONING_JSON
            createUpdatedPOSITIONING_JSON(van);
            return;
        }
    });
    //-------------------------------------------------
}



/**
* To plot van at new position and draw its coverage and paths
* @method dragEndHandlerForVan
* @param {Object} marker van marker object on map
* @for PositioningTool
*/
function dragEndHandlerForVan(marker) {
    $("#div_load").show();  // Showing loading
    $('#get_van_coverage').hide();   // Hiding the get-van-coverage button
    $('#update_van_coverage').show();   // Showing update-van-coverage button
    $('#reset_van_coverage').show();    // Showing update-van-coverage button

    var vanId = marker.id;  // Getting Van id form the marker

    MOVED_VAN_ROUTES = [];  // Making the Moved-Van-Routes array empty.

    coverageDesiged = false;    // Coverage is not there on map for this van
    enableCoverageDesign = true;    // enabling coverage design functionality

    var newLatOfVan = marker.position.lat();    // getting lat of dragged marker
    var newLongOfVan = marker.position.lng();   // getting long of dragged marker

    // Getting Van reachable points at a given radius
    var vanReachablePoints = getCoverageForVan(newLatOfVan, newLongOfVan, slaTimeInMin);
    //--------------------------------------------
    // Dividing reachable points array into two parts to send two saparate requests on direction matrix
    var vanReachablePoints1 = [];
    var vanReachablePoints2 = [];
    var mid = parseInt(vanReachablePoints.length / 2);
    for (var i = 0; i < mid ; i++) {
        vanReachablePoints1.push(vanReachablePoints[i])
        vanReachablePoints2.push(vanReachablePoints[mid + i]);
    }
    //--------------------------------------------
    var final_vanReachablePoints = [];
    //================== Design Coverage =====================
    // getting first 180 degree optimal points 
    setTimeout(function () {
        var request1 = {
            origins: [marker.position],
            destinations: vanReachablePoints1,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }
        distanceMatrixService.getDistanceMatrix(request1, function (response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK) {
                var result = response.rows[0].elements;
                var start = 1;
                var counter = 0;
                for (var index1 = 0; index1 < result.length; index1++) {
                    // putting van on its previous location when undefined response from direction matrix
                    if (typeof result[index1].duration === 'undefined') {
                        // Repositioning the marker to the last eligible location
                        //$.each(POSITIONING_JSON, function (i, van) {
                        //    if (van.VanId == vanId) {
                        //        marker.setPosition(new google.maps.LatLng(van.VanDefaultLatitude, van.VanDefaultLongitude));
                        //    }
                        //});
                        //jAlert(POSITIONING_MSG['drag_van_error'], 'Message');

                        dragEndHandlerForVanStatic(marker);
                        enableCoverageDesign = false;   // disabling van coverage design
                        //$("#div_load").hide();  // hiding loading
                        return;
                    };
                    // getting and converting duration in minutes
                    var durationInMin = parseInt(result[index1].duration.value / 60, 10);
                    counter++;
                    if ((durationInMin > (slaTimeInMin * bs_coverageMultiplier)) || (counter == 4)) {
                        ((index1 - 1) == -1) ? final_vanReachablePoints.push(vanReachablePoints1[index1]) : final_vanReachablePoints.push(vanReachablePoints1[index1 - 1]);
                        index1 = start * 4;
                        start++;
                        counter = 0;
                    }
                }
            }
        });
    }, 300);

    //--------------------------------
    // getting 180-360 degree optimal points
    setTimeout(function () {
        if (coverageDesiged) { return; }    // If coverage is designed once then exit the loop

        var request2 = {
            origins: [marker.position],
            destinations: vanReachablePoints2,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }
        distanceMatrixService.getDistanceMatrix(request2, function (response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK) {
                var result = response.rows[0].elements;
                var start = 1;
                var counter = 0;

                for (var index2 = 0; index2 < result.length; index2++) {
                    // putting van on its previous location when undefined response from direction matrix
                    if ((enableCoverageDesign == true) && (typeof result[index2].duration === 'undefined')) {
                        // Repositioning the marker to the last eligible location
                        //$.each(POSITIONING_JSON, function (i, van) {
                        //    if (van.VanId == vanId) {
                        //        marker.setPosition(new google.maps.LatLng(van.VanDefaultLatitude, van.VanDefaultLongitude));
                        //    }
                        //});
                        //jAlert(POSITIONING_MSG['drag_van_error'], 'Message');

                        dragEndHandlerForVanStatic(marker);

                        //$("#div_load").hide();  // hiding loading
                        return;
                    };

                    // getting and converting duration in minutes
                    var durationInMin = parseInt(result[index2].duration.value / 60, 10);
                    counter++;
                    if ((durationInMin > (slaTimeInMin * coverageMultiplier)) || (counter == 4)) {
                        ((index2 - 1) == -1) ? final_vanReachablePoints.push(vanReachablePoints2[index2]) : final_vanReachablePoints.push(vanReachablePoints2[index2 - 1]);
                        index2 = start * 4;
                        start++;
                        counter = 0;
                    }
                }
                //---------------------------------------------------------------
                // Plotting van, paths and updating van object
                var sourceVan = new google.maps.LatLng(newLatOfVan, newLongOfVan);
                // Plotting VAN's reachable points
                $.each(POSITIONING_JSON, function (index, van) {
                    if (van.VanId == vanId) {
                        deletePolygon(vanId);   // Deleting the dragged Polygon 
                        polyCoordinates = [];   // taking empty array to store polygon coordinates

                        van.VanDefaultLatitude = newLatOfVan;   // setting new lat to the Global JSON
                        van.VanDefaultLongitude = newLongOfVan; // setting new long to the Global JSON

                        // Remove previous polygon basis on "title"
                        for (var i = 0; i < POLYGONS.length; i++) {
                            if (POLYGONS[i].title == van.VanId) {
                                POLYGONS[i].setMap(null);
                                POLYGONS.splice(i, 1);
                            }
                        }
                        // Plotting VAN's reachable points
                        $.each(van.VanPostionList, function (point_index, point) {
                            var vanReachablePointId = point.VanPositionCoverageVanId + '_' + point.VanPositionCoverageId;
                            // One by one deleting route associated to this Van
                            deleteRoute(vanReachablePointId);
                            // One by one deleting VanReachable Points
                            deleteMarker(vanReachablePointId);

                            // if no point is there then set lat long to null
                            if (typeof final_vanReachablePoints[point_index] === 'undefined') {
                                // updating the Lat-Long of dragged item
                                //point.VanPositionCoverageVanLatitude = null;
                                //point.VanPositionCoverageVanLongitude = null;
                                point.VanPositionCoverageVanLatitude = '';
                                point.VanPositionCoverageVanLongitude = '';
                            }
                            else {
                                // updating the Lat-Long of dragged item
                                point.VanPositionCoverageVanLatitude = final_vanReachablePoints[point_index].lat();
                                point.VanPositionCoverageVanLongitude = final_vanReachablePoints[point_index].lng();

                                var reachablePointId = point.VanPositionCoverageVanId + '_' + point.VanPositionCoverageId;
                                var vanPointInfoWindow = '<div>' + reachablePointId + '</div>';
                                putMarkerOnMap(map, vanPointInfoWindow, point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude, '', reachablePointId, vanReachablePointImagePath, true, false, false)

                                // Storing Point Cordinaates to draw a polygon
                                var reachablePoint = new google.maps.LatLng(point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude);
                                polyCoordinates.push(reachablePoint);

                                // craeting Route Object and storing that globally.
                                var routeObj = new Object({ 'routeId': reachablePointId, 'source': sourceVan, 'destination': reachablePoint });
                                MOVED_VAN_ROUTES.push(routeObj);
                            }
                        });
                        // Draw polygon and storing them globally
                        var polygon = drawPolygon(polyCoordinates, van.VanId);
                        POLYGONS.push(polygon);

                        // Drawing path for moved Van.
                        drawPathManagerForMovedVan();

                        // Creating Updated POSITIONING_JSON
                        createUpdatedPOSITIONING_JSON(van);
                        return;
                    }
                });
                //-------------------------------------------------
            }
        });
        //----------------------------------------------
    }, 1000);
}

/**
* To plot van reachable point at new position and draw its path with distance check from the van
* @method dragEndHandlerForVanReachablePoint
* @param {Object} marker reachbale point marker object on map
* @for PositioningTool
*/
function dragEndHandlerForVanReachablePoint(marker) {
    $('#get_van_coverage').hide();   // Hiding the get-van-coverage button
    $('#update_van_coverage').show();   // Showing update-van-coverage button
    $('#reset_van_coverage').show();    // Showing update-van-coverage button

    var vanId = marker.id.split('_')[0];    // getting van id
    var markerId = marker.id.split('_')[1]; // getting van's reachbale point id

    // iterating through global JSON and updating that according for the dragged point
    $.each(POSITIONING_JSON, function (index, van) {
        if (van.VanId == vanId) {
            // Getting new Lat-Long of the dragged marker.
            var newLatOfPoint = marker.position.lat();
            var newLongOfPoint = marker.position.lng();

            // Calculating Distance and time between two locations.
            getDistanceAndTime(van.VanDefaultLatitude, van.VanDefaultLongitude, newLatOfPoint, newLongOfPoint);

            // Getting response from Direction-Matrix and Position the marker, drawing path accordingly
            setTimeout(function () {
                // If Travel time to newly dragged position is more than SLA-Time,
                // then show alert and Put back the marker in the last eligible position
                if ((distanceTimeObj.durationInMin == 'undefined') || (distanceTimeObj.durationInMin >= slaTimeInMin)) {
                    var alertMessage = POSITIONING_MSG['sla_exceed_error'] + slaTimeInMin;
                    jAlert(alertMessage, 'Message');
                    // Repositioning the marker to the last eligible location
                    $.each(van.VanPostionList, function (index, point) {
                        if (point.VanPositionCoverageId == markerId) {
                            marker.setPosition(new google.maps.LatLng(point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude));
                        }
                    });
                    return;
                }
                else {
                    // Making empty the polygon Coordinates Array
                    polyCoordinates = [];
                    // Plotting VAN's reachable points
                    $.each(van.VanPostionList, function (index, point) {
                        // Storing Point Coordinates to draw a polygon
                        if (point.VanPositionCoverageId == markerId) {
                            polyCoordinates.push(marker.position);

                            // updating the Lat-Long of dragged item
                            point.VanPositionCoverageVanLatitude = newLatOfPoint;
                            point.VanPositionCoverageVanLongitude = newLongOfPoint;
                        }
                        else {
                            polyCoordinates.push(new google.maps.LatLng(point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude));
                        }
                    });
                    // Remove previous polygon basis on "title"
                    for (var i = 0; i < POLYGONS.length; i++) {
                        if (POLYGONS[i].title == van.VanId) {
                            POLYGONS[i].setMap(null);
                            POLYGONS.splice(i, 1);
                        }
                    }
                    // Draw polygon and storing them globally
                    var polygon = drawPolygon(polyCoordinates, van.VanId);
                    POLYGONS.push(polygon);

                    // Creating Updated POSITIONING_JSON
                    createUpdatedPOSITIONING_JSON(van);

                    // Draw new path
                    var sourcePoint = new google.maps.LatLng(van.VanDefaultLatitude, van.VanDefaultLongitude);;
                    var destinationPoint = new google.maps.LatLng(marker.position.lat(), marker.position.lng());;

                    // delete existing path between source and this point and drawing a new path
                    var routeId = marker.id;
                    deleteRoute(routeId);
                    drawPath(sourcePoint, destinationPoint, routeId)
                    return;
                }
            }, 800);
        }
    });
}
////======================== Event / Action Handlers on Map Section End ===========================



////================== Draw / Put Objects on Map Section Start ==============================
/**
* To draw path between two points and setting am routeId for the same.
* @method drawPath
* @param {Object} sourcePoint source lat-long
* @param {Object} destinationPoint destination lat-long
* @param {Object} routeId route-id
* @for PositioningTool
*/
function drawPath(sourcePoint, destinationPoint, routeId) {
    // Storing directions in direction object
    if (!directionObj[routeId]) {
        directionObj[routeId] = [];
    }
    // setting the renderer opting 
    var rendererOptions = {
        preserveViewport: true,
        suppressMarkers: true,
        polylineOptions: { strokeColor: "#1b3f94" }
    };
    directionsRenderer = new google.maps.DirectionsRenderer(rendererOptions);   // creating direction renderer object
    directionsRenderer.setMap(map); // setting this direction renderer on map
    directionObj[routeId].push(directionsRenderer); // pusshing the route object in the global direction object

    // creating path request
    var request = {
        origin: sourcePoint,
        destination: destinationPoint,
        travelMode: google.maps.TravelMode.DRIVING
    };
    // Route the directions and pass the response to a
    // function to create markers for each step.
    directionService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsRenderer.setDirections(response);
        }
    });
}

/**
* To manage drawing paths on map at a time interval
* @method drawPathManagerForMovedVan
* @for PositioningTool
*/
function drawPathManagerForMovedVan() {
    $("#div_load").show();  // showing loading
    var maxTime = 0;    // initializing loader timer

    // iterating through global route array.
    $.each(MOVED_VAN_ROUTES, function (index, route) {
        setTimeout(function () {
            drawPath(route.source, route.destination, route.routeId);   // drawing path
        }, ((index + 1) * 600));
        maxTime = (index + 1) * 600;   // increasing loader time
    });
    setTimeout(function () {
        $("#div_load").hide();  // hiding loading
    }, (maxTime + 500));
}

/**
* To manage drawing paths on map at a time interval
* @method drawPathManager
* @for PositioningTool
*/
function drawPathManager() {
    $("#div_load").show();   // showing loading
    var maxTime = 0;    // initializing loader timer

    // iterating through global route array.
    $.each(ROUTES, function (index, route) {
        setTimeout(function () {
            drawPath(route.source, route.destination, route.routeId);   // drawing path
        }, ((index + 1) * 600));
        maxTime = (index + 1) * 600;    // increasing loader time
    });
    setTimeout(function () {
        $("#div_load").hide();  // hiding loading
        // Fitting all the markers on map area present on screen
        map.fitBounds(latlngbounds);
    }, maxTime);
}


/**
* To put a marker on map with supplied information.
* @method putMarkerOnMap
* @param {Object} map map object
* @param {String} markerInfoWindowContent info-window html string
* @param {Object} markerLat marker's lat
* @param {Object} markerLong marker's long
* @param {Object} markerTitle marker's title
* @param {Object} markerId marker's id
* @param {Object} markerImage marker's icon image
* @param {Object} isDraggable true if marker is draggable
* @param {Object} setMapCenter true if marker click will center the map
* @param {Object} openInfoWindow true if info window should open
* @for PositioningTool
*/
function putMarkerOnMap(map, markerInfoWindowContent, markerLat, markerLong, markerTitle, markerId, markerImage, isDraggable, setMapCenter, openInfoWindow) {
    var markerLatlng = new google.maps.LatLng(markerLat, markerLong);   // creating marker's object
    var infowindow = new google.maps.InfoWindow({ content: markerInfoWindowContent });  // setting info window conent

    // craeting marker's object with proper info
    var marker = new google.maps.Marker({
        position: markerLatlng,
        map: map,
        title: markerTitle,
        icon: markerImage,
        draggable: isDraggable,
        id: markerId
    });
    // click handler for marker  when marker is cicked 
    google.maps.event.addListener(marker, 'click', function () {
        if (openInfoWindow) { infowindow.open(map, marker); }   // setting info window should open
        if (setMapCenter) { map.setCenter(markerLatlng); }  // setting center on map when marker is clicked
    });
    // dragend handler for marker when marker is dragged
    google.maps.event.addListener(marker, 'dragend', function () {
        // If moved marker is VAN-Reachable-Point
        if (marker.id.indexOf('_') >= 0) {
            // plotting polygon and path on drag of a marker
            dragEndHandlerForVanReachablePoint(marker);
        }
            // If moved marker is Van itself
        else {
            // plotting polygon and path on drag of a marker
            dragEndHandlerForVan(marker);
        }
    });
    MARKERS.push(marker);   // pushing marker into global marker array
    return marker;
}


/**
* To draw polygon on map with some lat-long
* @method drawPolygon
* @param {Array} polyCoordinates array of lat-long objects
* @param {String} polygonTitle polygon title
* @for PositioningTool
*/
function drawPolygon(polyCoordinates, polygonTitle) {
    // Construct the polygon.
    var polygon = new google.maps.Polygon({
        paths: polyCoordinates,
        strokeColor: '#AAA8A5',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#AAA8A5',
        fillOpacity: 0.35,
        title: polygonTitle
    });
    polygon.setMap(map);    // setting the polygon on map
    return polygon; // returing the creating polygon
}
////================== Draw / Put Objects on Map Section End ==============================


///============== Delete/Remove Objects From Map Section Start ==============================
/**
* To delete a route based on the id
* @method deleteRoute
* @param {String} routeId Id of route
* @for PositioningTool
*/
function deleteRoute(routeId) {
    var route = directionObj[routeId];
    if (typeof route !== 'undefined') {
        for (var i = 0; i < route.length; i++) {
            route[i].setMap(null);
        }
    }
}

/**
* To delete all routes from the map
* @method deleteAllRoutes
* @for PositioningTool
*/
function deleteAllRoutes() {
    $.each(MARKERS, function (index, marker) {
        if (marker.id.indexOf('_') >= 0) {
            deleteRoute(marker.id);
        }
    });
    directionObj = {};
}

/**
* To delete all markers from the map
* @method deleteMarkers
* @for PositioningTool
*/
function deleteMarkers() {
    for (var i = 0; i < MARKERS.length; i++) {
        MARKERS[i].setMap(null);
    }
    // Making the MARKERS-Array empty.
    MARKERS = [];
}

/**
* To delete all van reachbale points from the map
* @method bs_deleteAllVanReachablePoint
* @for PositioningTool
*/
function bs_deleteAllVanReachablePoint() {
    for (var i = 0; i < BS_VAN_REACHABLE_POINT.length; i++) {
        BS_VAN_REACHABLE_POINT[i].setMap(null);
    }
    // Making the MARKERS-Array empty.
    BS_VAN_REACHABLE_POINT = [];
}

/**
* To delete marker from the map based on the id
* @method deleteMarker
* @param {String} markerId id of marker
* @for PositioningTool
*/
function deleteMarker(markerId) {
    for (var i = 0; i < MARKERS.length; i++) {
        if (MARKERS[i].id == markerId) {
            MARKERS[i].setMap(null);
            MARKERS.splice(i, 1);
        }
    }
}

/**
* To delete all polygons from the map
* @method deleteAllPolygons
* @for PositioningTool
*/
function deleteAllPolygons() {
    for (var i = 0; i < POLYGONS.length; i++) {
        POLYGONS[i].setMap(null);
    }
    POLYGONS = [];
}

/**
* To delete polygon from the map based on the id
* @method deletePolygon
* @param {String} polygonId id of polygon
* @for PositioningTool
*/
function deletePolygon(polygonId) {
    for (var i = 0; i < POLYGONS.length; i++) {
        if (POLYGONS[i].title == polygonId) {
            POLYGONS[i].setMap(null);
            POLYGONS.splice(i, 1);
        }
    }
}

/**
* To delete polygon from the map based on the id (Blind Spot)
* @method bs_deletePolygon
* @param {String} polygonId id of polygon
* @for PositioningTool
*/
function bs_deletePolygon(polygonId) {
    for (var i = 0; i < BS_POLYGONS.length; i++) {
        if (BS_POLYGONS[i].title == polygonId) {
            BS_POLYGONS[i].setMap(null);
            BS_POLYGONS.splice(i, 1);
        }
    }
}

/**
* To delete all polygons from the map based on the id (Blind Spot)
* @method bs_deleteAllPolygons
* @for PositioningTool
*/
function bs_deleteAllPolygons() {
    for (var i = 0; i < BS_POLYGONS.length; i++) {
        BS_POLYGONS[i].setMap(null);
    }
    BS_POLYGONS = [];
}

/**
* To delete a route based on the id (Blind Spot)
* @method bs_deleteRoute
* @param {String} routeId Id of route
* @for PositioningTool
*/
function bs_deleteRoute(routeId) {
    var route = bs_directionObj[routeId];
    if (typeof route !== 'undefined') {
        for (var i = 0; i < route.length; i++) {
            route[i].setMap(null);
        }
    }
    bs_directionObj[routeId] = [];
}

/**
* To delete all routes from the map based on the id (Blind Spot)
* @method bs_deleteAllRoutes
* @for PositioningTool
*/
function bs_deleteAllRoutes() {
    $.each(BS_VAN_REACHABLE_POINT, function (index, marker) {
        bs_deleteRoute(marker.id);
    });
    bs_directionObj = {};
}
///============== Delete/Remove Objects From Map Section End ==============================



////=======================================================================
////================= MAIN Thread Start ===================================
/**
* To get all the Vans, place them on map, draw polygons and draw paths.
* @method getAllVansOnGeoView
* @for PositioningTool
*/
function getAllVansOnGeoView() {
    if (!StateValid()) { return; }    // If state is not selected, then no action.

    slaTimeInMin = $("#slaCombobox").data("kendoDropDownList").text();  // Getting curent SLA time and storing that globally
    $("#div_load").show();  // Showing Loading
    $('#get_van_coverage').show();  // Showing the get-van-coverage button
    $('#update_van_coverage').hide();   // Hiding update-van-coverage button
    $('#reset_van_coverage').hide();    // Hiding update-van-coverage button

    deleteAllRoutes();  // Deleting all the routes plotted on the map
    ROUTES = [];    // Making Routes array empty.
    MOVED_VAN_ROUTES = [];  // Making Moved-Van-Routes array empty.
    POSITIONING_JSON = [];  // Making the positioning json empty.
    UPDATED_POSITIONING_JSON = [];  // Making the UPDATED-POSITIONING-JSON empty.

    latlngbounds = new google.maps.LatLngBounds();  // Creating Lat-Long bounds instance to fit all the markers on the map

    // Getting the params which needs to be passed to the API
    SecurityToken = securityToken;
    utcMinutes = parseInt(UtcMinutes, 10);
    UserId = userId;
    var state = $("#stateCombobox").data("kendoComboBox").text(),
        //city = $("#cityCombobox").data("kendoComboBox").text(),
        //dealerId = $("#dealerCombobox").val(),
        slaId = $("#slaCombobox").val();

    //setMapCenterToAddress(city + ' ' + state);  // Set map cneter to selected address
    setMapCenterToAddress(state);  // Set map cneter to selected address

    $.ajax({
        type: "POST",
        url: WCFRESTURL.GetAllVansOnGeoView,
        data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId, State: state, City: '', DealerId: '', SlaId: slaId },
        dataType: "json",
        success: function (data) {
            POSITIONING_JSON = data;    // Storing the Van-Data globally.
            deleteMarkers();    // Removing all the markers from the map
            deleteAllPolygons();    // removing polygon from the map
            var polyCoordinates = [];   // to store the van reachable points to draw polygon

            $.each(data, function (index, van) {
                polyCoordinates = [];   // making the polygon store empty

                // Plotting Van
                var vanInfoWindow = '<div class=""><h2 class="EngName_heading">' + van.ServiceEngineerName + '</h2><table class="InfoWindowTbl" width="100%" cellpadding="0" cellspacing="0"><tbody><tr><td><span>Organization Name</span></td><td>' + van.OrganizationName + '</td><td><span>EOS Team Member</span></td><td>' + van.ServiceEngineerName + '</td><td><span>VAN Registration No.</span></td><td>' + van.VanRegistrationNo + '</td></tr><tr><td><span>Dealer City</span></td><td>' + van.DealerCity + '</td><td><span>Mobile No.</span></td><td>' + van.ServiceEngineerContactNo + '</td><td><span>VAN Model</span></td><td>' + van.VanModelName + '</td></tr></tbody></table></div></div>';
                var vanMarker = putMarkerOnMap(map, vanInfoWindow, van.VanDefaultLatitude, van.VanDefaultLongitude, van.ServiceEngineerName, van.VanId, vanImagePath, true, true, true)

                var sourceVan = new google.maps.LatLng(van.VanDefaultLatitude, van.VanDefaultLongitude);    // ceating van lat-long object
                latlngbounds.extend(sourceVan); // extending lat-long object

                // Plotting VAN's reachable points
                $.each(van.VanPostionList, function (index, point) {
                    // If lattitude is non null and non-empty then plotting starts
                    if ((point.VanPositionCoverageVanLatitude != '') && (point.VanPositionCoverageVanLatitude !== null)) {
                        var reachablePointId = point.VanPositionCoverageVanId + '_' + point.VanPositionCoverageId;
                        var vanPointInfoWindow = '<div>' + reachablePointId + '</div>';
                        putMarkerOnMap(map, vanPointInfoWindow, point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude, '', reachablePointId, vanReachablePointImagePath, true, false, false)

                        // Storing Point Cordinaates to draw a polygon
                        var reachablePoint = new google.maps.LatLng(point.VanPositionCoverageVanLatitude, point.VanPositionCoverageVanLongitude);
                        polyCoordinates.push(reachablePoint);

                        latlngbounds.extend(reachablePoint);    // extending lat-long object

                        // craeting Route Object and storing that globally.
                        var routeObj = new Object({ 'routeId': reachablePointId, 'source': sourceVan, 'destination': reachablePoint });
                        ROUTES.push(routeObj);
                    }
                });
                // Draw polygon and storing them globally
                var polygon = drawPolygon(polyCoordinates, van.VanId);
                POLYGONS.push(polygon);
            });
        },
        complete: function () {
            // Drawing path by sending route request effectively to Direction Service
            drawPathManager();
        },
        error: function (jqXHR, textStatus, errorThrown) {
        }
    });
}
////================= MAIN Thread End ===================================
////=====================================================================




//===============================================================================
//=========================== BLIND SPOT Start ===================================
/**
* To put a marker on map with supplied information. (Blind Spot)
* @method bs_putMarkerOnMap
* @param {Object} map map object
* @param {String} markerInfoWindowContent info-window html string
* @param {Object} markerLat marker's lat
* @param {Object} markerLong marker's long
* @param {Object} markerTitle marker's title
* @param {Object} markerId marker's id
* @param {Object} markerImage marker's icon image
* @param {Object} isDraggable true if marker is draggable
* @param {Object} setMapCenter true if marker click will center the map
* @param {Object} openInfoWindow true if info window should open
* @for PositioningTool
*/
function bs_putMarkerOnMap(map, markerInfoWindowContent, markerLat, markerLong, markerTitle, markerId, markerImage, isDraggable, setMapCenter, openInfoWindow) {
    var markerLatlng = new google.maps.LatLng(markerLat, markerLong);   // creating lat-long object
    var infowindow = new google.maps.InfoWindow({ content: markerInfoWindowContent });  // creating info-window object

    // creating marker object
    var marker = new google.maps.Marker({
        position: markerLatlng,
        map: map,
        title: markerTitle,
        icon: markerImage,
        draggable: isDraggable,
        id: markerId
    });

    // drag handler of marker
    google.maps.event.addListener(marker, 'dragend', function () {
        // if moved marker is van-reachable-point
        if (marker.id.indexOf('_') >= 0) {
            // plotting polygon and path on drag of a marker
            //dragendhandlerforvanreachablepoint(marker);
        }
            // if moved marker is van itself
        else {
            bs_deletePolygon(marker.id);    // Deleting the dragged Polygon
            BS_MOVED_VAN_ROUTES = [];   // Making the Moved-Van-Routes array empty.
            for (var index = 0; index < 12 ; index++) {
                var reachablePointId = vanId + '_' + index;
                // One by one deleting route associated to this Van
                bs_deleteRoute(reachablePointId);
                // One by one deleting VanReachable Points
                bs_deleteMarker(reachablePointId);
            }
            // plotting polygon and path on drag of a marker
            bs_generateVanCoverage(marker);
        }
    });
    return marker;
}



////============= Enable/Disable Tools ===================
/**
* To enable waypoint tool in blind spot toolbox
* @method enable_bs_waypoint_tool
* @for PositioningTool
*/
function enable_bs_waypoint_tool() {
    disable_map_click_Listener = false; // enabling the map click
    disable_map_click_Listener_waypoint = false;    // enabling map click of waypoint tool
    disable_map_mousemove_Listener_waypoint = false;    // enabling mouse move of waypoint tool on map

    $('#bs_waypoint').addClass('selected_tool');    // select the waypoint tool
    $('#bs_van').removeClass('selected_tool');  // deselect van tool

    disable_bs_van_tool();  // disabling the van tool
}

/**
* To disble waypoint tool in blind spot toolbox
* @method disable_bs_waypoint_tool
* @for PositioningTool
*/
function disable_bs_waypoint_tool() {
    disable_map_click_Listener_waypoint = true; // disabling map click of waypoint tool
    disable_map_mousemove_Listener_waypoint = true; // disabling mouse move of waypoint tool on map
}

/**
* To enable van tool in blind spot toolbox
* @method enable_bs_van_tool
* @for PositioningTool
*/
function enable_bs_van_tool() {
    disable_map_click_Listener = false; // enabling map click
    disable_map_mousemove_Listener_van = false; // enabling van tool when mouse is moved on map
    disable_map_click_Listener_van = false; // enabling van-tool click on map

    $('#bs_van').addClass('selected_tool'); // select the van tool
    $('#bs_waypoint').removeClass('selected_tool'); // deselect the wayoint tool

    deleteAllCircles(); // Deleting all the circles on map.
    disable_bs_waypoint_tool(); // disable the waypoint tool
}

/**
* To disble van tool in blind spot toolbox
* @method disable_bs_van_tool
* @for PositioningTool
*/
function disable_bs_van_tool() {
    disable_map_click_Listener_van = true;  // disabling map click of van tool
    disable_map_mousemove_Listener_van = true;  // disabling mouse move of van tool on map

}
//==========================================================

/**
* To draw path between two points and setting am routeId for the same. (Blind Spot)
* @method bs_drawPath
* @param {Object} sourcePoint source lat-long
* @param {Object} destinationPoint destination lat-long
* @param {Object} routeId route-id
* @for PositioningTool
*/
function bs_drawPath(sourcePoint, destinationPoint, routeId) {
    if (!bs_directionObj[routeId]) { bs_directionObj[routeId] = []; }   // Storing directions

    // creting renderer options to draw path on map
    var rendererOptions = {
        preserveViewport: true,
        suppressMarkers: true,
        polylineOptions: { strokeColor: "#1b3f94" }
    };
    directionsRenderer = new google.maps.DirectionsRenderer(rendererOptions);   // creating renderer object
    directionsRenderer.setMap(map); // setting it on map
    bs_directionObj[routeId].push(directionsRenderer);  // storing direction globally

    // craeting path request between two points
    var request = {
        origin: sourcePoint,
        destination: destinationPoint,
        travelMode: google.maps.TravelMode.DRIVING
    };
    // Route the directions and pass the response to a
    // function to create markers for each step.
    directionService.route(request, function (response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            directionsRenderer.setDirections(response);
        }
    });
}

/**
* To manage drawing paths on map at a time interval (Blind Spot)
* @method bs_drawPathManagerForMovedVan
* @for PositioningTool
*/
function bs_drawPathManagerForMovedVan() {
    $("#div_load").show();  // showing loading
    var maxTime = 0;    // intializing maximum time

    // iterating through global route array.
    $.each(BS_VAN_ROUTES, function (index, route) {
        setTimeout(function () { bs_drawPath(route.source, route.destination, route.routeId); }, ((index + 1) * 600));  // drawing path at an interval
        maxTime = (index + 1) * 600;    // inceasing loading time
    });
    setTimeout(function () {
        $("#div_load").hide();  // hiding loading
        // Fitting all the markers on map area present on screen
        //map.fitBounds(latlngbounds);
    }, (maxTime + 500));
}


/**
* To plot van at new position and draw its coverage and paths when there is No response from Google.
* @method bs_generateVanCoverageStatic
* @param {Object} marker van marker object on map
* @for PositioningTool
*/
function bs_generateVanCoverageStatic(marker) {
    //$("#div_load").show();  // showing loading
    var vanId = marker.id;  // getting van id
    //bs_enableCoverageDesign = true; // Enabling Coverage design
    ///bs_popTheVanOut = true; // enabling deleting the last van
    //BS_VAN_ROUTES = [];   // Making the Moved-Van-Routes array empty.

    var newLatOfVan = marker.position.lat();    // getting new lat of marker
    var newLongOfVan = marker.position.lng();   // getting new long of marker

    // Getting Van reachable points at a given radius
    var final_vanReachablePoints = bs_getCoverageForVanStatic(newLatOfVan, newLongOfVan, slaTimeInMin);

    bs_coverageDesiged = true;  // Coverage is designed once here
    //================== Design Coverage =====================
    var sourceVan = new google.maps.LatLng(newLatOfVan, newLongOfVan);  // craeting source van lat-long object
    var bs_polyCoordinates = [];    // takign polygon lat-long array
    // Plotting VAN's reachable points
    $.each(final_vanReachablePoints, function (index, point) {
        //if ((typeof point === 'undefined') || (bs_enableCoverageDesign == false)) {
        //    if (bs_popTheVanOut && BS_VAN_MARKERS.length > 0) {
        //        var currentVanMarker = BS_VAN_MARKERS[BS_VAN_MARKERS.length - 1];   // getting last van marker
        //        BS_VAN_MARKERS.pop();   // poping out last van from global array
        //        currentVanMarker.setMap(null);  // removing that from map
        //        bs_popTheVanOut = false;    // disabling poping the van out further
        //    }
        //    jAlert(POSITIONING_MSG['bs_put_van_error'], 'Message');

        //    $("#div_load").hide();  // hiding the loading
        //    return;
        //};

        var reachablePointId = vanId + '_' + index;
        var bs_point = bs_putMarkerOnMap(map, "", point.lat(), point.lng(), "", reachablePointId, vanReachablePointImagePath, false, false, false);
        BS_VAN_REACHABLE_POINT.push(bs_point);

        // Storing Point Cordinaates to draw a polygon
        var reachablePoint = new google.maps.LatLng(point.lat(), point.lng());
        bs_polyCoordinates.push(reachablePoint);

        // craeting Route Object and storing that globally.
        var routeObj = new Object({ 'routeId': reachablePointId, 'source': sourceVan, 'destination': reachablePoint });
        BS_ROUTES.push(routeObj);
        BS_VAN_ROUTES.push(routeObj);
    });
    // Draw polygon and storing them globally
    var polygon = drawPolygon(bs_polyCoordinates, vanId);
    BS_POLYGONS.push(polygon);

    // Drawing path for moved Van.
    bs_drawPathManagerForMovedVan();

    return;
    //================== Design Coverage =====================
}



/**
* To generate van coverage for a marker
* @method bs_generateVanCoverage
* @param {Object} marker marker object
* @for PositioningTool
*/
function bs_generateVanCoverage(marker) {
    $("#div_load").show();  // showing loading
    var vanId = marker.id;  // getting van id
    bs_enableCoverageDesign = true; // Enabling Coverage design
    bs_coverageDesiged = false; // No Coverage for now
    bs_popTheVanOut = true; // enabling deleting the last van
    BS_VAN_ROUTES = [];   // Making the Moved-Van-Routes array empty.

    var newLatOfVan = marker.position.lat();    // getting new lat of marker
    var newLongOfVan = marker.position.lng();   // getting new long of marker

    // Getting Van reachable points at a given radius
    var vanReachablePoints = bs_getCoverageForVan(newLatOfVan, newLongOfVan, slaTimeInMin);
    var vanReachablePoints1 = [];
    var vanReachablePoints2 = [];
    var mid = parseInt(vanReachablePoints.length / 2);
    for (var i = 0; i < mid ; i++) {
        vanReachablePoints1.push(vanReachablePoints[i])
        vanReachablePoints2.push(vanReachablePoints[mid + i]);
    }

    //----------------------
    var final_vanReachablePoints = [];
    //================== Design Coverage =====================
    // Getting optimal reachable points for first 0 to 180 degrees
    setTimeout(function () {
        var request1 = {
            origins: [marker.position],
            destinations: vanReachablePoints1,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }
        distanceMatrixService.getDistanceMatrix(request1, function (response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK) {
                var result = response.rows[0].elements;
                var start = 1;
                var counter = 0;
                // getting optimal points for 0 to 180 degrees
                for (var index = 0; index < result.length; index++) {
                    if ((bs_coverageDesiged == false) && (typeof result[index].duration === 'undefined')) {
                        //if (BS_VAN_MARKERS.length > 0) {
                        //    var currentVanMarker = BS_VAN_MARKERS[BS_VAN_MARKERS.length - 1];   // getting last van marker
                        //    BS_VAN_MARKERS.pop();   // poping out last van from global array
                        //    currentVanMarker.setMap(null);  // removing that from map
                        //    bs_popTheVanOut = false;    // disabling poping the van out further
                        //}
                        //jAlert(POSITIONING_MSG['bs_put_van_error'], 'Message');

                        bs_generateVanCoverageStatic(marker);
                        bs_enableCoverageDesign = false;    // disabling coverage design
                        bs_coverageDesiged = true;
                        //$("#div_load").hide();  // hiding loading
                        return;
                    };
                    var durationInMin = parseInt(result[index].duration.value / 60, 10);    // getting duration in minutes
                    counter++;
                    // getting optimal points for current SLA time
                    if ((durationInMin > (slaTimeInMin * bs_coverageMultiplier)) || (counter == 4)) {
                        ((index - 1) == -1) ? final_vanReachablePoints.push(vanReachablePoints1[index]) : final_vanReachablePoints.push(vanReachablePoints1[index - 1]);
                        index = start * 4;
                        start++;
                        counter = 0;
                    }
                }
            }
        });
    }, 300);

    //--------------------------------
    // Getting optimal reachable points for 180 to 360 degrees
    setTimeout(function () {
        //console.log(bs_coverageDesiged);
        if (bs_coverageDesiged) { return; }    // If coverage is designed once then exit the loop

        var request2 = {
            origins: [marker.position],
            destinations: vanReachablePoints2,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }
        distanceMatrixService.getDistanceMatrix(request2, function (response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK) {
                var result = response.rows[0].elements;
                var start = 1;
                var counter = 0;
                // getting optimal points
                for (var index = 0; index < result.length; index++) {
                    if ((typeof result[index].duration === 'undefined') && (bs_coverageDesiged == false)) {
                        //if (bs_popTheVanOut && BS_VAN_MARKERS.length > 0) {
                        //    var currentVanMarker = BS_VAN_MARKERS[BS_VAN_MARKERS.length - 1];   // getting last van marker
                        //    BS_VAN_MARKERS.pop();   // poping out last van from global array
                        //    currentVanMarker.setMap(null);  // removing that from map
                        //    bs_popTheVanOut = false;    // disabling poping the van out further
                        //}
                        //jAlert(POSITIONING_MSG['bs_put_van_error'], 'Message');

                        bs_generateVanCoverageStatic(marker);
                        //$("#div_load").hide();  // hiding loading
                        return;
                    };
                    var durationInMin = parseInt(result[index].duration.value / 60, 10);    // getting duration in minutes
                    counter++;
                    // getting optimal points for current SLA time
                    if ((durationInMin > (slaTimeInMin * bs_coverageMultiplier)) || (counter == 4)) {
                        ((index - 1) == -1) ? final_vanReachablePoints.push(vanReachablePoints2[index]) : final_vanReachablePoints.push(vanReachablePoints2[index - 1]);
                        index = start * 4;
                        start++;
                        counter = 0;
                    }
                }

                //--------------------Plotting van, its points and drawing paths and polygon------------------
                var sourceVan = new google.maps.LatLng(newLatOfVan, newLongOfVan);  // craeting source van lat-long object
                var bs_polyCoordinates = [];    // takign polygon lat-long array
                // Plotting VAN's reachable points
                $.each(final_vanReachablePoints, function (index, point) {
                    if ((typeof point === 'undefined') || (bs_enableCoverageDesign == false)) {
                        //if (bs_popTheVanOut && BS_VAN_MARKERS.length > 0) {
                        //    var currentVanMarker = BS_VAN_MARKERS[BS_VAN_MARKERS.length - 1];   // getting last van marker
                        //    BS_VAN_MARKERS.pop();   // poping out last van from global array
                        //    currentVanMarker.setMap(null);  // removing that from map
                        //    bs_popTheVanOut = false;    // disabling poping the van out further
                        //}
                        //jAlert(POSITIONING_MSG['bs_put_van_error'], 'Message');

                        //$("#div_load").hide();  // hiding the loading
                        return;
                    };

                    var reachablePointId = vanId + '_' + index;
                    var bs_point = bs_putMarkerOnMap(map, "", point.lat(), point.lng(), "", reachablePointId, vanReachablePointImagePath, false, false, false);
                    BS_VAN_REACHABLE_POINT.push(bs_point);

                    // Storing Point Cordinaates to draw a polygon
                    var reachablePoint = new google.maps.LatLng(point.lat(), point.lng());
                    bs_polyCoordinates.push(reachablePoint);

                    // craeting Route Object and storing that globally.
                    var routeObj = new Object({ 'routeId': reachablePointId, 'source': sourceVan, 'destination': reachablePoint });
                    BS_ROUTES.push(routeObj);
                    BS_VAN_ROUTES.push(routeObj);
                });
                // Draw polygon and storing them globally
                var polygon = drawPolygon(bs_polyCoordinates, vanId);
                BS_POLYGONS.push(polygon);

                // Drawing path for moved Van.
                bs_drawPathManagerForMovedVan();

                return;
                //------------------------------------------------------------------------------
            }
        });
    }, 1000);
    //================== Design Coverage =====================
}



/**
* To Calculate the blind spots on a path strech
* @method BlindSpotCalculator
* @param {Array} BS_waypoints Source to Destination waypoints
* @param {Array} BS_waypoints_reverse Destination to Source waypoints
* @param {Int} slaTimeInMin SLA Time in minutes
* @for PositioningTool
*/
function BlindSpotCalculator(BS_waypoints, BS_waypoints_reverse, slaTimeInMin) {
    var bs_waypoints = BS_waypoints;    // storing S-->D waypoints locally
    if (bs_waypoints.length == 0) {
        jAlert(POSITIONING_MSG['bs_no_waypoints'], 'Message');
        $("#div_load").hide();
        return;
    }
    var bs_waypoints_reverse = BS_waypoints_reverse;    // storing D-->S waypoints locally
    var request_from_last_point_origin = bs_waypoints_reverse[0];   // getting source point
    var request_from_first_point_origin = bs_waypoints[0];  // getting destination point
    bs_waypoints.shift();   // removing source points from waypoints
    bs_waypoints_reverse.shift();   // removing destination point from waypoints

    //================== S --> D =====================
    // Getting BlindSpots while traversing from source to destinations
    var request_from_first_point = {
        origins: [request_from_first_point_origin],
        destinations: bs_waypoints,
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.METRIC,
        avoidHighways: false,
        avoidTolls: false
    }
    distanceMatrixService.getDistanceMatrix(request_from_first_point, function (response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK) {
            var sd_result = response.rows[0].elements;
            var sd_startLatency = 0;
            var sd_active_slaTime = slaTimeInMin;
            var sd_setActiveSlaTime = false;

            // if duration id undefined then reset the blind spots and reset it
            if (typeof sd_result[sd_result.length - 1].duration === 'undefined') {
                jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
                resetBlindSpotGenerator();  // reset the blind spot geneartor
                $("#div_load").hide();  // hiding loading
                return;
            };
            // if duration is less tha SLA time then reset the blind spots and reset it
            if (parseInt(sd_result[sd_result.length - 1].duration.value / 60, 10) < slaTimeInMin) {
                jAlert(POSITIONING_MSG['bs_calculate_blind_spot_success'], 'Message');
                $("#div_load").hide();  // hiding loading
                enableBlindSpotGenerator = false;   // disabling blind spot generator
                return;
            }
            // getting Blind spots while traversing form source to destination
            for (var sd_index = 0; sd_index < sd_result.length; sd_index++) {
                // if duration id undefined the reset the blind spot generator
                if (typeof sd_result[sd_index].duration === 'undefined') {
                    jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
                    resetBlindSpotGenerator();  // reset the blind spot generator
                    $("#div_load").hide();  // hiding the loading
                    return;
                };
                // getting blind spots
                if ((parseInt(sd_result[sd_index].duration.value / 60, 10) - sd_startLatency) > sd_active_slaTime) {
                    // handling distributed placement of waypoints
                    if (sd_index == 0) {
                        jAlert(POSITIONING_MSG['bs_calculate_blind_spot_warning'], 'Message');
                        resetBlindSpotGenerator();  //reset the blind spot
                        $("#div_load").hide();  // hiding loading
                        return;
                    }
                    BS_ENDS.push(bs_waypoints[sd_index - 1]);   // storing the blind spots ends
                    sd_startLatency = parseInt(sd_result[sd_index - 1].duration.value / 60, 10);    // resetting the start latency 
                    // second time active sla time will be twice of the sla time
                    if (!sd_setActiveSlaTime) {
                        sd_active_slaTime = sd_active_slaTime * 2;
                        sd_setActiveSlaTime = true;
                    }
                    sd_index = sd_index - 1;
                }
            }
        }
        else {
            jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
            resetBlindSpotGenerator();  // reset the blind spot
            $("#div_load").hide();  // hiding loading
            return;
        }
    });
    //================== S --> D =====================

    //================== D --> S =====================
    // Getting BlindSpots while traversing from destinations to source
    setTimeout(function () {
        var request_from_last_point = {
            origins: [request_from_last_point_origin],
            destinations: bs_waypoints_reverse,
            travelMode: google.maps.TravelMode.DRIVING,
            unitSystem: google.maps.UnitSystem.METRIC,
            avoidHighways: false,
            avoidTolls: false
        }
        distanceMatrixService.getDistanceMatrix(request_from_last_point, function (response, status) {
            if (status == google.maps.DistanceMatrixStatus.OK) {
                var ds_result = response.rows[0].elements;
                var ds_startLatency = 0;
                var ds_active_slaTime = slaTimeInMin;
                var ds_setActiveSlaTime = false;

                // if duration id undefined then reset the blind spots and reset it
                if (typeof ds_result[ds_result.length - 1].duration === 'undefined') {
                    jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
                    resetBlindSpotGenerator();  // reset the blind spot geneartor
                    $("#div_load").hide();  // hiding loading
                    return;
                };
                // if duration is less tha SLA time then reset the blind spots and reset it
                if (parseInt(ds_result[ds_result.length - 1].duration.value / 60, 10) < slaTimeInMin) {
                    jAlert(POSITIONING_MSG['bs_calculate_blind_spot_success'], 'Message');
                    $("#div_load").hide();    // hiding loading
                    return;
                }
                // getting Blind spots while traversing form source to destination
                for (var ds_index = 0; ds_index < ds_result.length; ds_index++) {
                    // if duration id undefined then reset the blind spots and reset it
                    if (typeof ds_result[ds_index].duration === 'undefined') {
                        jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
                        resetBlindSpotGenerator();  // reset the blind spot geneartor
                        $("#div_load").hide();    // hiding loading
                        return;
                    };
                    // getting blind spots
                    if ((parseInt(ds_result[ds_index].duration.value / 60, 10) - ds_startLatency) > ds_active_slaTime) {
                        if (ds_index == 0) {
                            jAlert(POSITIONING_MSG['bs_calculate_blind_spot_warning'], 'Message');
                            resetBlindSpotGenerator();  // reset the blind spot geneartor
                            $("#div_load").hide();  // hiding loading
                            return;
                        }

                        BS_STARTS.unshift(bs_waypoints_reverse[ds_index - 1]);     // storing the blind spots starts
                        ds_startLatency = parseInt(ds_result[ds_index - 1].duration.value / 60, 10);   // resetting the start latency 
                        // second time active sla time will be twice of the sla time
                        if (!ds_setActiveSlaTime) {
                            ds_active_slaTime = ds_active_slaTime * 2;
                            ds_setActiveSlaTime = true;
                        }
                        ds_index = ds_index - 1;
                    }
                }

                //------------ Draw blindspot range now ---------------
                if (BS_ENDS.length == BS_STARTS.length) {
                    drawBlindSpotRegion(BS_STARTS, BS_ENDS);
                }
                else {
                    jAlert(POSITIONING_MSG['bs_calculate_blind_spot_warning'], 'Message');
                    resetBlindSpotGenerator();
                    $("#div_load").hide();
                    return;
                }
                //----------------------------------------------------
            }
            else {
                jAlert(POSITIONING_MSG['bs_calculate_blind_spot_error'], 'Message');
                resetBlindSpotGenerator();
                $("#div_load").hide();
                return;
            }
        });
    }, 1000);
    //================== D --> S =====================
}


/**
* To draw blind spots and their region
* @method drawBlindSpotRegion
* @param {Array} bs_starts blind spot start points
* @param {Array} bs_ends blind spot end points
* @for PositioningTool
*/
function drawBlindSpotRegion(bs_starts, bs_ends) {
    for (var index = 0; index < bs_starts.length; index++) {
        var points = [];    // Making points arrray.
        // pushing a set of positions to draw blind spots
        points.push(bs_starts[index]);
        points.push(bs_ends[index]);

        // Getting distance between two points
        var distance = google.maps.geometry.spherical.computeDistanceBetween(bs_starts[index], bs_ends[index]);
        var radius = parseInt(distance / 2, 10);
        var midpoint = getMidpoint(points, distance / 2);   // Getting midpoint of two points.
        var circle = drawCircle(midpoint, radius, ('circle_' + index)); // Drawing BlindSpot region
        BS_CIRCLES.push(circle);    // stroing blind spot circle globally
        // putting bouncing down arrow on the middle of blind spots
        var midMarker = new google.maps.Marker({
            map: map,
            draggable: false,
            animation: google.maps.Animation.DROP,
            position: midpoint,
            icon: bs_downArrowImagePath,
            id: "arrow_" + index
        });
        midMarker.setAnimation(google.maps.Animation.BOUNCE);
        BS_ARROW_MARKERS.push(midMarker);
    }
    $("#div_load").hide();
}


/**
* To generate blind spots  
* @method BlindSpotGenerator
* @for PositioningTool
*/
function BlindSpotGenerator() {
    if (enableBlindSpotGenerator) {
        $("#div_load").show();
        BlindSpotCalculator(BS_WAYPOINTS, BS_WAYPOINTS_reverse, slaTimeInMin);
        enableBlindSpotGenerator = false;
    } else {
        jAlert(POSITIONING_MSG['bs_reset_tools'], 'Message');
        $("#div_load").hide();
        return;
    }
}

/**
* To reset blind spots generator
* @method resetBlindSpotGenerator
* @for PositioningTool
*/
function resetBlindSpotGenerator() {
    deleteWaypoints();  // Deleting waypoints markers from the map.
    deleteVanMarkers(); // Deleting Van-Markers from the map.
    deleteArrowMarkers();   // Deleting Arrow-Markers from the map.
    deleteAllCircles(); // Deleting all the blind spot circles on map.
    bs_deleteAllRoutes();   // Deleting all the routes from the map
    bs_deleteAllPolygons(); // Deleting all the polygons
    bs_deleteAllVanReachablePoint();    // Deleting all van reachbale points

    $('#bs_van').removeClass('selected_tool');  // deselect the van tool
    $('#bs_waypoint').removeClass('selected_tool');  // deselect the waypoint tool

    // Re-Initializing all the global variables for BlindSpot.
    BS_WAYPOINDID = 0;
    BS_VAN_ID = 0;
    disable_map_click_Listener = true;
    disable_map_mousemove_Listener_waypoint = true;
    disable_map_click_Listener_waypoint = true;
    disable_map_click_Listener_van = true;
    disable_map_mousemove_Listener_van = true;
    enableBlindSpotGenerator = true;
    bs_enableCoverageDesign = true;
    bs_popTheVanOut = true;
    bs_coverageDesiged = false;

    BS_MARKERS = [];
    BS_WAYPOINTS = [];
    BS_WAYPOINTS_reverse = [];
    BS_ENDS = [];
    BS_STARTS = [];
    BS_CIRCLES = [];
    BS_MID_MARKERS = [];
    BS_ARROW_MARKERS = [];
    BS_VAN_REACHABLE_POINT = [];
    BS_ROUTES = [];
}


/**
* To delete all the waypoints from the map
* @method deleteWaypoints
* @for PositioningTool
*/
function deleteWaypoints() {
    for (var i = 0; i < BS_MARKERS.length; i++) {
        BS_MARKERS[i].setMap(null);
    }
    BS_MARKERS = [];    // Making the Global waypoint-Array empty.
}

/**
* To delete all the van markers from the map
* @method deleteVanMarkers
* @for PositioningTool
*/
function deleteVanMarkers() {
    for (var i = 0; i < BS_VAN_MARKERS.length; i++) {
        BS_VAN_MARKERS[i].setMap(null);
    }
    BS_VAN_MARKERS = [];    // Making the Global Van-Array empty.
}

/**
* To delete all the arrow markers from the map
* @method deleteArrowMarkers
* @for PositioningTool
*/
function deleteArrowMarkers() {
    for (var i = 0; i < BS_ARROW_MARKERS.length; i++) {
        BS_ARROW_MARKERS[i].setMap(null);
    }
    BS_ARROW_MARKERS = [];  // Making the Global arrow-Array empty.
}

/**
* To delete all the circles from the map
* @method deleteAllCircles
* @for PositioningTool
*/
function deleteAllCircles() {
    for (var i = 0; i < BS_CIRCLES.length; i++) {
        BS_CIRCLES[i].setMap(null);
    }
    BS_CIRCLES = []; // Making the global circle-Array empty.
}
//=========================== BLIND SPOT End ===================================
//==============================================================================


//===============================================================================
//===================== Google Map Initialization ===============================
/**
* To initialize the map and binding the event handlers
* @method initialize
* @for PositioningTool
*/
function initialize() {
    var myLatlng = new google.maps.LatLng(defaultLat, defaultLng);
    var mapOptions = {
        zoom: 7,
        center: myLatlng
    };
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

    //===========================Geo Analysis report =========================
    GA_openTicketMarkerArray = [];
    GA_closeTicketMarkerArray = [];

    GA_slaMeetMarkerArray = [];
    GA_slaNotMeetMarkerArray = [];
    // Set Mass By passing the Div Id
    GA_SetMap('map-canvas');
    /*Create a instance of OverlappingMarkerSpiderfier*/
    oms = new OverlappingMarkerSpiderfier(map,
      { markersWontMove: true, markersWontHide: true });

    //Put Marker On Map
    GA_PutMarker(GA_ArrOpenTicket, GA_OpenTicketMarker, false);
    GA_PutMarker(GA_ArrCloseTicket, GA_CloseTicketMarker, false);

    var vTempMarkerCluster = GA_slaMeetMarkerArray.concat(GA_slaNotMeetMarkerArray);
    masterClusterInstance = new MarkerClusterer(map, vTempMarkerCluster, { maxZoom: 9 });
    //===========================Geo Analysis report End=========================


    //Initialize the Direction Service
    directionService = new google.maps.DirectionsService();
    // Creating an instance of Google Distance Matrix
    distanceMatrixService = new google.maps.DistanceMatrixService();

    //================ Blind Spot Section =========================
    google.maps.event.addListener(map, 'click', function (event) {
        if (disable_map_click_Listener) {
            return;
        }
        // if Waypoint is click on Map
        if (!disable_map_click_Listener_waypoint) {
            if (enableBlindSpotGenerator) {
                if (BS_MARKERS.length >= 25) {
                    jAlert(POSITIONING_MSG['bs_waypoints_limit'], 'Message');
                    $("#div_load").hide();
                    return;
                }
                else {
                    var bs_waypointId = 'bs_' + BS_WAYPOINDID;
                    var waypoint_marker = bs_putMarkerOnMap(map, "", event.latLng.lat(), event.latLng.lng(), '', bs_waypointId, bs_waypointImagePath, false, false, false);
                    BS_WAYPOINDID++;
                    BS_MARKERS.push(waypoint_marker);
                    BS_WAYPOINTS.push(event.latLng);
                    BS_WAYPOINTS_reverse.unshift(event.latLng);
                }
            }
            else {
                jAlert(POSITIONING_MSG['bs_reset_tools'], 'Message');
                $("#div_load").hide();
                return;
            }
        }
        // if VAN is click on Map
        if (!disable_map_click_Listener_van) {
            var bs_vanId = 'bsVan' + BS_VAN_ID;
            //pankaj working here: draw polygon and paths
            var van_marker = bs_putMarkerOnMap(map, "", event.latLng.lat(), event.latLng.lng(), '', bs_vanId, bs_vanImagePath, false, false, false);
            BS_VAN_MARKERS.push(van_marker);
            BS_VAN_ID++;
            bs_generateVanCoverage(van_marker);
        }
    });
    google.maps.event.addListener(map, 'mousemove', function (event) {
        if (disable_map_mousemove_Listener_waypoint && disable_map_mousemove_Listener_van) {
            map.setOptions({ draggableCursor: '' });
        }
        if (!disable_map_mousemove_Listener_waypoint) {
            map.setOptions({ draggableCursor: "url(" + bs_waypointToolImagePath + "), auto" })
        }
        if (!disable_map_mousemove_Listener_van) {
            map.setOptions({ draggableCursor: "url(" + bs_vanToolImagePath + "), auto" })
        }
    });
    //============================================================
}
//===============================================================================
//===============================================================================




$(document).ready(function () {
    $("#div_load").hide();  // hiding loading
    $('#get_van_coverage').show()   // Showing the get-van-coverage button
    $('#update_van_coverage').hide();   // Hiding update-van-coverage button
    $('#reset_van_coverage').hide();    // Hiding update-van-coverage button

    loadAllSla();   // populating SLA combobox
    loadStateChoices();    // populating state combobox
    //loadCityChoices($("#stateCombobox").val());   // populating city combobox
    //loadDealerChoices($("#stateCombobox").val(), $("#cityCombobox").val());   // populating dealer combobox
});

// Window is ready with all its resources, then load the Google-Map.
google.maps.event.addDomListener(window, 'load', initialize);