//La classe dérive de la classe Followmap et implante les méthodes nécessaires
// à l'usage des maps GoogleMaps de Google

GMap.prototype = new Followmap();
GMap.prototype.constructor = GMap;
GMap.prototype.baseClass = Followmap.prototype.constructor;
GMap.prototype.loadMap = GloadMap;

GMap.prototype.DrawShape = GDrawShape;
GMap.prototype.centermap = Gcentermap;
GMap.prototype.remove = Gremove;
GMap.prototype.CenterOneCompet = GCenterOneCompet;
GMap.prototype.dotoggledisplay = Gdotoggledisplay;
GMap.prototype.displayCheckpoints = GdisplayTopPoints;
GMap.prototype.erasePoints = GErasepoints;
GMap.prototype.dessineParcours = GdessineParcours;
GMap.prototype.ClearAll = GClearAll;
GMap.prototype.traceCompet = GtraceCompet;
GMap.prototype.erasetrace = Gerasetrace;
GMap.prototype.redrawtrace = Gredrawtrace;
GMap.prototype.Clearmap = DoClearmap;

// Le constructeur
function GMap(divname)
{
    this.baseClass(divname);
    this.map = null;
    
    // les tableaux associatifs pour gérer l'affichage
    this.checkPointsArray = null;
    this.GMparcours = null;
    this.positionsArray = null;
    this.tjrsvisibleArray = null;
}
//---------------------------------------------------------
// les fonctions propres à la classe

//---------------------------------------------------------
function DoClearmap()
{
    google.maps.Event.removeListener(this.mapTypeListener);
    google.maps.Event.removeListener(this.moveListener);
    this.map.removeControl(this.PositionControl);
}
//---------------------------------------------------------
function MySetCenter(latlng,zoom)
{
    google.maps.Map2.prototype.setCenter.call(this,latlng,zoom);
}
//---------------------------------------------------------
function GloadMap(style)
{
// Inutile d'utiliser setOnLoadCallback car cette méthode est soit appelée
// par onLoaded soit lors des toggle. La page est donc tjrs entièrement chargée

    this.positionsArray = new Array();
    
  //  this.map = new ExtGMap(document.getElementById(this.divname));
    this.map = new GMap2(document.getElementById(this.divname));
    
    this.map.setCenter(new google.maps.LatLng(this.startLat,this.startLon), 8);
    this.map.setMapType(G_HYBRID_MAP);
    var ctrl = new google.maps.MapTypeControl();
    this.map.addControl(ctrl);
    ctrl = new google.maps.SmallZoomControl();
    this.map.addControl(ctrl);
    this.map.enableScrollWheelZoom();
    this.PositionControl = new PositionsControl();
    this.map.addControl(this.PositionControl);
    
    switch(style) {
        case "R" :this.map.setMapType(G_NORMAL_MAP);break;
        case "A" :this.map.setMapType(G_SATELLITE_MAP);break;
        case "H" :this.map.setMapType(G_HYBRID_MAP);break;
    }
    
    // Pour enregistrer le changement de style
    
    this.mapTypeListener = google.maps.Event.addListener(this.map,"maptypechanged",function()
        {
            var style = this.getCurrentMapType().getName();
            switch(style)
            {
                case "Plan" : writeCookie(kindmap,"R");break;
                case "Satellite" : writeCookie(kindmap,"A");break;
                case "Mixte" : writeCookie(kindmap,"H");break;
            }
        }
    );
    
    this.moveListener = google.maps.Event.addListener(this.map,"mousemove",function(latlng)
        {
            var lat = latlng.lat();
            var lng = latlng.lng();
            var latLng = document.getElementById("lLPositions");
            latLng.innerText = gettextPositions(lat,lng);
        }
    );
}
//---------------------------------------------------------
function GDrawShape(isReplay,alpha,nom,nom2,team,kind,id,lat,lng,speed,date)
{
    var myicon = new google.maps.Icon(G_DEFAULT_ICON);
    myicon.image = "images/balise.png";
    myicon.shadow = "";
    myicon.iconSize = new google.maps.Size(20,20);
    myicon.iconAnchor = new google.maps.Point(0,0);
    var mOptions = {icon:myicon,title:nom};
    var marker = new FMMarker(new google.maps.LatLng(lat,lng),myicon,id);
    google.maps.Event.addListener(marker,"mouseover",function(){
        var details = "<span id='detailsblock'><span id='detailsheader'>" + id + "-" + nom + "</span><br><br><span id='detailszone'>Car # : " + id  + "<br/>Driver : " + nom + "<br/>Co driver : " + nom2 + "<br/>Team : " + team + "<br/>Type : " + kind + "<br/>Speed : " + speed + " km/h<br/>";
        if (isReplay)
        {
            var hms = getHMS(date);
            details +=  "Elapsed time : " + hms + "</span></span>"
        }
        else
            details +=  "Date : " + date + "</span></span>"
        marker.openInfoWindowHtml(details);
        displayInfosFromPosis(posis[alpha]);
        return marker;
    });
    
    this.positionsArray[alpha] = marker;
    this.map.addOverlay(marker);
}
//---------------------------------------------------------
function Gcentermap()
{
    var id;
    var count = 0;
    
    // on compte le nombre de membres - les tableaux associatifs ne connaissent pas length
    for (id in this.positionsArray) 
    {
        count ++;
    }

    if (count == 0)
        return;
        
    if (count == 1)
    {
        this.CenterOneCompet(id);
    }
    else
    {
        var bounds = new google.maps.LatLngBounds();
        for (shape in this.positionsArray)
        {
            var marker = this.positionsArray[shape];
            var pt = marker.getPoint();
            bounds.extend(pt);
        }
        var center = bounds.getCenter();
        var zoomlevel = this.map.getBoundsZoomLevel(bounds);
        this.map.panTo(center);
        this.map.setZoom(zoomlevel-1);
    }
}
//---------------------------------------------------------
function Gremove(id)
{
    var marker = this.positionsArray[id];
    this.map.removeOverlay(marker);
    var newarray = new Array();
    
    for (shape in this.positionsArray)
    {
        if (shape == id)
            continue;
        newarray[shape] = this.positionsArray[shape];
    }
    this.positionsArray = newarray;
}
//---------------------------------------------------------
function GClearAll()
{
    for (alpha in this.positionsArray)
    {
        var marker = this.positionsArray[alpha];
        this.map.removeOverlay(marker);
    }
    this.positionsArray = new Array();
}
//---------------------------------------------------------
function GtraceCompet(posi,autozoom)
{
    if (posi.points.length == 0)    // rien à dessiner
        return;
    
    var pts = new Array();
    for (var i = 0 ; i < posi.points.length;i++)
    {
        var pt = new google.maps.LatLng(posi.points[i].lat,posi.points[i].lng);
        pts.push(pt);
    }
    
   var polyline = new google.maps.Polyline(pts,posi.color);
    posi.polyline = polyline;
    this.map.addOverlay(polyline);
    if (autozoom) {
        var level = this.map.getBoundsZoomLevel(polyline.getBounds());
        this.map.setZoom(level);
    }
}
//---------------------------------------------------------
function GErasepoints(kind)
{
    if (kind == "ROUTE")
    {
        this.GMparcours.eraseRoute();
        this.GMparcours = null;
    }
    else if (kind == 'TOP')
    {
        for (var i = 0;i < this.checkPointsArray.length;i++)
        {
            this.map.removeOverlay(this.checkPointsArray[i]);
        }
        Array.clear(this.checkPointsArray);
    }
}
//---------------------------------------------------------
function Gerasetrace(posi)
{
    if ( (posi != null) && (posi.polyline!=null) )
        this.map.removeOverlay(posi.polyline);
}
//---------------------------------------------------------
function Gredrawtrace(alpha)
{
    var pts = new Array();
    var posi = posis[alpha];
    
    if (posi.polyline == null)
        return;
        
    for (var i=0;i<posi.polyline.getVertexCount();i++)
    {
        pts.push(posi.polyline.getVertex(i));
    }
   this.map.removeOverlay(posi.polyline);
   var polyline = new google.maps.Polyline(pts,posi.color);
   posi.polyline = polyline;
   this.map.addOverlay(polyline);
}
//---------------------------------------------------------
function GCenterOneCompet(alpha)
{
    if (this.positionsArray == null)
        return;

    var marker = this.positionsArray[alpha];
    if (marker == null)
        return;
    var pt = marker.getPoint();
    this.map.panTo(pt);
}
//---------------------------------------------------------
function Gdotoggledisplay(cb)
{
    var markers;

    switch(cb.id)
    {
        case "dispCompets":markers = this.positionsArray;break;
        case "dispParcours":markers = null; if ((this.GMparcours == null) && (route != null))
                                    this.GMparcours = new parcours(route);
                                    this.GMparcours.showhide(cb.checked);break;
        case "dispCheckpoints":markers = this.checkPointsArray;break;
    }
    
    if (markers != null)
        for (alpha in markers)
        {
            var marker = markers[alpha];
            (cb.checked) ? marker.show() : marker.hide();
        }
}
//---------------------------------------------------------
function GdisplayTopPoints(pts,context)
{
    var marker;
    var iconSrc;
    
    if (context == 'OPT')
    {
        var newarray = new Array();
        var bounds = new google.maps.LatLngBounds();
        
        for (var i=0;i<pts.length;i++)
        {
            var pt = pts[i];
            var image = new Image();
            switch (pt.kind)
            {
                case 10 : iconSrc = "green.png";break;
                case 11 : iconSrc = "start.ico";break; //START
                case 12 : iconSrc = "red.png";break; // Stop Chk
                case 13 : iconSrc = "yellow.png";break; // Pit
                case 14 : iconSrc = "roadx.png";break; // Road X
                case 15 : iconSrc = "black.png";break; // Road X
                case 21 : iconSrc = "finish.ico";break; //FINISH
                default:iconSrc = pt.imgName;break;
            }
            
            image.src = "images/" + iconSrc;
            var w = image.width;
            var h = image.height;
            var myicon = new google.maps.Icon("",image.src);
            myicon.iconSize = new google.maps.Size(w,h);
            myicon.iconAnchor = new google.maps.Point(0,h);
            var mOptions = {icon:myicon,title:pt.nom};

            var lLpoint = new google.maps.LatLng(pt.lat,pt.longi);
            marker = new google.maps.Marker(lLpoint,mOptions);
            newarray.push(marker);
            bounds.extend(lLpoint);
            this.map.addOverlay(marker);
        }
        
       var level = this.map.getBoundsZoomLevel(bounds);
       this.map.setZoom(level);
       this.checkPointsArray = newarray;
    }
}
//---------------------------------------------------------
function GdessineParcours(route)
{
    if (this.GMparcours == null)
        this.GMparcours = new parcours(this.map,route);
        
    this.GMparcours.afficheroute();
}
//*************************************************************
// Classe PositionsControl
// Surclasse le contrôle GControl pour afficher la position courante sur la mapView
function PositionsControl() {}

PositionsControl.prototype = new google.maps.Control;

PositionsControl.prototype.initialize = function(map)
{
    this.mapWidth = map.getSize().width;
    
    var container = document.createElement("div");
    
    var id = document.createAttribute("id");
    id.nodeValue = "lLPositions";
    container.setAttributeNode(id);
        
    map.getContainer().appendChild(container);
    
    return container;
}

// Position du contrôle
PositionsControl.prototype.getDefaultPosition = function() {
    return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(300,10));
}
//*************************************************************
// La classe parcours
parcours.prototype.afficheroute = afficheroute;
parcours.prototype.showhide = doshowhide;
parcours.prototype.eraseRoute = doeraseRoute;

function parcours(map,route)
{
    this.route = route;
    this.gmap = map;
    
    var secteur = "";
    var color1 = "#0032FF";
    var color2 = "#FF0000";
    var color = color1;
    var point;
    var points = new Array(); // tableau de Gpoints pour polyline
    this.linesArray = new Array(); // tableau des polylines ( 1 par secteur)
    this.pointsArray = new Array(); // tableau des markers spéciaux pour le parcours
    
    if (route.length > 0)
    {
        if (route[0].secteur==2)
            color = color2;
    }
    
    for (var i = 0;i<route.length;i++)
    {
        point = new google.maps.LatLng(route[i].lat,route[i].longi);
        
        if (route[i].secteur != secteur)    // nouveau secteur
        {
            if (points.length > 1) // existe t-il déjà un polyline ?
            {
                var polyline = new google.maps.Polyline(points,color,4);
                this.linesArray.push(polyline);
                points = new Array();
             }
             secteur = route[i].secteur;
              if (secteur==1)
                color = color1;
            else
                color = color2;
      }
        
        points.push(point); // on construit le tableau pour polyline
         if (route[i].kind > 1)
        {
            // Construire les markers pour les points spéciaux du parcours
            this.pointsArray.push(buildmarker(route[i]));
        }
   }
    
       // Pour tracer l'étape unique
        if (points.length > 0)
        {
           var polyline = new google.maps.Polyline(points,color,4);
           this.linesArray.push(polyline);
           var level = map.getBoundsZoomLevel(polyline.getBounds());
           map.setZoom(level);

        } 
}
//-----------------------------------------------------------------------
function doeraseRoute()
{
    for (var i = 0;i<this.linesArray.length; i++)
    {
       var polyline = this.linesArray[i];
       this.gmap.removeOverlay(polyline);
    }
    Array.clear(this.linesArray);
    
   if (this.pointsArray != null)
   {
       for (var i = 0;i<this.pointsArray.length; i++)
            this.gmap.removeOverlay(this.pointsArray[i]);
            
       Array.clear(this.pointsArray);
   }

}
//-----------------------------------------------------------------------
 function buildmarker(gpt)
{
    var kind = gpt.kind;
    
    // construit le marker associé aux vertex simples (type 1) ou aux CPs (type 2)
    var mOptions;
    
    var myicon = new google.maps.Icon(G_DEFAULT_ICON);
    myicon.image = "images/" + gpt.imgName;
    myicon.iconSize = new google.maps.Size(20,20);
    myicon.iconAnchor = new google.maps.Point(0,0);
    
    if(kind == 2) // CP ?
        mOptions = {icon:myicon,title:gpt.nom};
    else
        mOptions = {icon:myicon};
    var marker = new google.maps.Marker(new google.maps.LatLng(gpt.lat,gpt.longi),mOptions);

    if(kind == 2) // CP ?
    {
    google.maps.Event.addListener(marker,"mouseover",function(){
        var content = "<span style='color:black'>" + gpt.infos + "</span>";
        marker.openInfoWindowHtml(content);
    });
    }
    return marker;
}
//-------------------------------------------------------
function CenterOnRoute(map,centers)
{
    var polyline = new google.maps.Polyline(centers);
    var bounds = polyline.getBounds();

    var center = bounds.getCenter();
    map.panTo(center);
}
//-------------------------------------------------------
function afficheroute()
{
    if (this.linesArray != null)
    {
        var ne;
        var centersArray = new Array();
        
        for (var i = 0;i<this.linesArray.length; i++)
            {
                var polyline = this.linesArray[i];
                this.gmap.addOverlay(polyline);
                var glatlngbounds = polyline.getBounds();
                var glatlng = glatlngbounds.getCenter();
                centersArray.push(glatlng);
            }
        CenterOnRoute(this.gmap,centersArray);
    }
        
     if (this.pointsArray != null)
     {
        var lLBounds = new google.maps.LatLngBounds
        for (var i = 0;i<this.pointsArray.length; i++)
        {
            lLBounds.extend(this.pointsArray[i]);
            this.gmap.addOverlay(this.pointsArray[i]);
        }    
            
   //    var level = this.gmap.getBoundsZoomLevel(lLBounds);
   //    this.gmap.setZoom(level);
     }
}
//-------------------------------------------------------
function doshowhide(checked)
{
    if (this.linesArray != null)
    {
        var centersArray = new Array();
        for (var i = 0;i<this.linesArray.length; i++)
        {
          var polyline = this.linesArray[i];
          if (checked)
            {
                polyline.show();
                var glatlngbounds = polyline.getBounds();
                var glatlng = glatlngbounds.getCenter();
                centersArray.push(glatlng);
            }
            else
                polyline.hide();
         }
         if (checked)
            CenterOnRoute(this.gmap,centersArray);
        }
        
     if (this.pointsArray != null)
        for (var i = 0;i<this.pointsArray.length; i++)
            (checked) ? this.pointsArray[i].show():this.pointsArray[i].hide();
}
//**********************************************************
// Sous classe de GMap2 pour gérer le zoom avec le dragging
function ExtGMap(div)
{
    this.dragListener = null;
    this.div_ = div;
    google.maps.Map2.call(this,div);
    
    this.dragListener = google.maps.Event.bindDom(this,"click",this,this.OnDragStart);
}

inherit(ExtGMap,google.maps.Map2);

ExtGMap.prototype.setCenter = MySetCenter;
ExtGMap.prototype.OnDragStart = DoDragStart;

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();