﻿var IsRecenteringEnabled = false;
var IsMonitoringEnabled = false;
var CheckResize = false;
var SelectMarker = null;
//var IsResizeForReports = false; 
// A MapModeControl is a GControl that displays checkboxes with map mode centering

function IsRecentering(){
    return IsRecenteringEnabled;
}
function IsMonitoring(){
    return IsMonitoringEnabled;
}
//map zone control
function MapZoneControl() {
}

MapZoneControl.prototype = new GControl();
var imgExpand = "../resources/PlusL.bmp", imgCollapse = "../resources/MinusL.bmp";
MapZoneControl.prototype.initialize = function(map) {
    var container = document.createElement("div");
    container.style.backgroundColor = "#001D44";
    container.style.filter = "alpha(opacity = 70)";
    container.style.width = "80px";
    container.style.height = "25px";

    //zones
    var ShowZoneCB = document.createElement("input");
    ShowZoneCB.type = "image";
    ShowZoneCB.id = "ShowZomeMode";
    ShowZoneCB.name = "ShowZomeMode";
    ShowZoneCB.expanded = false;
    ShowZoneCB.src = ShowZoneCB.expanded ? imgCollapse : imgExpand;
    ShowZoneCB.width = 14;
    ShowZoneCB.height = 14;
    ShowZoneCB.style.marginTop = "4px";
    ShowZoneCB.style.marginLeft = "4px";
    ShowZoneCB.style.marginRight = "4px";
    ShowZoneCB.listCtrl = new ZoneListControl();
    container.appendChild(ShowZoneCB);
    this.getListCtrl = function() {
        return ShowZoneCB.listCtrl;
    }

    GEvent.addDomListener(ShowZoneCB, "click", function(e) {
        this.expanded = !this.expanded;
        this.src = this.expanded ? imgCollapse : imgExpand;
        if (this.expanded) {
            this.listCtrl.container.innerHTML = GetZoneList();
        }
        else
            this.listCtrl.container.innerHTML = "";
        this.listCtrl.container.style.zIndex = 20000;
        this.listCtrl.container.style.display = 'block';
        if (e && e.preventDefault) e.preventDefault();
        return false;
    });

    var showZoneCaptionLbl = document.createElement("span");
    this.setSpanStyle_(showZoneCaptionLbl);
    showZoneCaptionLbl.innerHTML = showZoneCaption;
    container.appendChild(showZoneCaptionLbl);

    map.getContainer().appendChild(container);
    return container;
}

MapZoneControl.prototype.setSpanStyle_ = function(span) {
    span.style.color = "white";
    span.style.font = "12px Verdana, MS Sans Serif, Arial Black ";
}

//zone list control
function ZoneListControl() {
    this.container = document.createElement("div");
    this.container.style.background = "#B3C8DB";
    this.container.style.filter="alpha(opacity =80)";
}

ZoneListControl.prototype = new GControl();

ZoneListControl.prototype.initialize = function (map) {
    map.getContainer().appendChild(this.container);
    return this.container;
}


function MapModeControl() {
}

// To "subclass" the GControl, we set the prototype object to an instance of the GControl object
MapModeControl.prototype = new GControl();
MapModeControl.prototype.initialize = function(map) {
    var container = document.createElement("div");
    container.style.backgroundColor = "#001D44";
    container.style.filter = "alpha(opacity = 70)";
    container.style.width = "140px";
    container.style.height = "25px";

//    var CenterModeCB = document.createElement("input");
//    CenterModeCB.type = "checkbox";
//    CenterModeCB.id = "CenterMode";
//    CenterModeCB.name = "CenterMode";
//    container.appendChild(CenterModeCB);
//    CenterModeCB.checked = IsRecenteringEnabled;

//    var centerModeCaptionLbl = document.createElement("span");
//    this.setSpanStyle_(centerModeCaptionLbl);
//    centerModeCaptionLbl.innerHTML = centerModeCaption;
//    container.appendChild(centerModeCaptionLbl);


//    GEvent.addDomListener(CenterModeCB, "click", function() {
//        IsRecenteringEnabled = !IsRecenteringEnabled;
//        if (IsRecenteringEnabled == true) {
//            IsMonitoringEnabled = false;
//            FollowModeCB.checked = IsMonitoringEnabled;
//        }

//        LockeyApplication.Map.MapService.MarkSelectedCar(fGetGoogleObjectOptimized);
//    });


    var FollowModeCB = document.createElement("input");
    FollowModeCB.type = "checkbox";
    FollowModeCB.id = "FollowMode";
    FollowModeCB.name = "FollowMode";
    container.appendChild(FollowModeCB);
    FollowModeCB.checked = IsMonitoringEnabled;

    var followModeCaptionLbl = document.createElement("span");
    this.setSpanStyle_(followModeCaptionLbl);
    followModeCaptionLbl.innerHTML = followModeCaption;
    container.appendChild(followModeCaptionLbl);


    GEvent.addDomListener(FollowModeCB, "click", function() {
        IsMonitoringEnabled = !IsMonitoringEnabled;
//        if (IsMonitoringEnabled == true) {
//            IsRecenteringEnabled = false;
//            CenterModeCB.checked = IsRecenteringEnabled;
//        }
       
        LockeyApplication.Map.MapService.MarkSelectedCar(fGetGoogleObjectOptimized);
    });
  

    map.getContainer().appendChild(container);
    return container;
}
MapModeControl.prototype.setSpanStyle_ = function(span) {
    span.style.color = "white";
    span.style.font = "12px Verdana, MS Sans Serif, Arial Black ";
}

var map;
var trafficInfo = null;
var maptype = "Google";
function fMarkers()
{
    this.ms = new Array();
    this.getLength = function () { this.ms.length; };
    this.pushValue = function (v) { this.ms.push(v); };
    this.getValue = function (i) { return this.ms[i]; };
    this.getLastValue = function () { return this.ms[this.ms.length - 1]; };
    this.getValueById = function (ID) {
        for (var i = 0; i < this.ms.length; i++)
            if (this.ms[i].value == ID)
                return this.ms[i];
        return null;
    };
    this.removeValueById = function (ID) {
        for (var i = 0; i < this.ms.length; i++)
            if (this.ms[i].value == ID)
                this.ms.splice(i, 1);
        return null;
    };
}

function fPolylines()
{
    this.polylines = new Array();
    this.polylinesID = new Array();
    this.getLength = function() { return this.polylines.length; };
    this.pushValue = function(v,ID) {  this.polylines.push(v); this.polylinesID.push(ID); }
    this.getValue = function(i) { return this.polylines[i]; }
    this.getIDValue = function(i) { return this.polylinesID[i]; }
    this.getLastValue = function()  { return this.polylines[this.polylines.length-1]; }
    this.getValueById = function(ID)  {var i;
                for(i=0;i<this.polylinesID.length;i++){
                    if(this.polylinesID[i]==ID){
                        return this.polylines[i];
                    }
                }
                return null;
              }
     this.removeValueById = function(ID) {var i;
                for(i=0;i<this.polylinesID.length;i++){
                    if(this.polylinesID[i]==ID){
                        this.polylines.splice(i,1);
                        this.polylinesID.splice(i,1);
                    }
                }
                return null;
            }
    /*-----extension Distance method for polyline--------*/
    this.Distance = function () {
        var dist = 0;
        for (var i = 1; i < this.getVertexCount(); i++) {
            dist += this.getVertex(i).distanceFrom(this.getVertex(i - 1));
        }
        return dist;
    }
    /*---- ~ Distance method for polyline---------------*/
}

function fPolygons(){
    this.polygons = new Array();
    this.getLength = function() { return this.polygons.length; };
    this.pushValue = function(v, ID, title) {
        var i, done = false;
        v.ID = ID; v.Title = title;
        for (i = 0; i < this.polygons.length; i++)
            if (this.polygons[i].ID == ID && this.polygons[i].Title == title) {
            done = true;
            break;
        }
        if (!done) this.polygons.push(v);
    }
    this.getValue = function(i) { return this.polygons[i]; }
    this.getTitle = function(i) { return this.polygons[i].Title; }
    this.getIDValue = function(i) { return this.polygons[i].ID; }
    this.getLastValue = function() { return this.polygons[this.polygons.length - 1]; }
    this.setVisible = function (i, val){this.polygons[i].IsVisible = val;}
    this.getValueById = function(ID)  {var i;
        for(i=0;i<this.polygons.length;i++)
            if(this.polygons[i].ID==ID)
                return this.polygons[i];
        return null;
      }
    this.getTitleById = function(ID) {
          var i;
          for (i = 0; i < this.polygonsID.length; i++)
              if (this.polygons[i].ID == ID)
                  return this.polygons[i].Title;
          return null;
      }
      this.removeValueById = function(ID) {
          var i;
          for (i = 0; i < this.polygons.length; i++)
              if (this.polygons[i].ID == ID) {
              this.polygons.splice(i, 1);
              break;
          }
          return null;
      }
}


var markers = null;
var polylines = null;
var polygons = null;
var mapzones = null;
var mapzoneObjects = null;

if (GBrowserIsCompatible()) {

markers = new fMarkers();
polylines = new fPolylines();
polygons = new fPolygons();
mapzones = new fPolygons();
mapzoneObjects = new Object();

function importanceOrder(marker, b) {
    marker.importance = 0;
        return GOverlay.getZIndex() + marker.importance*1000000;
      }

function CreateMarker(point,icon1,InfoHTML,bDraggable,sTitle, sToolTip, id, isClickable, zorder) {
    if (bDraggable) {
        var marker = new GMarker(point, { icon: icon1, draggable: true, title: sTitle });

        if (InfoHTML != '') {
            GEvent.addListener(marker, "click", function() { this.openInfoWindowHtml(InfoHTML); });
        }

        GEvent.addListener(marker, "dblclick", dblClick);
        GEvent.addListener(marker, "dragend", dragEnd);
        return marker;
    }
    else {
        var marker;
        if (zorder >1)
            marker = new LabeledMarker(point, { icon: icon1, draggable: false, title: sTitle, labelText: sToolTip, clickable: isClickable, zIndexProcess: importanceOrder });
        else
            marker = new LabeledMarker(point, { icon: icon1, draggable: false, title: sTitle, labelText: sToolTip, clickable: isClickable });
        if (isClickable)
            GEvent.addListener(marker, "click", marker.clickHandler);
        return marker;
    }
}
function dblClick() { RaiseEvent('PushpinDblClicked', this.value); }
function dragEnd() {
    LockeyApplication.Map.MapService.SetLatLon(this.value, this.getLatLng().y, this.getLatLng().x);
    RaiseEvent('PushpinMoved', this.value);
}

function OpenInfoWindow(id,InfoHTML){
    var marker = markers.getValueById(id);
    if(marker!=null){
        marker.openInfoWindowHtml(InfoHTML);
    }
}

function CreatePolyline(points,color,width,opacity,isgeodesic){
    var polyline;
    if (!isgeodesic) {
        polyline = new ArrowedPolyline(points, color, width, opacity, 1, 14, color, width, opacity);
    }
    else {
       polyline = new GPolyline(points,color,width , opacity,{geodesic:true});      
    }
    return polyline;
}
//Polyline with arows
function ArrowedPolyline(points, color, weight, opacity, opts, headLength, headColor, headWeight, headOpacity) {
    this.points = points;
    this.color = color;
    this.weight = weight;
    this.opacity = opacity;
    this.headLength = headLength;    //arrow length
    this.headColor = headColor;      //arrow color
    this.headWeight = headWeight;    //arrow width
    this.headOpacity = headOpacity;  //arrow opacity
    this.opts = opts;
    this.heads = new Array();
    this.line = null;
    this.isShown = false;
    
}
ArrowedPolyline.prototype = new GOverlay();

ArrowedPolyline.prototype.initialize = function(map) {
    this.line = new GPolyline(this.points, this.color, this.weight, this.opacity);
    map.addOverlay(this.line);
    this.prj = map.getCurrentMapType().getProjection();
}

ArrowedPolyline.prototype.remove = function() {
    map.removeOverlay(this.line);
    for (var i = 0; i < this.heads.length; i++)
        map.removeOverlay(this.heads[i]);
    this.isShown = false;        
}

ArrowedPolyline.prototype.removeArrows = function() {
   try {
        for (var i = 0; i < this.heads.length; i++)
            map.removeOverlay(this.heads[i]);
        this.isShown = false;                    
    }
    catch (ex) {
    }
}

ArrowedPolyline.prototype.redraw = function(force) {
    if (!force) return;
    if (this.isShown == true) {
        this.removeArrows();
    }
    this.makeArrows();
    for (var i = 0; i < this.heads.length; i++)
        map.addOverlay(this.heads[i]);
    this.isShown = true;
}

ArrowedPolyline.prototype.copy = function(map) {
    return new ArrowedPolyline(this.points, this.color, this.weight, this.opacity, this.opts, this.headLength, this.headColor, this.headWeight, this.headOpacity);
}

ArrowedPolyline.prototype.makeArrows = function() {
    var zoom = map.getZoom();
    // the arrow heads
    this.heads = new Array();

    var p1 = this.prj.fromLatLngToPixel(this.points[0], zoom);//first point
    var p2; //next point
    var dx, dy;
    var sl; //segment length
    var theta; //segment angle

    for (var i = 1; i < this.points.length; i++) {

        p2 = this.prj.fromLatLngToPixel(this.points[i], zoom)
        dx = p2.x - p1.x;
        dy = p2.y - p1.y;

        sl = Math.sqrt((dx * dx) + (dy * dy));
        if (sl / 3 > this.headLength) {
            if (Math.abs(this.points[i - 1].lng() - this.points[i].lng()) > 180.0)
                dx = -dx;
            theta = Math.atan2(-dy, dx);
            this.makeHead(p1.x + ((sl / 2) * Math.cos(theta)), p1.y - ((sl / 2) * Math.sin(theta)), theta, zoom);
            //this.makeHead(p1.x + dx/2), p1.y - (dy/2), theta, zoom);
            //this.makeHead(p1.x + dx / 2, p1.y - dy / 2, Math.atan2(-dy, dx), zoom);
        }
        p1 = p2;
    }
}
ArrowedPolyline.prototype.makeHead = function(x, y, theta, zoom) {
    //add an arrow head at the specified point
    var t = theta + (Math.PI / 10);
    if (t > Math.PI)
        t -= 2 * Math.PI;
    var t2 = theta - (Math.PI / 10);
    if (t2 <= (-Math.PI))
        t2 += 2 * Math.PI;
    var pts = new Array();
    pts.push(this.prj.fromPixelToLatLng(new GPoint(x - Math.cos(t) * this.headLength, y + Math.sin(t) * this.headLength), zoom));
    pts.push(this.prj.fromPixelToLatLng(new GPoint(x, y), zoom));
    pts.push(this.prj.fromPixelToLatLng(new GPoint(x - Math.cos(t2) * this.headLength, y + Math.sin(t2) * this.headLength), zoom));
    this.heads.push(new GPolyline(pts, this.headColor, this.headWeight, this.headOpacity, this.opts));
}
/*---Extension Method for distance------------*/
ArrowedPolyline.prototype.Distance = function () {
    
        var dist = 0;
        var p1, p2;
        var dx, dy;
        var zoom = map.getZoom();
        p1 = this.prj.fromLatLngToPixel(this.points[0], zoom); //start point
        for (var i = 1; i < this.points.length; i++) {

            p2 = this.prj.fromLatLngToPixel(this.points[i], zoom)
            // dist += this.points[i].distanceFrom(this.points[i - 1]);
            dist += p2.distanceFromPoint(p1);
            p1 = p2;
        } 
        
        return dist;
   
}
GPoint.prototype.distanceFromPoint= function (point){
var dx,dy;
dx= this.x-point.x;
dy=this.y-point.y;
return Math.sqrt((dx * dx) + (dy * dy));
}

ArrowedPolyline.prototype.GetPointAtDistance = function (metres) {

    // some awkward special cases
    if (metres == 0) return this.points[0];
    if (metres < 0) return null;
    var zoom = map.getZoom();
    var dist = 0;
    var olddist = 0;
    var pt1, pt2;
    
    for (var i = 1; (i < this.points.length && dist < metres); i++) {
        olddist = dist;
        pt1 = this.prj.fromLatLngToPixel(this.points[i - 1],zoom);
        pt2 = this.prj.fromLatLngToPixel(this.points[i],zoom);
        dist += pt2.distanceFromPoint(pt1);
        pt1 = pt2;
    }
    if (dist < metres) { return null; }
    var p1 = this.points[i - 2];
    var p2 = this.points[i - 1];
    var m = (metres - olddist) / (dist - olddist);
    return new GLatLng(p1.lat() + (p2.lat() - p1.lat()) * m, p1.lng() + (p2.lng() - p1.lng()) * m);

}



/*---Extension Method for distance------------*/
function CreatePolygon(points,strokecolor,strokeweight,strokeopacity,fillcolor,fillopacity){
    return new GPolygon(points, strokecolor, strokeweight, strokeopacity, fillcolor, fillopacity);
}

var MapZoneControlObj = new MapZoneControl();



function fGetGoogleObject(result, userContext) {
    map.setCenter(new GLatLng(result.CenterPoint.Latitude, result.CenterPoint.Longitude), result.ZoomLevel);
    map.addControl(new GScaleControl());

    if (result.ShowMapModeControl) {
        map.addControl(new MapModeControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(90, 7)));
    }
    if (result.ShowZoneControl) {
        SetZoneControlVisibility(true);
    }

    if(result.ShowMapTypesControl){
        map.addControl(new GMapTypeControl());
    }

    if(result.ShowZoomControl){
        map.addControl(new GLargeMapControl());
    }
        
    map.setMapType(eval(result.MapType));
    
    var i;
    if(markers!=null){
        for(i=0;i<markers.getLength();i++){
            var cmark = markers.getValue(i);
            if(cmark !=null){
                    map.removeOverlay(cmark);
            }
        }
    }

    var ps = result.Points;
    for (i = 0; i < ps.length; i++) {
        var myIcon_google, p = ps[i];

        var myPoint = new GLatLng(p.Latitude, p.Longitude);
        
        myIcon_google = null;
        if(p.IconImage!=''){
            myIcon_google = new GIcon(G_DEFAULT_ICON);
            
            myIcon_google.iconSize = new GSize(p.IconImageWidth,p.IconImageHeight);
            myIcon_google.image = p.IconImage;
            myIcon_google.shadow = p.IconShadowImage;
            myIcon_google.shadowSize = new GSize(p.IconShadowWidth, p.IconShadowHeight);
            myIcon_google.iconAnchor =  new GPoint(p.IconAnchor_posX, p.IconAnchor_posY);
            myIcon_google.infoWindowAnchor = new GPoint(p.InfoWindowAnchor_posX, p.InfoWindowAnchor_posY);
        }

        var marker = CreateMarker(myPoint, myIcon_google, p.InfoHTML, p.Draggable, p.Title, p.ToolTip, p.ID, p.IsClickable, 0);
        marker.value = p.ID;
        markers.pushValue(marker);
        map.addOverlay(markers.getLastValue());
    }
    //Add polylines
    polylines = new fPolylines();
    var pls = result.Polylines;
    for (i = 0; i < pls.length; i++) {
        var pl = pls[i], ps = Polylines[i].Points;
        var polypoints = new Array(ps.length);
        var j;
        for (j = 0; j < ps.length; j++) {
            var p = ps[j]; 
            polypoints[j] = new GLatLng(p.Latitude, p.Longitude);
        }
        var polyline = CreatePolyline(polypoints,pl.ColorCode,pl.Width,pl.Opacity,pl.Geodesic);
        polylines.pushValue(polyline,pl.ID);
        map.addOverlay(polylines.getLastValue());
    }
    polygons = new fPolygons();
    var pgs = result.Polygons;
    for (i = 0; i < result.Polygons.length; i++) {
        var polypoints = new Array(result.Polygons[i].Points.length);
	    var j, pg = pgs[i];
	    for (j = 0; j < pg.Points.length; j++) {
	       var p = pg.Points[j];
	 	   polypoints[j] = new GLatLng(p.Latitude, p.Longitude);
	    }
	    var polygon = CreatePolygon(polypoints, pg.StrokeColor, pg.StrokeWeight, pg.StrokeOpacity, pg.FillColor, pg.FillOpacity);
	    if (pg.IsVisible == false) {
	        mapzones.pushValue(polygon, pg.ID, pg.Title);
	    }
	    else {
	        polygons.pushValue(polygon, pg.ID);
	        map.addOverlay(polygons.getLastValue());
	    }
        if (pg.IsEditable == true) {
            polygon.enableEditing();
        }
    }
    if(result.ShowTraffic){
        trafficInfo = new GTrafficOverlay();
        map.addOverlay(trafficInfo);
    }
    if (IsMonitoringEnabled) {
         RecenterAndZoom(IsMonitoringEnabled, result);

     }
//     if (IsResizeForReports == true && IsMonitoringEnabled == false) {
//         RecenterAndZoom(IsResizeForReports, result);
//     }
    
}

function moveEnd() {
    var centerMap = map.getCenter();
    var centerAndZoom = centerMap.lat() + ";" + centerMap.lng() + ";" + map.getZoom()
    RaiseEvent('MapMoved', centerAndZoom);
}

function addMoveEndEvent() {
    GEvent.addListener(map, "moveend", moveEnd);
}

var mapZoom;
var mapCenterLat;
var mapCenterLng;

function ReSizeMap() {
    map.checkResize();
}

function DrawMapControl() {
    if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("Map_Div"));
        GEvent.addListener(map, "load", function () { if (typeof (ongMapLoad) == 'function') ongMapLoad(); });
        map.onmoveend = null;
        GEvent.addListener(map, "moveend", function() {
            mapZoom = map.getZoom();
            SetZoomLevel(mapZoom);
            var centerMap = map.getCenter();
            mapCenterLat = centerMap.lat();
            mapCenterLng = centerMap.lng();
            SetCenter(mapCenterLat, mapCenterLng);
        });
        GEvent.addListener(map, "zoomend", function(zOld, zNew) {
            SetZoomLevel(zNew);
        });

        geocoder = new GClientGeocoder();
        map.enableScrollWheelZoom();

        LockeyApplication.Map.MapService.GetMapObject(fGetGoogleObject);
    }
}

var SingleMarkerOverlay = null;
function DrawMarker(lat, lng) {

    if (SingleMarkerOverlay != null)
        map.removeOverlay(SingleMarkerOverlay);

    var iconWidth = 13;
    var iconHeight = 28;
    var myPoint = new GLatLng(lat, lng);
    var myIcon_google = new GIcon(G_DEFAULT_ICON);
    myIcon_google.iconSize = new GSize(iconWidth, iconHeight);
    myIcon_google.image = "../Map/resources/red_pointer.gif";
    SingleMarkerOverlay = new GMarker(myPoint, { icon: myIcon_google });

    map.addOverlay(SingleMarkerOverlay);
    map.setCenter(myPoint, 12);
}

function RemoveMarker() {
    if (SingleMarkerOverlay != null)
        map.removeOverlay(SingleMarkerOverlay);
}
var selected = null;
function KeepSelected(id) { selected = id;}
function AddMarker(car) {
    var m = markers.getValueById(car.ID);
    if (m == null) {
        var myIcon_google = null;
        myIcon_google = new GIcon(G_DEFAULT_ICON);
        myIcon_google.shadow = null;
        myIcon_google.iconSize = new GSize(16, 24);

        var m = CreateMarker(new GLatLng(car.Lat, car.Lon), myIcon_google, '', false, car.Name, car.LicenseID, car.ID, false,0);
        m.value = car.ID;
        markers.pushValue(m);
        map.addOverlay(m);
    }
}

function RemoveMarker(id) {
    var m = markers.getValueById(id);
    if (m != null) {
        markers.removeValueById(id);
        map.removeOverlay(m);
    }
}



function fGetGoogleObjectOptimized(result, userContext) {
    if (CheckResize) {
        ReSizeMap();
        CheckResize = false;
    }
    if (map.getSize().width == 0)
        CheckResize = true;
        
    var selectedCarPosition = new GLatLng(0, 0);
    var IsCarSelected = false;
    if (result.RecenterMap) {
        mapZoom = result.ZoomLevel;
        map.setCenter(new GLatLng(result.CenterPoint.Latitude, result.CenterPoint.Longitude), result.ZoomLevel);
        LockeyApplication.Map.MapService.RecenterMapComplete();
    }
    
    map.setMapType(eval(result.MapType));

    if(result.ShowTraffic){
        trafficInfo = new GTrafficOverlay();
        map.addOverlay(trafficInfo);
    }
    else{
        if(trafficInfo!=null){
            map.removeOverlay(trafficInfo);
            trafficInfo = null;
        }
    }

    var i, points = result.Points;
    for (i = 0; i < points.length; i++) {
        var p = points[i];
        if (p.Selected == true) {
            selectedCarPosition = new GLatLng(p.Latitude, p.Longitude);
            IsCarSelected = true;
        }
        //Create icon
        var myIcon_google;
        var myPoint = new GLatLng(p.Latitude, p.Longitude);
        
        //Existing marker, but changed.
        if (p.PointStatus == 'C') {
            var marker = markers.getValueById(p.ID);

            if (p.Selected == true && marker != null) {
                markers.removeValueById(p.ID);
                map.removeOverlay(marker);
                marker = null;
            }
                   
            if (marker != null) {
                marker.setLatLng(myPoint);
                marker.setImage(p.IconImage);
            }
            else {
                myIcon_google = null;
                if (p.IconImage != '') {
                    myIcon_google = new GIcon(G_DEFAULT_ICON);

                    myIcon_google.iconSize = new GSize(p.IconImageWidth, p.IconImageHeight);
                    myIcon_google.image = p.IconImage;
                    myIcon_google.shadow = p.IconShadowImage;
                    myIcon_google.shadowSize = new GSize(p.IconShadowWidth, p.IconShadowHeight);
                    myIcon_google.iconAnchor = new GPoint(p.IconAnchor_posX, p.IconAnchor_posY);
                    myIcon_google.infoWindowAnchor = new GPoint(p.InfoWindowAnchor_posX, p.InfoWindowAnchor_posY);
                    
                }
                var zorder = p.Selected?2:0;
                marker = CreateMarker(myPoint, myIcon_google, p.InfoHTML, p.Draggable, p.Title, p.ToolTip, p.ID, p.IsClickable, zorder);
         
                marker.value = p.ID;
                markers.pushValue(marker);
                map.addOverlay(marker);
            }
        }
        //New Marker
        else if(p.PointStatus=='N'){
            myIcon_google = null;
            if (p.IconImage != '') {
                myIcon_google = new GIcon(G_DEFAULT_ICON);

                myIcon_google.iconSize = new GSize(p.IconImageWidth, p.IconImageHeight);
                myIcon_google.image = p.IconImage;
                myIcon_google.shadow = p.IconShadowImage;
                myIcon_google.shadowSize = new GSize(p.IconShadowWidth, p.IconShadowHeight);
                myIcon_google.iconAnchor = new GPoint(p.IconAnchor_posX, p.IconAnchor_posY);
                myIcon_google.infoWindowAnchor = new GPoint(p.InfoWindowAnchor_posX, p.InfoWindowAnchor_posY);
            }

            var marker = CreateMarker(myPoint, myIcon_google, p.InfoHTML, p.Draggable, p.Title, p.ToolTip, p.ID, p.IsClickable, 0);
            marker.value = p.ID;
            markers.pushValue(marker);
            map.addOverlay(markers.getLastValue());
        }
        //Existing marker, but deleted.
        if(p.PointStatus=='D'){
            var marker = markers.getValueById(p.ID);
            if(marker!=null){
                markers.removeValueById(p.ID);
                map.removeOverlay(marker);
            }
        }
    }
    //Get Polylines
    var plines = result.Polylines;
    for (i = 0; i < plines.length; i++) {
        var pl = result.Polylines[i];
        if (pl.LineStatus == 'C') {
            var polyline = polylines.getValueById(pl.ID);
            if(polyline!=null){
                polylines.removeValueById(pl.ID);
                map.removeOverlay(polyline);
            }
	        var polypoints = new Array();
	        var j;
	        for (j = 0; j < pl.Points.length; j++) {
	            var p = pl.Points[j];
	 	        polypoints.push(new GLatLng(p.Latitude, p.Longitude));
	        }
            var polyline = CreatePolyline(polypoints,pl.ColorCode,pl.Width,pl.Opacity,pl.Geodesic);
            polylines.pushValue(polyline,pl.ID);
            map.addOverlay(polylines.getLastValue());
        }
        if(pl.LineStatus=='N'){
	        var polypoints = new Array();
	        var j;
	        for(j=0;j<pl.Points.length;j++){
	            var p = pl.Points[j];
	            polypoints.push(new GLatLng(p.Latitude, p.Longitude));
	        }
            var polyline = CreatePolyline(polypoints,pl.ColorCode,pl.Width,pl.Opacity,pl.Geodesic);
            polylines.pushValue(polyline,pl.ID);
            map.addOverlay(polylines.getLastValue());
        }
        if(pl.LineStatus=='D'){
            var polyline = polylines.getValueById(pl.ID);
            if(polyline!=null){
                polylines.removeValueById(pl.ID);
                map.removeOverlay(polyline);
            }
        }
    }
    //Get Polygons
    var pgs = result.Polygons;
    for (i = 0; i < pgs.length; i++) {
        var pg = pgs[i];
        if(pg.Status=='C'){
            var polygon = polygons.getValueById(pg.ID);
            if(polygon!=null){
                polygons.removeValueById(pg.ID);
                map.removeOverlay(polygon);
            }
	        var polypoints = new Array();
	        var j;
	        for (j = 0; j < pg.Points.length; j++) {
	            var p = pg.Points[j]
	 	        polypoints.push(new GLatLng(p.Latitude, p.Longitude));
	        }
            var polygon = CreatePolygon(polypoints,pg.StrokeColor,pg.StrokeWeight,pg.StrokeOpacity,pg.FillColor,pg.FillOpacity);
            polygons.pushValue(polygon,pg.ID);
            map.addOverlay(polygons.getLastValue());
            if (pg.IsEditable == true) {
                polygon.enableEditing();
            }
        }
        if(pg.Status=='N'){
	        var polypoints = new Array();
	        var j;
	        for (j = 0; j < pg.Points.length; j++) {
	            var p = pg.Points[j];
	 	        polypoints.push(new GLatLng(p.Latitude, p.Longitude));
	        }
	        var polygon = CreatePolygon(polypoints, pg.StrokeColor, pg.StrokeWeight, pg.StrokeOpacity, pg.FillColor, pg.FillOpacity);
	        if (pg.IsVisible == false) {
	            mapzones.pushValue(polygon, pg.ID, pg.Title);
            }
            else {
                polygons.pushValue(polygon, pg.ID);
                map.addOverlay(polygons.getLastValue());
            }
	        if (pg.IsEditable == true) {
	            polygon.enableEditing();
	        }
	    }
        //Existing marker, but deleted.
        if(pg.Status=='D'){
            var polygon = polygons.getValueById(pg.ID);
            if(polygon!=null) {
                polygons.removeValueById(pg.ID);
                map.removeOverlay(polygon);
            }
        }
    }

    if (IsRecenteringEnabled == true && IsMonitoringEnabled == false) {

        if (IsCarSelected) {
            map.setCenter(selectedCarPosition, mapZoom);
            LockeyApplication.Map.MapService.RecenterMapComplete();
        } 
    }
    if (IsMonitoringEnabled) {
    RecenterAndZoom(IsMonitoringEnabled, result);   
    }
//    if (IsResizeForReports == true && IsMonitoringEnabled == false) {
//        RecenterAndZoom(IsResizeForReports, result);          
//    }
}
}

//This function causes Recentering of map. It finds all visible markers on map and decides center point and zoom level based on these markers.
function RecenterAndZoom(bRecenter, result) {
    if(bRecenter){
        //Check if there is any visible pushpin on map.
        var cnt = 0;
        bounds = new GLatLngBounds();
        var objIgnore = document.getElementById('chkIgnoreZero');
        var bIgnore = false;
        if(objIgnore!=null){
           bIgnore  = objIgnore.checked;
        }    
        bIgnore = result.IgnoreZeroLatLngs;
        for(var i=0;i<markers.getLength();i++){
            var ignoremarker = false;
            if(bIgnore){
                var point1 = markers.markers[i].getPoint();
                if((point1.x==0) && (point1.y==0)){
                    ignoremarker = true;
                }
            }
            if(!ignoremarker){
                if(!markers.markers[i].isHidden()){
                    bounds.extend(markers.markers[i].getPoint());
                    cnt++;
                }
            }
        }
        var iZoomLevel = map.getBoundsZoomLevel(bounds);
        FollowMapZoom = iZoomLevel;
        var point = bounds.getCenter();
        var currZoom = map.getZoom();
        
        if(cnt<=0){
            point = new GLatLng(result.CenterPoint.Latitude,result.CenterPoint.Longitude);
            iZoomLevel =result.ZoomLevel;           
        }
        if (currZoom < iZoomLevel) {//save current zoom level if conforms
            iZoomLevel = currZoom;
        }
        map.setZoom(iZoomLevel);
        map.setCenter(point);
    }
}


function endRequestHandler(sender, args){
    LockeyApplication.Map.MapService.GetOptimizedMapObject(fGetGoogleObjectOptimized);
}
function pageLoad(){
    if(!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
}

function RefreshCarsOnMap() {
    RemoveTemporalMarker(); //clean track point marker
    LockeyApplication.Map.MapService.RefreshObjectsOnMap();
    LockeyApplication.Map.MapService.GetOptimizedMapObject(fGetGoogleObjectOptimized);
}

function GetZonePoints() {
    var str = '<zone/>';
    if (polygons.getLength() > 0) {
        var zone = polygons.getValue(0);
        str = '<zone>';
        for (var i = 0; i < zone.getVertexCount(); i++) {
            var point = zone.getVertex(i);
            str += '<point lat="' + point.lat() + '" lng="' + point.lng() + '" />';
        }
        str += '</zone>';
    }
    return str;
}

function CleanMap(lt, ln, zoom) {
    RemoveTemporalMarker(); //clean track point marker    
    while (markers.getLength() > 0) {
        var marker = markers.getValue(0);
        map.removeOverlay(marker);
        markers.removeValueById(marker.value);
    }
    while (polylines.getLength() > 0) {
        map.removeOverlay(polylines.getValue(0));
        polylines.removeValueById(polylines.getIDValue(0));
    }
    while (polygons.getLength() > 0) {
        map.removeOverlay(polygons.getValue(0));
        polygons.removeValueById(polygons.getIDValue(0));
    }
    map.setZoom(zoom);
    map.setCenter(new GLatLng(lt, ln));
}

function ShowZone(n) {
   mapzones.setVisible(n, true);
   map.addOverlay(mapzones.getValue(n));
}
function HideZone(n, clear) {
    map.removeOverlay(mapzones.getValue(n));
    if (clear) mapzones.setVisible(n, false);
}
function SetZoneControlVisibility(visibility) {
    if (map == null) return;
    if (visibility == true) {
        map.addControl(MapZoneControlObj, new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(230, 7)));
        map.addControl(MapZoneControlObj.getListCtrl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(240, 32)));
    }
    else {
        MapZoneControlObj.getListCtrl().container.innerHTML = "";
        map.removeControl(MapZoneControlObj.getListCtrl());
        map.removeControl(MapZoneControlObj);
    }
}
function MapUnload() {
    GUnload();
}
if (document.addEventListener)
    document.addEventListener('onunload', MapUnload, false);
if (window.attachEvent)
    document.attachEvent('onunload', MapUnload);

function ShowZoneOnMap() {
    LockeyApplication.Map.MapService.RefreshObjectsOnMap();
    LockeyApplication.Map.MapService.GetOptimizedMapObject(fGetGoogleObjectOptimized);
}

var tempMarker;
var stopMarker;

function GetTemporalIcon() {
    var iconPath = window.location.protocol + "//" + window.location.host;
    var path = window.location.pathname;
    var ss = path.split("/");

    for (var i = 0; i < ss.length - 2; i++)
        iconPath += "/" + ss[i];
    iconPath += "/map/resources/red_pointer.gif";
    return iconPath;
}
function CreateTemporalMarker(Lat, Lon) {
    RemoveTemporalMarker();
    var tmpIcon = new GIcon(G_DEFAULT_ICON);
    tmpIcon.iconSize = new GSize(13, 28);
    tmpIcon.image = "../Map/resources/red_pointer.gif";
    tmpIcon.shadow = null;
    tmpIcon.shadowSize = new GSize(0, 0);
    tmpIcon.iconAnchor = new GPoint(7, 28);
    tmpIcon.infoWindowAnchor = new GPoint(8, 8);
    var pnt = new GLatLng(Lat, Lon);
    tempMarker = new LabeledMarker(pnt, { icon: tmpIcon, draggable: false, title: "", labelText: "", clickable: false});
    tempMarker.description = "";
    tempMarker.name = "";
    tempMarker.id = "reportMarker";

    map.addOverlay(tempMarker);
     map.setCenter(pnt);
}

function RemoveTemporalMarker() {
    if (tempMarker != null)
        map.removeOverlay(tempMarker);
    tempMarker = null;
}

function CreateStopMarker(Lat, Lon) {
    RemoveStopMarker();
    var tmpSIcon = new GIcon(G_DEFAULT_ICON);
    tmpSIcon.iconSize = new GSize(20, 20);
    tmpSIcon.image = "../Map/resources/parking_red.gif";
    tmpSIcon.shadow = null;
    tmpSIcon.shadowSize = new GSize(0, 0);
    tmpSIcon.iconAnchor = new GPoint(10, 20);
    tmpSIcon.infoWindowAnchor = new GPoint(8, 8);
    var lat = Lat.toString().replace(',', '.');
    var lon = Lon.toString().replace(',', '.');
    var pnt = new GLatLng(lat, lon);
    stopMarker = new LabeledMarker(pnt, { icon: tmpSIcon, draggable: false, title: "", labelText: "", clickable: true });
    stopMarker.description = "";
    stopMarker.name = "";
    stopMarker.id = "reportMarker";
    map.addOverlay(stopMarker);
     map.setCenter(pnt);
}

function RemoveStopMarker() {
    if (stopMarker != null)
        map.removeOverlay(stopMarker);
    stopMarker = null;
}
function Recenter(lat, lon) {
    var pt = new GLatLng(lat, lon);
    map.setCenter(pt);
}
//---- extensions for track player
function  RegZoomListener(callback){
    GEvent.addListener(map, "zoomend", callback);
}
function CreatePlayerMarker() {
    var carIcon = new GIcon(G_DEFAULT_ICON);
    carIcon.image = "../Map/resources/car_gray.gif";
    carIcon.shadow = null;
    carIcon.iconSize = new GSize(50, 17);
    carIcon.iconAnchor = new GPoint(25, 17);
    var point =polylines.getLastValue().points[0];
    marker = new GMarker(point, { icon: carIcon });
    return marker;
}
// ~----extensions for track player
