
//  Global Variables
var g_map = null;   //  the global var g_map is defined in the script wl_load_track_lib.js

var g_zoom_level = "none";
var g_races_bounds = null;
var g_rest_request = null;
var g_rest_originaldata = null;
var g_rest_deloriginal = null;
var g_marker_manager = null;
var g_markers = null;
var g_selection_mode = 1;   //  1 for races selection, 2 when at least 1 race has been selected
var g_zoom = 0;
var g_center = 0;
var g_check_iframe;
var g_check_timeout = 0;
var g_current_token = null;
var g_current_challenger = null;
var g_original_polys = null;
var g_original_totems = null;
var g_totem_manager = null;



//===============================================
//  inherited
//===============================================
var request;
var response_txt;


//  global variables
var g_icon_totem = null;    //  icon for the original data - totem
var g_race_entries;         //  contains the records from the table "challenges"

//  new global variables for this applet
var g_mtp_track_obj = null;
var g_nav_bar_obj = null;




//===========================================================
//  AJAX
//===========================================================

function createXMLHttpRequest() {
    var req = null;

    if (window.XMLHttpRequest) {
        try {
            req = new XMLHttpRequest();
        }
        catch (e) {
            req = null;
        }
    }
    else if (window.ActiveXObject) {
        try {
            req = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            try {
                req = new ActiveXObject("Microsoft.XMLHTTP");
            }
            catch (e) {
                req = null;
            }
        }
    }
    else {
        alert("This browser does not support dynamic content.");
    }

    return req;
}


//===========================================================


function get_event_position(posobj, evt) {
    if (evt.pageX) {
        posobj.left = evt.pageX;
        posobj.top = evt.pageY;
    }
    else if (evt.clientX) {
        posobj.left = evt.clientX + document.body.scrollLeft - document.body.clientLeft;
        posobj.top = evt.clientY + document.body.scrollTop - document.body.clientTop;
        if (document.body.parentElement && document.body.parentElement.clientLeft) {
            var bodParent = document.body.parentElement;
            posobj.left += bodParent.scrollLeft - bodParent.clientLeft;
            posobj.top += bodParent.scrollTop - bodParent.clientTop;
        }
    }
}


function ShowUser(elem, evt, x_delta, y_delta) {
    //  show the UserPopupId popup
    if (!elem.user_id) { return false; }
    var user_id = elem.user_id;
    var url = "/scripts/wl_show_user.php?u=" + user_id;

    //  get the position of the click event
    var evtpos = { left: 0, top: 0 };
    get_event_position(evtpos, evt);
    evtpos.left += x_delta;
    evtpos.top += y_delta;
    evtpos.left = (evtpos.left >= 0) ? evtpos.left : 0;
    evtpos.top = (evtpos.top >= 0) ? evtpos.top : 0;
    evtpos.top = (evtpos.top > 300) ? 300 : evtpos.top;

    //  move the popup
    movePopup('UserPopupId', evtpos.left, evtpos.top);

    //  set the new content of the popup
    changecontent('UserPopupId', url);
    //  show the popup
    fadeboxin('UserPopupId');

    return false;
}

function ShowPost(race_id, evt, x_delta, y_delta) {
    //  get the id and the name of the race
    if (!g_mtp_track_obj) { return; }
    if (g_mtp_track_obj.i_status != 2) { return; }  //  the race track has to be completely loaded
    race_name = escape(g_mtp_track_obj.i_name);

    //  show the RacePostId popup
    var url = "/i_rate_post.html?rid=" + g_mtp_track_obj.i_uid + "&nid=" + race_name;

    //  get the position of the click event
    var evtpos = { left: 0, top: 0 };
    get_event_position(evtpos, evt);
    evtpos.left += x_delta;
    evtpos.top += y_delta;
    evtpos.left = (evtpos.left >= 0) ? evtpos.left : 0;
    evtpos.top = (evtpos.top >= 0) ? evtpos.top : 0;
    evtpos.top = (evtpos.top > 300) ? 300 : evtpos.top;

    //  move the popup
    movePopup('RacePostId', evtpos.left, evtpos.top);

    //  set the new content of the popup
    changecontent('RacePostId', url);
    //  show the popup
    fadeboxin('RacePostId');

    return false;
}

function ShowRaceUrl(race_url) {
    //  get the id and the name of the race

    var content = "<html><body><p>Copy and paste the URL into your code</p><code>" + race_url + "</code></body></html>";
    changecontent("RaceUrlId", content);
    
    movePopup('RaceUrlId', 200, 200);

    //  show the popup
    fadeboxin('RaceUrlId');

    return false;

}


function TrackStatusText(msg) {
    var elem = document.getElementById("status_txt");
    if (elem) {
        elem.innerHTML = msg;
    }
}

function TrackStatusImg(imgsrc) {
    var elem = document.getElementById("status_img");
    if (elem) {
        elem.setAttribute("src", imgsrc);
    }
}

function SetDataRaceButton(enabled) {
    var elem = document.getElementById("race_data");
    if (!elem) { return; }
    
    if (enabled) {
        //  enable button
        elem.disabled = null;
        elem.setAttribute("src", "/images/magnifier.gif");
        elem.onmouseover = function() { Img(this, '/images/magnifier_over.gif'); }
        elem.onmouseout = function() { Img(this, '/images/magnifier.gif'); }
        elem.onclick = RaceData;
    } else {
        //  disable button
        elem.disabled = true;
        elem.setAttribute("src", "/images/null.gif");
        elem.onmouseover = null;
        elem.onmouseout = null;
        elem.onclick = null;    
    }
}

function SetUploadButton(enabled) {
    var browse = document.getElementById("Browse");
    if (browse) {
        if (enabled) { browse.disabled = null; }
        else { browse.disabled = true; }
    }

    var upload = document.getElementById("Upload");
    if (upload) {
        if (enabled) { upload.disabled = null; }
        else { upload.disabled = true; }
    }
}

function SetUploadForm(race_index, user_id, track_id) {
    //  This function sets the action attr. of the form "UploadForm".
    //  race_index is the index of the race (table challenges)
    //  user_id is the index of the user that owns the race
    //  track_id is the index of the track (index relative to the user)
    var elem = document.getElementById("UploadForm");
    if (!elem) { return; }
    var now_date = new Date();
    var action = "/scripts/wl_race_upload.php?i=" + race_index + "&u=" + user_id + "&r=" + track_id + "&seq=" + now_date.getTime();
    elem.setAttribute("action", action);
    
    return;
}

function UploadShowOriginalData(od_points) {
    if (!g_map) return;
    if (od_points.length < 1) { return; }
    
    ResetOriginalData();
    if (g_original_polys == null) { g_original_polys = new Array(); }

    var points = new Array();
    var pt_type = 0;
    var pt_lat = 0.0;
    var pt_lon = 0.0;
    var pt_colors = new Array();
    pt_colors[0] = "#00ffff"
    pt_colors[1] = "#ff0000"
                       
    for (var iod = 0; iod < od_points.length; iod++) {
        var od_point_rec = od_points[iod].innerHTML;
        var pt_fields = od_point_rec.split(";");
        
        if (pt_type != parseInt(pt_fields[0])) {
            //  draw the polyline onto the map
            var gpoly = new GPolyline(points, pt_colors[pt_type], 2, 1);
            g_original_polys.push(gpoly);
            while (points.length > 0) { points.pop(); }
        }
        
        pt_type = parseInt(pt_fields[0]);
        pt_lat = parseFloat(pt_fields[1]);
        pt_lon = parseFloat(pt_fields[2]);

        points.push(new GLatLng(pt_lat, pt_lon));

        if (points.length >= 200) {
            //  draw the polyline onto the map
            var gpoly = new GPolyline(points, pt_colors[pt_type], 2, 1);
            g_original_polys.push(gpoly);
            while (points.length > 0) { points.pop(); }
        }
                                
        //alert("type(" + pt_type + ") lat(" + pt_lat + ") lon(" + pt_lon + ")" );
    }

    //  drae the remaining points, if any
    if (points.length > 0) {
        //  draw the polyline onto the map
        var gpoly = new GPolyline(points, pt_colors[pt_type], 2, 1);
        g_original_polys.push(gpoly);
        while (points.length > 0) { points.pop(); }
    }

    for (i = 0; i < g_original_polys.length; i++) {
        g_map.addOverlay(g_original_polys[i]);
    }        
}    

function WaitForUploadResult() {
    
    //  This function checks if any content has been presented, in the iframe that receives
    //  the results from the wl_race_upload service.
    var reply_res = window.frames["UploadFrame"].document.getElementById('RES');
    if (reply_res) {
        //  The content has been produced by the web service wl_race_upload.php.
        //  Process the content.
        var reply_rc = window.frames["UploadFrame"].document.getElementById('RC');
        if (reply_rc) {            
            //  reply_rc contains the return code
            if (reply_rc.innerHTML == "0") {
                //  The upload was successfull, so the new entry can be expected in the id "RD" (Race Data)
                var reply_data = window.frames["UploadFrame"].document.getElementById('RD');
                if (reply_data) {
                    //  the data contains the last appended record (challenges) resulting from the upload
                    var re = new RaceEntry(reply_data.innerHTML);
                    if (g_race_entries == null) { g_race_entries = new Array(); }
                    g_race_entries.push(re);

                    //  Render the last record
                    var rtable = document.getElementById("RaceDataBody");
                    if (rtable) {
                        AppendRow(rtable, re, "#00cc00");
                    }
                    
                    //  HERE
                    //  Increment the usage count
                    if (g_mtp_track_obj != null) {
                        if (g_mtp_track_obj.i_marker != null) {
                            if (g_mtp_track_obj.i_marker.wl_usage == 0) {
                                //  this is the first race data that has been uploaded, so show the lens button
                                SetDataRaceButton(true);
                            }
                            g_mtp_track_obj.i_marker.wl_usage++;
                        }                  
                    }

                } // if (reply_data)

            }


            //  new version with original data sent back to the user
            var reply_od = window.frames["UploadFrame"].document.getElementById('UOD');
            if (reply_od) {
                //alert("Original Data available");
                var od_points = reply_od.getElementsByTagName("p");
                //alert("Num of points: " + od_points.length);
                //  the array od_points contains the original points
                UploadShowOriginalData(od_points);


                //  remove the p containins points
                while (reply_od.childNodes.length > 0) { reply_od.removeChild(reply_od.firstChild); }                                         
                
            }
            
            
            
            
        }
        //  Show the reply from the server
        alert(reply_res.innerHTML);
        TrackStatusImg("/images/null.gif");
        
        //  TODO
        //  set another seq for wl_race_upload
        return;
    } else {
        //  No content is available, yet, so re-program the function to be called again
        g_check_timeout++;
        if (g_check_timeout > 120) {
            alert("Error uploading the race. (Timeout)");
            TrackStatusImg("/images/null.gif");

            //  TODO
            //  set another seq for wl_race_upload
            
            return;
        }
        g_check_iframe = setTimeout("WaitForUploadResult()", 1000);
    }
}

function CheckUploadForm() {
    //  this function check if the file can be uploaded
    //  basically this checks if the value of the input id is not empty
    var elem = document.getElementById("Browse");
    if (!elem) { return false; }
    if (elem.value.length <= 0) { return false; }

    //  The action of the form has to be changed here so to avoid cache problems
    if (g_mtp_track_obj) {
        SetUploadForm(g_mtp_track_obj.i_uid, g_mtp_track_obj.i_author_id, g_mtp_track_obj.i_track_id);
    }

    //  Remove (if any) any previous reply from the server
    while (window.frames["UploadFrame"].document.childNodes.length > 0) {
        window.frames["UploadFrame"].document.removeChild(window.frames["UploadFrame"].document.firstChild);
    }
    

    //==============================================
    //  The file can be uploaded
    //==============================================
    TrackStatusImg("/images/loading.gif");
                
    //  set the target attribute
    var form_elem = document.getElementById("UploadForm");
    if (form_elem) {
        form_elem.target = "UploadFrame";
        var iframe_elem = document.getElementById("UploadFrame");
    }

    {
        //  Set the delayed call to the WaitForUploadResult function
        g_check_timeout = 0;
        g_check_iframe = setTimeout("WaitForUploadResult()", 2000);
    }        
    
    return true;
}

//  Marker events
function OnMarkerOver(latlng) {
    //  the mouse is over the marker, show author and usage
    

    //marker.wl_usage = parseInt(prop[5]);    //  if usage is greater than 0, then there are some challengers
    //marker.wl_user_nickname = prop[6];      //  the nickname of the user author of this race
    var props = "Race id: " + this.wl_index + " Challengers: " + this.wl_usage + " Author: " + this.wl_user_nickname;

    SetAuthorProps("AuthorProp", this.wl_user_nickname, this.wl_user_id);                
}

function OnMarkerClick() {

    //  new version
    var user_is_logged = false;
    {
        //  check if the user is logged in
        //  if the user is logged in then the "Logged" element will be available
        var element = document.getElementById("Logged");
        if (element) {
            var check = element.innerHTML;
            if (check == "0") { user_is_logged = false; }
            else { user_is_logged = true; }
        }
    }
    
    /*
        this.wl_index;              //  race index assigned by server (unique track identifier)
        this.wl_user_id;            //  user index
        this.wl_race_id;            //  race index
        this.wl_usage;              //  race usage (if this is greater than 0 -> some challengers are on)
        this.wl_user_nickname;      //  the nickname of the author of the track
    */

    
    //  check if the track is the current track (track already loaded)
    if (g_mtp_track_obj) {
        if (g_mtp_track_obj.i_uid == this.wl_index) {
            //  the track that is going to be loaded and the last loaded track are the same
            if (g_mtp_track_obj.i_status != 0) {
                //  the track is "loading" or "loaded" =>  do not load the track again
                //  clear original data if available
                ResetOriginalData();
                return;
            }
        } else {
            //  the user has clicked on another track ==> reset the current track, original data, etc.            

            if (g_mtp_track_obj) { g_mtp_track_obj.Reset(); }
            
            if (g_map) { 
                //  get the current lat long and zoom - store them
                g_map.clearOverlays(); 
                g_center = g_map.getCenter();
                g_zoom = g_map.getZoom();                
            }

            //  reset original data (if any)
            ResetOriginalData();

            //  reset data race table and the waypoints selection list
            ResetTable("RaceDataBody");
            ResetSelection("WaypointSelection");

            SetDataRaceButton(false);   //  disable data race button
            SetCurrentToken(null);
        }        
    }
    
        
    //  g_selection_mode:   1: "global" race selection, 2: race has been selected
    SetSelection(2);
    
    //  show or hide the button used to load race data
    SetDataRaceButton((this.wl_usage > 0));
    ResetTable("RaceDataBody");
    ResetSelection("WaypointSelection");            
    SetCurrentToken(null);
    
    
    // new version
    if (user_is_logged == true) {
        //  if the user is logged in, enable upload functionality
        SetUploadButton(true);
        SetUploadForm(this.wl_index, this.wl_user_id, this.wl_race_id);
    }

    
    //  NEW VERSION
    //  Creating the global object for the track
    if (g_mtp_track_obj == null) { 
        g_mtp_track_obj = new mtp_track(g_map);
        
        // handlers
        g_mtp_track_obj.OnLegTimeout = function(track_name, leg_idx) {
            var msg = "Track: " + track_name + " <b>Reloading</b> leg " + leg_idx;
            TrackStatusText(msg);
            }
            
        g_mtp_track_obj.OnLegLoading = function(track_name, leg_idx, leg_tot) {
            var msg = "Track: " + track_name + " Loading leg " + leg_idx + " of " + leg_tot;
            TrackStatusText(msg);    
            }
            
        g_mtp_track_obj.OnLegDone = function(track_name, track_length) {
            var msg = "Track " + track_name + " Loaded. Track Lenght: " + track_length + " Km";
            TrackStatusText(msg);
            TrackStatusImg("/images/null.gif");
            show_track_properties();
            }     
        }
        
    g_mtp_track_obj.Load(this, this.wl_index, this.wl_user_id, this.wl_race_id);    
    return;
}

//  Race loaders
function ParseResponse(reply) {

    var content = new Array();
    var token = "";
    var value = "";
    var type = "";
    var races = new Array();
    var glat;
    var glon;


    //  remove all the current markers
    g_marker_manager.clearMarkers();  
    
    content = reply.split(";");
    for (i = 0; i < content.length; i++) {
        token = content[i].substr(0, 3);    //  token
        value = content[i].substr(3);       //  value

        if (token == "ty=") {
            type = value;
        }
        else if (token == "ok=") {
        }
        else if (token == "er=") {
            alert("ERROR(" + value + ") The races could not be loaded.");
            return false;
        }
        else if (token == "id=") 
        {
            if ((type == "races") || (type == "mytrack"))
            {
                //  create the marker
                var prop = value.split(",");
                //  prop [0] id, [1] glat, [2] glong, [3] userid, [4] raceid, [5] usage, [6] user_nickname
                var marker = new GMarker(new GLatLng(parseFloat(prop[1]), parseFloat(prop[2])));
                marker.wl_index = parseInt(prop[0]);    //  index assigned by db for the race
                marker.wl_user_id = parseInt(prop[3]);  //  index of the user that owns the race
                marker.wl_race_id = parseInt(prop[4]);  //  index of the race (as owned by the user)
                marker.wl_usage = parseInt(prop[5]);    //  if usage is greater than 0, then there are some challengers
                marker.wl_user_nickname = prop[6];      //  the nickname of the user author of this race

                if (type == "mytrack") {
                    //  center the map onto the track start
                    glat = prop[1];
                    glon = prop[2];
                }                

                GEvent.addListener(marker, "click", OnMarkerClick);
                //  new release
                GEvent.addListener(marker, "mouseover", OnMarkerOver);                
                
                races.push(marker);
                if (races.length > 20) 
                {
                    //  Push the markers to the MarkerManager
                    g_marker_manager.addMarkers(races, 8);
                    while (races.length > 0) { races.pop(); }
                }        
            }
        }
    } // for

    //  check if there are any races left
    if (races.length > 0) {
        if (type == "mytrack") {
            //  center the map onto the track start
            g_map.setCenter(new GLatLng(parseFloat(prop[1]), parseFloat(prop[2])), 8);
        }    
        g_marker_manager.addMarkers(races, 8);
        while (races.length > 0) { races.pop(); }
    }
    else {
        if (type == "mytrack") {
            alert("No track was found");
        }
    }
    
    g_marker_manager.refresh();

    
    return true;
}

function onLoadRaces() {
    if (g_rest_request.readyState != 4) {
        return;
    }

    ParseResponse(g_rest_request.responseText);
    //  reset the text in the track status div
    TrackStatusText("");
    TrackStatusImg("/images/null.gif");
}


function race_ext_bounds() {    
    g_races_bounds = g_map.getBounds();
    var sw = g_races_bounds.getSouthWest();
    var ne = g_races_bounds.getNorthEast();
    var lat_delta = (ne.lat() - sw.lat()) * 3.0;
    var lng_delta = (ne.lng() - sw.lng()) * 3.0;

    var new_sw = new GLatLng((sw.lat() - lat_delta), (sw.lng() - lng_delta));
    var new_ne = new GLatLng((ne.lat() + lng_delta), (ne.lng() + lng_delta));
    
    //  extend the boundaries so to optimize races download
    g_races_bounds.extend(new_sw);
    g_races_bounds.extend(new_ne);
}

function load_race(track_index) {
    {
        TrackStatusText("Loading races ...");
        TrackStatusImg("/images/loading.gif");
    }

    //  send the request
    var rest_request = "/scripts/wl_load_races.php?type=mytrack&rid=" + track_index;

    g_rest_request = createXMLHttpRequest();
    if (g_rest_request == null) { return false; }

    g_rest_request.open("GET", rest_request, true);
    g_rest_request.onreadystatechange = onLoadRaces;
    g_rest_request.send(null);

    return true;
}



function load_races() {
    if (g_races_bounds == null) {
        //  Set the bounds for the race zoom level. The g_race_bounds is larger than
        //  the current map's bound so to optimize dragging
        race_ext_bounds();
    }
    else {
        //  The g_races_bounds has been initialized, already, so check if the
        //  current map is within the prev "extended" bounds
        var cb = g_map.getBounds();
        if (g_races_bounds.containsBounds(cb)) { return true; } //  the races have been downloaded, already
        //  we need another extended bounds
        race_ext_bounds();
    }

    {
        TrackStatusText("Loading races ...");
        TrackStatusImg("/images/loading.gif");
    }
    
    
    //  Get the current g_map's bounds. The bounds contains the SouthWest and the NorthEast "corners"
    var south_west = g_races_bounds.getSouthWest().toUrlValue(6).split(",");
    var north_east = g_races_bounds.getNorthEast().toUrlValue(6).split(",");
    //  get all the races that are inside the current bound
    var rest_request = "/scripts/wl_load_races.php?type=races&swlat=" + south_west[0] + "&swlng=" + south_west[1] + "&nelat=" + north_east[0] + "&nelng=" + north_east[1];
    //  alert(request);

    g_rest_request = createXMLHttpRequest();
    if (g_rest_request == null) { return false; }

    g_rest_request.open("GET", rest_request, true);
    g_rest_request.onreadystatechange = onLoadRaces;
    g_rest_request.send(null);

    return true;    
}


//  Race Show(s)
function show_countries()
{
    //  alert("Show country");
    //  Show all the countries where at least one race has been published.
    //  The countries that are being shown are inside the current map's bounds.
}

function show_regions()
{
    //  alert("Show region");
    //  Show all the regions where at least one race has been published.
    //  The regions that are being shown are inside the current map's bounds.
}

function show_races()
{
    //  alert("Show race");
    //  Show all the races that has been published.
    //  The races to be shown must be inside the current map's bounds.

    //  The races are appended to the previously loaded races.
    load_races();
}

function show_none() 
{
    //alert("Show none");
    //  Do not show anything.
    //  (Possibly) remove all the overlays
}

//  Event Handlers
function OnZoomEnd(old_level, new_level)
{
    //  alert("old :" + old_level + " new:" + new_level);
    
    if (new_level < 3) {
        if (g_zoom_level != "none") {
            g_zoom_level = "none";
            show_none();
        }
    }
    else if ((new_level >= 3) && (new_level < 6)) {
        if (g_zoom_level != "countries") {
            g_zoom_level = "countries";
            show_countries();
        }
    }
    else if ((new_level >= 6) && (new_level < 8)) {
        if (g_zoom_level != "regions") {
            g_zoom_level = "regions";
            show_regions();
        }
    }
    else if (new_level >= 8) {
        if (g_zoom_level != "races") {
            g_zoom_level = "races";
            show_races();
        }
    }
}

function OnDragEnd() {
    //alert("Dragend");
    //  This handler manages the map move
    if (g_zoom_level == "none") { return; }
    else if (g_zoom_level == "countries") { show_countries(); }
    else if (g_zoom_level == "regions") { show_regions(); }
    else if (g_zoom_level == "races") { show_races(); }
}



//  Initializtion

function LoadPopup() {
    new popUp
(
    200,480,200,200,"UserPopupId","#","#FFFFFF","lightgrey","9pt sans-serif","User Details","#0084d8","lightgrey","gray","#00468c","black",false,                  //  is_hidden_on_start - Specifies whether the popup is initially "closed". true or false [NOTE: seems to be the other way around]
    true,true,true,true,false,'/images/min.gif','/images/max.gif','/images/close.gif','/images/resize.gif'
);

    new popUp
(
    200, 200, 700, 200, "RacePostId", "#", "#FFFFFF", "lightgrey", "9pt sans-serif", "Race Post", "#0084d8", "lightgrey", "gray", "#00468c", "black", false,                  //  is_hidden_on_start - Specifies whether the popup is initially "closed". true or false [NOTE: seems to be the other way around]
    true, true, true, true, false, '/images/min.gif', '/images/max.gif', '/images/close.gif', '/images/resize.gif'
);

    new popUp
(
    200, 200, 400, 100, "RaceUrlId", "#", "#FFFFFF", "black", "9pt sans-serif", "Race URL", "#0084d8", "lightgrey", "gray", "#00468c", "black", false,                  //  is_hidden_on_start - Specifies whether the popup is initially "closed". true or false [NOTE: seems to be the other way around]
    true, false, true, false, false, '/images/min.gif', '/images/max.gif', '/images/close.gif', '/images/resize.gif'
);

}

function LoadMap(single_track) {
    //  This function is called during page load (body onload)
    //  The user will select the race of interest by navigating the map.

    //  create the map
    var map_div = "MapBlock";
    var map_container = document.getElementById(map_div);
    if (!map_container) {
        alert("No map div");
        return false;
    }

    if (g_map == null) {
        //  create the map object
        //g_map = new GMap2(map_container, { draggableCursor: "crosshair" });
        g_map = new GMap2(map_container);

        //  set the properties of the map
        g_map.enableDoubleClickZoom();
        g_map.enableScrollWheelZoom();
        g_map.enableContinuousZoom();
        //g_map.addMapType(G_SATELLITE_3D_MAP);
        g_map.addMapType(G_PHYSICAL_MAP);

        g_map.addControl(new GMapTypeControl());
        g_map.addControl(new GLargeMapControl());
        g_map.addControl(new GScaleControl());        
    }
    
    
    if (g_icon_totem == null) {
        //  load the totem icon
        g_icon_totem = new GIcon();
        g_icon_totem.image = '/images/totem.png';
        g_icon_totem.shadow = '';
        g_icon_totem.iconSize = new GSize(22, 22);
        g_icon_totem.shadowSize = new GSize(0, 0);
        g_icon_totem.iconAnchor = new GPoint(18, 4);
        g_icon_totem.infoWindowAnchor = new GPoint(18, 4);
        g_icon_totem.dragCrossImage = 'empty.gif'; // undocumented String: indicates an image to be used as the drag cross. If you set it to the null string, you get the default drag_cross_67_16.png image.
        g_icon_totem.dragCrossSize = GSize(1, 1); //undocumented GSize(): indicates the size of the drag cross.
        g_icon_totem.maxHeight = 1; //undocumented integer: The maximum difference in height between the marker anchor and the drag cross anchor during dragging. Setting the maxHeight to zero causes it to use the default 13.
    }
    

    //  set the center and the zoom of the map as defined in the original track definition file
    g_map.setCenter(new GLatLng(40.0, -20.0), 2);
    //g_bounds = g_map.getBounds();


    //  Map events
    //  Event listener for the zoomend event
    if (!single_track) {
        GEvent.addListener(g_map, 'zoomend', OnZoomEnd);
        //  Event listener for the movend event
        GEvent.addListener(g_map, 'dragend', OnDragEnd);
    }



    //  Marker Manager for the races
    g_markers = new Array();
    g_marker_manager = new MarkerManager(g_map);

    //  Marker Manager for the totems
    g_totem_manager = new MarkerManager(g_map);
        
    return true;
}


function LoadDispatcher() {
    //  This function is called when the onload event fires
    LoadPopup();

    //  Load my track
    var elem = document.getElementById("RID");
    if (elem) {
        LoadMap(true);
        //  load the referenced track
        var track_index = elem.innerHTML;
        load_race(track_index);
    }
    else { LoadMap(false); }
    
}

function ResetOriginalData() {
    if (g_original_polys) { 
        while (g_original_polys.length > 0) { 
            var gov = g_original_polys.pop(); 
            if (g_map) {
                g_map.removeOverlay(gov);
            }                
        } 
    }
    if (g_original_totems) { while (g_original_totems.length > 0) { g_original_totems.pop(); } }
    if (g_totem_manager) { g_totem_manager.clearMarkers(); g_totem_manager.refresh(); }
}


function EnableSelectionButton(enabled) {
    var elem = document.getElementById("selection_type");
    if (!elem) { return; }

    if (enabled == true) {
        //  The button has to be enabled. A race has been selected so
        //  the user has to be able to go back to "large view"
        elem.disabled = null;
        elem.setAttribute("src", "/images/globe.gif");
        elem.onmouseover = function() { Img(this, '/images/globe_over.gif'); }
        elem.onmouseout = function() { Img(this, '/images/globe.gif'); }
        elem.onclick = Selection;
    }
    else {
        //  No race has been selected, so there is no need to enable
        //  the large view button
        elem.disabled = true;
        elem.onmouseover = null;
        elem.onmouseout = null;        
        //elem.setAttribute("onmouseover", null);
        //elem.setAttribute("onmouseout", null);
        elem.setAttribute("src", "/images/null.gif");
        elem.onclick = null;    
    }
}


function RacePost(evt) {
    ShowPost(32, 200, 200);    
}

function EnablePostButton(enabled) {
    var elem = document.getElementById("race_post");
    if (!elem) { return; }

    if (enabled == true) {
        //  The button has to be enabled. A race has been selected so
        //  the user has to be able to post about the race
        elem.disabled = null;
        elem.setAttribute("src", "/images/post.gif");
        elem.onmouseover = function() { Img(this, '/images/post_over.gif'); }
        elem.onmouseout = function() { Img(this, '/images/post.gif'); }
        //elem.onclick = RacePost;
        //  TODO - find a solution so to avoid browser detection
        var browser = navigator.appName;
        if (browser.match("Microsoft")) {
            //  the following works with Microsoft explorer
            elem.onclick = function() { RacePost(event); }
        }
        else {
            //  the following works with Firefox
            elem.onclick = function(event) { RacePost(event); }
        }
        
    }
    else {
        //  close the Post Popup
        fadeboxout('RacePostId');
        //  No race has been selected, so the user cannot post
        elem.disabled = true;
        elem.onmouseover = null;
        elem.onmouseout = null;                
        //elem.setAttribute("onmouseover", null);
        //elem.setAttribute("onmouseout", null);
        elem.setAttribute("src", "/images/null.gif");
        elem.onclick = null;
    }
}


function NavOnStart() {
    if (g_mtp_track_obj) { g_mtp_track_obj.NavStart(); }
}
function NavOnNext() {
    if (g_mtp_track_obj) { g_mtp_track_obj.NavNext(); }
}
function NavOnPrev() {
    if (g_mtp_track_obj) { g_mtp_track_obj.NavPrev(); }
}
function NavOnEnd() {
    if (g_mtp_track_obj) { g_mtp_track_obj.NavEnd(); }
}
function NavOnLink() {
    if (g_mtp_track_obj) {
        var race_url = "http://www.mindthepedal.com/c_races.html?rid=" + g_mtp_track_obj.i_uid;
        ShowRaceUrl(race_url);
        }
}


function SetSelection(mode) {
    //  if status is 1 then the Selection button has to be disabled (a race has been selected)
    //  if status is 2 then the Selection button has to be enabled (no race is currently selected)

        //  this has been tested with IE
        if (mode == 1) {
            EnableSelectionButton(false);
            EnablePostButton(false)

            //  reset the track object
            if (g_mtp_track_obj) { g_mtp_track_obj.Reset(); }
            
            //  back to the last saved global view
            
            if (g_map) {
                //  reset waypoints and overlays
                g_map.clearOverlays();
                g_map.setCenter(g_center, g_zoom);
            }

            //  reset original data (if any)
            ResetOriginalData();

            //  reset data race table and the waypoints selection list
            ResetTable("RaceDataBody");
            ResetSelection("WaypointSelection");
            

            SetUploadButton(false);     //  disable upload button
            SetDataRaceButton(false);   //  disable data race button
            SetCurrentToken(null);
            if (g_nav_bar_obj != null) { g_nav_bar_obj.Hide(); }
            
        } else {
            EnableSelectionButton(true);
            EnablePostButton(true);
            //  show nav bars
            if (g_nav_bar_obj == null) {
                g_nav_bar_obj = new mtp_track_nav();
                //  handlers
                g_nav_bar_obj.OnStart = NavOnStart;
                g_nav_bar_obj.OnPrev = NavOnPrev;
                g_nav_bar_obj.OnNext = NavOnNext;
                g_nav_bar_obj.OnEnd = NavOnEnd;
                g_nav_bar_obj.OnLink = NavOnLink;
            }
            g_nav_bar_obj.Show();
            
            //  store the map properties before going to race view ...
            if (g_selection_mode == 1) {
                //  ... only if the current mode is 1 (global view)
                if (g_map) {
                    g_zoom = g_map.getZoom();           //  get last global zoom
                    g_center = g_map.getCenter();       //  get last global map center            
                }
            }
            
        }
        
    g_selection_mode = mode;
}

function Selection() {

    //  go back to the "super map"    
    SetSelection(1);
    return true;
}

function ResetSelection(elem_name) {
    var drop_down = document.getElementById(elem_name);
    if (!drop_down) { return false; }
    while (drop_down.lastChild) {
        drop_down.removeChild(drop_down.lastChild);
    }

    return true;
}


function ResetTable(elem_name) {

    var tbody = document.getElementById(elem_name);
    if (!tbody) { return false; }

    //  reset the tbody
    while (tbody.lastChild) {
        tbody.removeChild(tbody.lastChild);
    }

    return true;
}

function PopulateSelection(elem_name, g_race_entries) {
    //  this function populates the selection dropdown box with the number of waypoints
    //  The number of waypoints is obtained using the length of the array that contains
    //  all the elapsed time
    if (g_race_entries == null) { return false; }
    if (g_race_entries.length == 0) { return false; }
    //  get the first entry
    var re = g_race_entries[0];
    if (re.race_times == null) { return false; }
    var num_of_wps = re.race_times.length;
    
    //  get the selection element
    var drop_down = document.getElementById(elem_name);
    if (!drop_down) { return false; }

    var i = 1;
    for (; i <= num_of_wps; i++) {
        var new_option = document.createElement("option");
        new_option.setAttribute("value", (i - 1));
        if (i == num_of_wps) {
            // set the last option as selected
            new_option.setAttribute("selected", true);
        }
        new_option.appendChild(document.createTextNode(i.toString()));
        drop_down.appendChild(new_option);
    }

    //  enable the drop down
    drop_down.disabled = null;

    return true;
}

function RefreshRows(elemname) {
    var tbody = document.getElementById("RaceDataBody");
    if (!tbody) return;
    var rows = tbody.getElementsByTagName("tr");
    
    var grey = 0;
    for (i = 0; i < rows.length; i++) {
        if (grey > 0) { rows[i].bgColor = '#dddddd'; grey = -1; }
        else { rows[i].bgColor = '#ffffff'; }
        grey++;
    }
    
    return;
}

function ParseOriginalData(data) {
    //alert("Original Data: [" + data + "]");

    if (g_original_polys == null)
        g_original_polys = new Array();
    else {
        //  remove the overlays (reset the array and removes the overlays from the g_map obj)
        while (g_original_polys.length > 0) {
            var gov = g_original_polys.pop();
            if (g_map) {
                g_map.removeOverlay(gov);
            }
        }
    }        
    
    if (g_original_totems == null)
        g_original_totems = new Array();
    else {
        //  remove the overlays
        while (g_original_totems.length > 0) { g_original_totems.pop(); }
    }
    if (g_totem_manager) { g_totem_manager.clearMarkers(); g_totem_manager.refresh(); }
    
    
    var points = new Array();
    var token = "";
    var value = "";
    var content = data.split(";");
    for (i = 0; i < content.length; i++) {
        token = content[i].substr(0, 3);    //  token
        value = content[i].substr(3);       //  value

        if (token == "pt=") {
            //  to be displayed
            var fields = value.split(",");
            var p_lat = parseFloat(fields[0]);
            var p_lon = parseFloat(fields[1]);            
            
            points.push(new GLatLng(p_lat, p_lon));
            if (points.length >= 200) {
                var gpoly = new GPolyline(points,"#ff0000",2,1);
                g_original_polys.push(gpoly);
                while (points.length > 0) { points.pop(); }
                
                points.push(new GLatLng(p_lat, p_lon));
            }

            // New Version
            if (fields.length > 4) {
                //  the original file contains the 'totem' flag
                if (fields[4] == "1") {
                    //  This point is a totem, it can be displayed on the map
                    if (g_original_totems != null) {
                        var totem = new GMarker(new GLatLng(p_lat, p_lon), g_icon_totem);
                        g_original_totems.push(totem);
                    }                   
                }
            }
        }
        else if (token == "ok=") {
        }
        else if (token == "tk=") {
        }        
        else if (token == "er=") {
            alert("ERROR(" + value + ") The original data could not be loaded.");
            return false;
        }
    }
    
    if (points.length > 0)
    {
        var gpoly = new GPolyline(points, "#ff0000", 2, 1);
        g_original_polys.push(gpoly);
        //  add the new polylines
        if (g_map) {
            for (i = 0; i < g_original_polys.length; i++) {
                g_map.addOverlay(g_original_polys[i]);
            }                             
        }
    }

    if (g_totem_manager != null) {
        if (g_original_totems != null) {
            if (g_original_totems.length > 0) {
                g_totem_manager.addMarkers(g_original_totems, 8);
                g_totem_manager.refresh();
            }
        }
    }
    
}

function onLoadOriginalData() {
    if (g_rest_originaldata.readyState != 4) {
        return;
    }

    ParseOriginalData(g_rest_originaldata.responseText);

    {
        //  set the load original button img
        var elem = document.getElementById("race_gpx");
        if (elem) {
            elem.disabled = null;
            elem.setAttribute("src", "/images/original_data.gif");
        }
    }

}

function LoadOriginalData() {
    //  request the original data from the server the web server requires the token of the race
    {
        //  set the load original button img
        var elem = document.getElementById("race_gpx");
        if (elem) {
            elem.disabled = true;
            elem.setAttribute("src", "/images/loading.gif");
        }
    }

    var rest_request = "/scripts/wl_load_originaldata.php?u=" + g_current_challenger + "&r=" + g_current_token;
    g_rest_originaldata = createXMLHttpRequest();
    if (g_rest_originaldata == null) { return false; }

    g_rest_originaldata.open("GET", rest_request, true);
    g_rest_originaldata.onreadystatechange = onLoadOriginalData;
    g_rest_originaldata.send(null);
    
    return true;
}


function ParseDelOriginalData(data) {
    //alert(data);
    
    content = data.split(";");
    var token = "";
    var value = "";
    var reply_token = "";
    var token_ok = false;
    for (i = 0; i < content.length; i++) {
        token = content[i].substr(0, 3);    //  token
        value = content[i].substr(3);       //  value

        if (token == "er=") {
            alert("Error while deleting race data");
            return;
        }
        else if (token == "ok=") {
        }
        else if (token == "tk=") {
            //  here the token is sent back in order to facilitate the process
            reply_token = value;
            token_ok = true;
        }
    }



    if (token_ok == true) {        
        //  the token was assigned, process it
        //  --> remove the row from the table
        //  --> remove the selection from the table
        //  --> set g_current_token etc to null
        if (g_race_entries != null) {
            
            for (i = 0; i < g_race_entries.length; i++) {
                if (g_race_entries[i].token == reply_token) {
                
                    
                    //  remove the race entry from the table data
                    g_race_entries.splice(i, 1);

                    //  Reset the interface
                    SetCurrentToken(null);
                    //  Reset the table
                    ResetTable("RaceDataBody");
                    //  Show the table
                    PopulateTable("RaceDataBody", g_race_entries);

                    return;
                }
            }
        }
    }
}

function onDelOriginalData() {
    if (g_rest_deloriginal.readyState != 4) {
        return;
    }
    ParseDelOriginalData(g_rest_deloriginal.responseText);
}

function DeleteOriginal() {
    //  The function deletes the original data
    //  The original data reference is to be found in the table challenges and it is identified
    //  by the token (sent as an argument to the web server) and by the id of the currently
    //  logged user
    if (g_current_token == null) { return false; }
    var rest_request = "/scripts/wl_del_originaldata.php?t=" + g_current_token;
    g_rest_deloriginal = createXMLHttpRequest();
    if (g_rest_deloriginal == null) { return false; }

    g_rest_deloriginal.open("GET", rest_request, true);
    g_rest_deloriginal.onreadystatechange = onDelOriginalData;
    g_rest_deloriginal.send(null);

    return true;
}


function SetCurrentToken(token) {

    if (g_current_token == token) return;
    
    var elem = document.getElementById("race_gpx");
    if (!elem) return;
    
    if (token == null) {
        //  disable original data button
        elem.disabled = true;
        elem.setAttribute("src", "/images/null.gif");
        elem.onmouseover = null;
        elem.onmouseout = null;
        elem.onclick = null;
        
    } else {
        //  enable original data button
        elem.disabled = null;
        elem.setAttribute("src", "/images/original_data.gif");
        elem.onmouseover = function() { Img(this, '/images/original_data_over.gif'); }
        elem.onmouseout = function() { Img(this, '/images/original_data.gif'); }
        elem.onclick = LoadOriginalData;
    }

    g_current_token = token;
    g_current_challenger = null;
    {
        var row_del = document.getElementById("data_del");
        if (row_del) {
            row_del.setAttribute("src", "/images/null.gif");
            row_del.disabled = true;
            row_del.onmouseover = null;
            row_del.onmouseout = null;
        }
    }

    if (token == null) return;
        
    if (g_race_entries) {
        //  set the current challenger
        for (i = 0; i < g_race_entries.length; i++) {
            if (g_race_entries[i].token == token) {
                g_current_challenger = g_race_entries[i].challenger_id;
                {
                    var lelem = document.getElementById("LogIdx");
                    if (lelem) {
                        if (g_current_challenger == lelem.innerHTML) {
                            //  here we can activate the deletion of the selected row
                            var row_del = document.getElementById("data_del");
                            if (row_del) {
                                row_del.disabled = null;
                                row_del.setAttribute("src", "/images/basket.gif");
                                row_del.onmouseover = function() { Img(this, '/images/basket_over.gif'); };
                                row_del.onmouseout = function() { Img(this, '/images/basket.gif'); };
                                row_del.onclick = function() { DeleteOriginal(); }
                            }
                        }
                    }
                }
                return;
            }
        }
    }    
}

function RowSelection(row) {

    RefreshRows("RaceDataBody");
    row.bgColor = "#5555ff";

    //  set the global g_current_token
    SetCurrentToken(row.getAttribute("id"));
}

function FormatElapsed(secs) {
    /*
        arg:    secs
                the total number of seconds
        return:
                a string in the format hh:mm:ss                
    */
    
    var tot;
    var ela_hours = (secs - (secs % 3600)) / 3600;
    tot = secs - (ela_hours * 3600);
    var ela_mins = (tot - (tot % 60)) / 60;
    var ela_secs = secs - (ela_hours * 3600) - (ela_mins * 60);

    var str_hours = ela_hours.toString();
    var str_mins = ela_mins.toString();
    var str_secs = ela_secs.toString();

    if (str_hours.length < 2) { str_hours = "0" + str_hours; }
    if (str_mins.length < 2) { str_mins = "0" + str_mins; }
    if (str_secs.length < 2) { str_secs = "0" + str_secs; }

    var str_elapsed = str_hours + ":" + str_mins + ":" + str_secs;
    return str_elapsed;    
}


function AppendRow(rtable, entry, bgcolor) {
    //  rtable  :       reference to the tbody element
    //  entry   :       a race entry object
    //  bgColor :       the background color for the current row

    //  create the row
    var row = document.createElement("tr");
    row.setAttribute("name", "data");
    row.setAttribute("id", entry.token);
    row.onclick = function() { RowSelection(this); };
    row.bgColor = bgcolor;

    //  first column - challenger_nickname/challenger_id
    var challenger_id = document.createElement("td");
    {
        var challenger_name = entry.challenger_nickname;
        if (challenger_name.length == 0) {
            challenger_name = "(" + entry.challenger_id + ")"
        }
        var challenger_entry = document.createElement("a");
        challenger_entry.className = "UserRef"; // or challenger_entry.setAttribute("class", "UserRef");
        challenger_entry.href = "#";
        challenger_entry.user_id = entry.challenger_id;


        //  TODO - find a solution so to avoid browser detection
        var browser = navigator.appName;
        if (browser.match("Microsoft")) {
            //  the following works with Microsoft explorer
            challenger_entry.onclick = function() { ShowUser(this, event, 50, -50); }
        }
        else {
            //  the following works with Firefox
            challenger_entry.onclick = function(event) { ShowUser(this, event, 50, -50); }
        }
                                       
        // challenger_entry.onclick = function() { ShowUserFixed(this, 550, 350); }
        
        challenger_entry.appendChild(document.createTextNode(challenger_name));
        challenger_id.appendChild(challenger_entry);
    }

    //  second column - race_date
    var race_date = document.createElement("td");
    race_date.appendChild(document.createTextNode(entry.race_date));

    //  third column - gps_error
    var gps_error = document.createElement("td");
    gps_error.appendChild(document.createTextNode(entry.gps_error));

    //  fourth column - race_times
    var elapsed_value = FormatElapsed(entry.cur_elapsed);
    var elapsed = document.createElement("td");
    elapsed.appendChild(document.createTextNode(elapsed_value));

    //  append the columns to the row
    row.appendChild(challenger_id);
    row.appendChild(race_date);
    row.appendChild(gps_error);
    row.appendChild(elapsed);

    //  append the row to the table
    rtable.appendChild(row);
}


function PopulateTable(elem_name, race_entries) {
    var rtable = document.getElementById(elem_name);
    if (!rtable) { return false; }

    //  all the race entries have to be added here
    var i = 0;
    var grey = 0;
    var bgColor = "";
    for (i = 0; i < race_entries.length; i++) {
        //  append the row
        if (grey > 0) { bgColor = '#dddddd'; grey = -1; }
        else { bgColor = '#ffffff'; }
        grey++;

        AppendRow(rtable, race_entries[i], bgColor);
    }
    
    return true;
}

function SetWaypoint(elem) {
    if (!elem) { return; }
    if (g_race_entries == null) { return; }
    if (g_race_entries.length == 0) { return; }
    
    if (elem.selectedIndex >= 0) {
        //  the elem.value is the index of the entry.race_time
        var wp_idx = parseInt(elem.value);
        //  re is the object representing the current record
        var re = g_race_entries[0];
        //  using the first record, check if the waypoint idx is valid (all the entries
        //  in the current race must have the same length)
        if (re.race_times.length <= wp_idx) { alert("Invalid Waypoint"); }

        var i = 0;
        for (; i < g_race_entries.length; i++) {
            re = g_race_entries[i];
            if (wp_idx == 0) { re.cur_elapsed = 0; }            //  first waypoint (race starting point)
            else { re.cur_elapsed = re.race_times[wp_idx]; }
        }

        ResetTable("RaceDataBody");
        PopulateTable("RaceDataBody", g_race_entries);  
    }
}


function compare_num(a, b) {
    return (a.sort_num - b.sort_num);
}

function compare_str(a, b) {
    var str_a = a.sort_str.toLowerCase();
    var str_b = b.sort_str.toLowerCase();
    if (str_a < str_b) { return -1; }
    if (str_a > str_b) { return 1; }
    return 0;
}

function Sort(elem) {
    // alert("Sort");

    if (!elem) { return; }
    var id_attr_val = elem.getAttribute("id");
    var sort_type = id_attr_val.substr(0, 2);
    var sort_col = id_attr_val.substr(3);
    var i;

    //  sort type can be UP or DN
    //  sort_col can be: ruserid, rdate, rgps, relapsed

    //  process the sorting
    if (sort_col == "ruserid") {
        for (i = 0; i < g_race_entries.length; i++) {
            var re = g_race_entries[i];
            re.sort_num = re.challenger_id;
        }
        //  apply sort on sort_num
        g_race_entries.sort(compare_num);
    }
    else if (sort_col == "rdate") {
        for (i = 0; i < g_race_entries.length; i++) {
            var re = g_race_entries[i];
            re.sort_str = re.race_date;
        }
        //  apply sort on sort_str
        g_race_entries.sort(compare_str);
    }
    else if (sort_col == "rgps") {
        for (i = 0; i < g_race_entries.length; i++) {
            var re = g_race_entries[i];
            re.sort_num = re.gps_error;
        }
        //  apply sort on sort_num
        g_race_entries.sort(compare_num);
    
    }
    else if (sort_col == "relapsed") {
        for (i = 0; i < g_race_entries.length; i++) {
            var re = g_race_entries[i];
            re.sort_num = re.cur_elapsed;
        }
        //  apply sort on sort_num
        g_race_entries.sort(compare_num);
    
    }

    //  change versus
    var new_img = "";
    if (sort_type == "UP") {
        new_img = "/images/sort_down.gif";
        sort_col = "DN_" + sort_col;
    } else {
        new_img = "/images/sort_up.gif";
        sort_col = "UP_" + sort_col;
        g_race_entries.reverse();
    }
    
    //  ResetTable
    //  PopulateTable
    ResetTable("RaceDataBody");
    PopulateTable("RaceDataBody", g_race_entries);
    

    //  set the properties
    elem.setAttribute("id", sort_col);
    elem.setAttribute("src", new_img);
    elem.onmouseout = function() { Img(this, new_img); }    
}

function RaceEntry(record) {
    //  record is a string in the format
    //  challenger_id, challenger_nickname, race_date, gps_error, token, racetimes
    if (record == null) return;
    if (record.length <= 0) return;
    
    var fields = record.split(",");
    
    //  challenger_id
    this.challenger_id = parseInt(fields[0]);

    //  challenger_nickname
    this.challenger_nickname = fields[1];

    //  original date
    var shortdate = fields[2].split(" ");
    this.race_date = shortdate[0];

    //  gps error
    var shortgpsdelta = fields[3].substr(0, 10);
    this.gps_error = parseFloat(shortgpsdelta);

    //  token
    this.token = fields[4];

    //  race times
    this.race_times = new Array();
    //  Copy the times into the race_times array
    var fi = 5;
    for (; fi < fields.length; fi++) {
        this.race_times.push(parseInt(fields[fi]));
    }

    this.cur_elapsed = this.race_times[this.race_times.length - 1];    
}

function ParseRaceData(srv_reply) {

    //alert(srv_reply);
    
    var reply = new Array();
    var token = "";
    var value = "";
    var t_ok = false;

    reply = srv_reply.split(";");
    
    for (i = 0; i < reply.length; i++) {
        token = reply[i].substr(0, 3);    //  token
        value = reply[i].substr(3);       //  value


        if (token == "er=") {
            //  TODO error management
            return false;
            }
            else if (token == "ok=") {
                t_ok = true;
            }
            else if (token == "re=") {
                // race entry
                var re = new RaceEntry(value);
                g_race_entries.push(re);              
            }            
    }

    

    if (t_ok == true) {
        // reset the current challenges table
        ResetTable("RaceDataBody");
        ResetSelection("WaypointSelection");
        
        if (g_race_entries.length > 0)
        {
            //  update the table
            PopulateTable("RaceDataBody", g_race_entries);
            PopulateSelection("WaypointSelection", g_race_entries);
            return true;
        }
        
        return true;
    }
    
    return false;
}



function onLoadRaceData() {
    if (g_rest_request.readyState != 4) { return; }

    ParseRaceData(g_rest_request.responseText);
    //  set the load original button img
    SetDataRaceButton(true);
}


function LoadRaceData(user_id, track_id) {
    //  loading the timetables (from challenges) for the track (user_id, track_id)
    {
        //  set the load original button img
        var elem = document.getElementById("race_data");
        if (elem) {
            elem.disabled = true;
            elem.setAttribute("src", "/images/loading.gif");
        }
    }
    

    //  reset the array containing the race entries
    if (g_race_entries == null) { g_race_entries = new Array(); }
    else { while (g_race_entries.length > 0) { g_race_entries.pop(); } }


    var now_date = new Date();
    var rest_request = "/scripts/wl_race_data.php?u=" + user_id + "&r=" + track_id + "&seq=" + now_date.getTime();

    g_rest_request = createXMLHttpRequest();
    if (g_rest_request == null) { return false; }

    g_rest_request.open("GET", rest_request, true);
    g_rest_request.onreadystatechange = onLoadRaceData;
    g_rest_request.send(null);
    
}


function RaceData() {
    //  The button "Race Data" has been pressed. Now we need to show
    //  all the challengers - and their elapsed
    if (g_mtp_track_obj == null) { return false; }
            
    //  The race data has not been loaded, yet, load the race data
    LoadRaceData(g_mtp_track_obj.i_author_id, g_mtp_track_obj.i_track_id);
    return true;
}




function SetAuthorProps(elem_id, user_nickname, user_id) {
    var elem = document.getElementById(elem_id);
    if (elem == null) { return; }
    
    if (user_nickname.length > 0) { elem.innerHTML = user_nickname; }
    else { elem.innerHTML = "(" + user_id + ")"; }

    //  set the onclick attribute
    elem.user_id = user_id;

    //  TODO - find a solution so to avoid browser detection
    var browser = navigator.appName;
    if (browser.match("Microsoft")) {
        //  the following works with Microsoft explorer
        elem.onclick = function() { ShowUser(this, event, -100, 10); }
    }
    else {
        //  the following works with Firefox
        elem.onclick = function(event) { ShowUser(this, event, -100, 10); }
    }
}


function show_track_properties(track_obj) {
    //  NEW VERSION
    //  displays track properties such as country name and region
    if (track_obj == null) { return; }
    var propbar = document.getElementById("TrackPropertiesDiv");
    if (propbar) {
        //  set the country property
        var CountryProp = document.getElementById("CountryProp");
        if (CountryProp) {
            CountryProp.innerHTML = track_obj.i_country;
        }
        //  set the region property
        var RegionProp = document.getElementById("RegionProp");
        if (RegionProp) {
            RegionProp.innerHTML = track_obj.i_region;
        }

        //  set the author
        SetAuthorProps("AuthorProp", track_obj.i_author_nickname, track_obj.i_author_id);
    }
}


