// Lastest changes
// Reduce server calls by keeping ID in cookie for a direct call to populate on restart.

window.onload = function() { if (window.myStart && myStart) {
    getRiderNames(myStart);
 } else { cookieCheck(); } }

var picHttp, artHttp, resHttp, praHttp, basicsHttp;
var typedSize = 0;
var http = createRequestObject();
httpLock = 0;
var listCache = {};
var namesToShow;
var idList;
var currID = 0;

function askPin() {
    return 'To see your private practice times, please enter your 5-digit PIN.<br>'
      + '<form name="form_pin_select" action="javascript:void(null)">'
      + '  <input type="text" name="input_pin_text" value=""'
      + '  onkeyup="getPrac('
      + '  window.document.form_pin_select.input_pin_text.value)">'
      + '</form>';
}

function getPrac(pinArg) {
    if (pinArg.length == 5) {
        getPractice(pinArg);
    }
}

function getPractice(pinArg) {    
    // myPractice
    // If there's a pin, try to get data.  If not, still check for whether they have a pin.
    praHttp = createRequestObject();
    // Removed leading slash so it works in temporary BlueHost acct.
    var myreq4 = 'wp-content/ajax/prac.php';
    //praHttp.open('POST', myreq4);
    praHttp.open('GET', myreq4 + "?action=getPractice&id="+currID+"&pin="+pinArg);
    praHttp.onreadystatechange = handlePractice;
    praHttp.send(null);
    //praHttp.send("action=getPractice&id="+currID+"&pin="+pinArg);
}

function handlePractice() {
    if (praHttp.readyState == 4) {
        // On a good match, we just get results.
        divData['pra']['text'] = praHttp.responseText;
        // But there are other cases.
        var lead = praHttp.responseText.substr(0,7);
        if ( lead == 'Not PIN') {
            // No pin for this rider (usually true)
            divData['pra']['text'] = '';
            divData['pra']['open'] = 0;
        } else if (lead == 'Bad PIN') {
            divData['pra']['open'] = 1;
            divData['pra']['text'] = '<b>Incorrect PIN</b> please retry.<br>' + askPin();
        } else if (lead == 'Ask PIN') {
            divData['pra']['open'] = 1;
            divData['pra']['text'] = askPin();
        } else {
            divData['pra']['open'] = 1;
        }
        showPra();
    }
}

function showPra() {
    // Unlike other divs, hide if the rider has no PIN.  This is flagged by an empty
    // string.
    if (divData['pra']['text'] == '') {
        divData['pra']['open'] = 0;
        changeContent('myPractice', '');
        return;
    }
    var head = 'My Practice';
    if (divData['pra']['open'] == 1) {
        // Removed leading slash so it works in temporary BlueHost acct.
        changeContent('myPractice', 
            '<h2><a href="javascript:togglePra();" title="Hide"><img src="wp-content/AD.gif" width="16" height="16" alt="Hide Practice Results"></a>' + head + '</h2>' + divData['pra']['text']);
    } else {
        changeContent('myPractice', 
            '<h2><a href="javascript:togglePra();" title="Show"><img src="wp-content/AR.gif" width="16" height="16" alt="Show Practice Results"></a>' + head + '</h2>');
    }
}

function cookieCheck() {
    var cook = readCookie('myJV');
    if (cook != '' && cook != undefined) {
        var p = cook.split('|');
        if (p.length == 1) {
            // Original flavor - just the name.
            getRiderNames(cook);
        } else if (p.length == 2) {
            // New with added ID for more crunch.
            populate(p[1], p[0]);  // Name first in the cookie, id first in the call.
        }
    }
}


/* The following function creates an XMLHttpRequest object... */

function createRequestObject(){
	var req; //declare the variable to hold the object.
	var browser = navigator.appName; //find the browser name
	if(browser == "Microsoft Internet Explorer"){
		/* Create the object using MSIE's method */
		req = new ActiveXObject("Microsoft.XMLHTTP");
	}else{
		/* Create the object using other browser's method */
		req = new XMLHttpRequest();
	}
	return req; //return the object
}

function browserID() {
    var browser = navigator.appName; //find the browser name
    if (browser == "Microsoft Internet Explorer"){
        return 'IE';
    } else if (browser == "Netscape"){
        // Note that Firefox returns Netscape, and MO (in changeContent)
	// is the option that works with Firefox.  Need to test more.
        return 'MO';
    } else if (browser == "Opera") {
        return 'OP';
    } else {
        //alert("New browser type " + browser);
    }
    return browser;
}

function changeContent(id, str) {
  var type = browserID();
  if (type=="IE") {
    document.all[id].innerHTML = str;
  } else if (type=="NN") {
    document.layers[id].document.open();
    document.layers[id].document.write(str);
    document.layers[id].document.close();
  } else if (type=="MO" || type=="OP") {
    document.getElementById(id).innerHTML = str;
  } else {
    document.getElementById(id).innerHTML = str;
  }
}

// id here means the id of an object in the page
function multiGetByID(id) {
  var type = browserID();
  if (type=="IE") {
    return document.all[id];
  } else
  if (type=="NN") {
    return document.layers[id];
  } else
  if (type=="MO" || type=="OP") {
    return document.getElementById(id);
  } else {
    alert("whoa, no type?");
  }
}



function getRiderNames(name) {
    var len = name.length;
    if (len > 2) {
        // Always keep names for matching and caching in lowercase.
        name = name.toLowerCase();
        // Check cache, then hit server if needed.
        var set;
        if ((set = listCache[name]) != null) {
            // Exact match in cache
//alert("Got exact cache match with " + set.names.length + " names, type " + set.type + " and first name of " + set.names[0]);
            useNameSet(set);

        } else if ((set = listCache[name.substring(0,name.length-1)]) != null) {

            //alert("Got approx match, type " + set.type);
            // Match after deleting one letter - use it if good enough.
            if (set.type == 'full' || set.type == 'single') {
                // All matches are local, trim any which no longer fit.
                //alert("Got approx match, type " + set.type);
                set = trimSet(set, name);
                listCache[name] = set;
                useNameSet(set);
            } else if (set.type == 'empty') {
                // Already had no matches - just adjust and send on.
                // Don't change - it's a copy:
                //set.keyLen = set.keyLen+1;
                //alert("Using exising empty cache set for " + name + " too.");
                listCache[name] = set;
                useNameSet(set);
            } else if (set.type == 'big') {
                // The tricky one.  If some names are eliminated, we

                // may want to check with the server.  If list shrinks and
                // we are beginning to select among names still on the
                // server, must check.        
                // XXX this is only a first cut at knowing when to hit the server.
                tmpSet = trimSet(set, name);
                if (tmpSet.names.length >= 7) {
                    // Use but don't cache.  This means that every second
                    // letter will hit the server on "big" sets.
                    useNameSet(tmpSet);
                } else {
                    serverCall(name);
                }
            }
        } else {
	    serverCall(name);
        }

    } else {
        // Too small to pre-fill.  Remove the list if backspacing.
        if (name.length < typedSize) {
              changeContent("nameSelectSub", "");
        }
    }
    typedSize = name.length;

    return;

}


function serverCall(name) {
    if (http.readyState != 4 && http.readyState != 0) {
        // The last request hasn't finished.  Just dump it and move on!
        if (httpLock == 0) {
            http.abort();
        } else {
            // Heck, busy receiving.  Skip the new request.
            //alert("Skipped request on lock.");
            return;
        }
    }
    // Removed leading slash so it works in temporary BlueHost acct.
    var myreq = 'wp-content/ajax/ajax.php?action=getRiders&name=' + escape(name);
//alert("Requesting with name " + escape(name));
    http.open('get', myreq);
    http.onreadystatechange = handleRiders;
    http.send(null);
}

// Given a set of names and a prefix, eliminate any names which
// don't match the prefix.  Adjust attributes accordingly.
function trimSet(set, pre) {
    if (set.type == 'empty') return set;
    len = pre.length;
    var keepN = Array();
    var keepI = Array();
    var keepCount = 0;
    for (i=0; i<set.names.length; i++) {
        name = set.names[i];
        if (name.substring(0,len).toLowerCase() == pre) {
            keepN[keepCount] = name;
            keepI[keepCount] = set.ids[i];
            keepCount++;
        }
    }
    // Note that we must make a new set or we are modifying the old
    // set which is still cached under a different tag.  If there are
    // no changes, we'll just double-cache the same set and hope for
    // no problems down the line.
    var newSet = {};
    // types: full, single, empty, big
    if (keepCount == 0) {
        newSet.type = 'empty';
        newSet.names = keepN;
        newSet.ids = keepI;
        newSet.keyLen = len;
        return newSet;
    } else if (keepCount < set.names.length) {
        if (keepCount == 1) {
            newSet.type = 'single';
        } else {
            newSet.type = set.type;
        }
        newSet.names = keepN;
        newSet.ids = keepI;
        newSet.keyLen = len;
        return newSet;
    } else {
        return set;

    }
}

function checkOneName(check) {
    alert("Checking the name " + check);

    if (idList.length > 0) {
        for (i=0; i<idList.length; i++) {
            if (namesToShow[i] == check) {
                populate(idList[i], nameList[i]);

                return;
            }
        }
    }
    return;
}

// To do: split into http-handling and list-handling
// so when we know we don't need a server hit we just modify
// the list locally.


function handleRiders() {
    //alert("Got a state change: " + http.readyState);
    // True when we get the rider list:
    if (http.readyState == 4) {
        httpLock = 1;
        //alert("In rS = 4");
	var response = http.responseText;
        //alert("Response:\n" + response);
        if (response == undefined || response == '') {
            alert("Bad response.\nReadystate is " + http.readyState
                + "\nCode is " + http.status);
        }
        httpLock = 0;
        var lines = response.split('\n');
        var qs = lines[0];
        // Line 0 is a query string, the rest are ids and names.
        var args = parseQueryString (qs);
        var type = args['s'];
        var numReturned = args['r'];
        if (type == 'single') numReturned = 1;
        else if (type == 'empty') numReturned = 0;

        //alert("nR: " + numReturned + ", type = " + type);
        var lineParts;

        namesToShow = Array();
        idList = Array();
        for (i=1; i<=numReturned; i++) {
            lineParts = lines[i].split('|');
            namesToShow[i-1] = lineParts[1];
            idList[i-1] = lineParts[0];
        }
        // Cache the return in case of reuse and then pass
        // it to the handling routine.
        var set = {};
        set.names = namesToShow;
        set.ids = idList;
        set.type = type;
        set.keyLen = args['c'];
        // XXX other returned values could be added there.
        // Can't cache without a name, unless we pass it via the server.
        if (numReturned > 0) {

            var qName = (namesToShow[0].substr(0,args['c'])).toLowerCase();
            //alert("Caching the set, string is " + qName);
            listCache[qName] = set;
        }

        useNameSet(set);
    }
}

function useNameSet(set) {
    if (set.type == 'single') {
        currID = set.ids[0];
        changeContent("nameSelectSub", set.names[0]);
        populate(set.ids[0], set.names[0]);
    } else if (set.type == 'full' || set.type == 'big') {
        fillSub(set.names, set.ids);
        changeContent("bookMark", "");
    } else if (set.type == 'empty') {
        var t = 'No matching names found.  Here are some tips. <ul>' +
           '<li>Enter first name first, like "Theo Bos", not "Bos, Theo".  If that fails, try just the last name and check the dropdown list.</li>' +
           '<li>Try avoiding nicknames.  Try Benjamin, not Ben;  James, not Jim, and so on.  I have a few nicknames in the database by accident, ' +
           'but mostly only more formal names from race results are recognized.</li>' +
           '<li>I have work to do on characters with accent marks.  Try using the dropdown list as much as possible.</li>' +
           '<li>Failing all that, try a misspelling.  If it works, please leave a comment or email so I can fix it.</li>' +
           '<li>The database does not go back far.  Only a few riders above the age of 20 can be found here.</li>' +
           '<li>I do not have every junior track rider.  I am happy to add current juniors on request if you send name, birth year, and country ' +
           'at a minumum.  City, team, and US or UCI license number would be nice.</li>' +
           '</ul>';
        changeContent("bookMark", "");
        changeContent("nameSelectSub", t);
    }
}

/* Replact the nameSelectSub div contents with the latest list.
 */
function fillSub(names, ids) {
  var s = "<select name=\"input_name_select\""
    + " value=\"\" onchange=\"dropPop()\">\n";
  s += "<option value=\"\">- select - </option>\n";
  for (i=0; i<names.length && i<10; i++) {
    s = s + "<option value=\"" + ids[i] + "\">" + names[i]
        + "</option>\n";
  }

  s = s + "</select>\n";
  changeContent("nameSelectSub", s);
}

// Handle events from the dropdown, to call populate correctly.
function dropPop() {
    var x = window.document.form_name_select.input_name_select;
    populate(x.options[x.selectedIndex].value, x.options[x.selectedIndex].text);
}



// Once the rider ID is known, call this to populate the page.


function populate(id, name) {
    // We can get here with no ID if the "- select -" options is
    // chosen in the dropdown.  Do nothing.
    if (id == '') return;
    currID = id;
    // Save a cookie so we can recreate this after a back button
    // or on the next visit.
    createCookie("myJV", name + '|' + id, 90);

    // Bookmark
    var link = "http://www.juniorvelo.com/?page_id=329&mjvname=" + name;
    var markText = "<br><br>To bookmark this rider's page or email a link, please use <a href=\"" + link + "\">" + link + "</a>."
    changeContent("bookMark", markText);

    // Removed leading slashes so it works in temporary BlueHost acct.
    // myBasics
    basicsHttp = createRequestObject();
    var myreq = 'wp-content/ajax/ajax.php?action=getBasics&id=' + id;
    basicsHttp.open('get', myreq);
    basicsHttp.onreadystatechange = handleBasics;
    basicsHttp.send(null);

    // myPictures
    picHttp = createRequestObject();
    var myreq = 'wp-content/ajax/ajax.php?action=getPictures&id=' + id;
    picHttp.open('get', myreq);
    picHttp.onreadystatechange = handlePictures;
    picHttp.send(null);

    // myArticles
    artHttp = createRequestObject();
    var myreq2 = 'wp-content/ajax/ajax.php?action=getArticles&name=' + name;
    artHttp.open('get', myreq2);
    artHttp.onreadystatechange = handleArticles;
    artHttp.send(null);

    // myResults
    resHttp = createRequestObject();
    var myreq3 = 'wp-content/ajax/ajax.php?action=getResults&id=' + id;

    resHttp.open('get', myreq3);
    resHttp.onreadystatechange = handleResults;
    resHttp.send(null);

    // myPractice
    // Unlike the other sections, this may be called from more than one
    // place, so make it a function.
    getPractice(0);
}



// Storage for div info blocks
var divData = Array();
divData['res'] = Array();
divData['art'] = Array();
divData['pic'] = Array();
divData['pra'] = Array();
divData['bas'] = Array();

divData['bas']['open'] = 1;
divData['bas']['text'] = '';
divData['bas']['name'] = 'Basic Info';

divData['res']['open'] = 1;
divData['res']['text'] = '';
divData['res']['name'] = 'Results';

divData['art']['open'] = 1;
divData['art']['text'] = '';
divData['art']['name'] = 'Articles';

divData['pic']['open'] = 1;
divData['pic']['text'] = '';
divData['pic']['name'] = 'Pictures';

divData['pra']['open'] = 1;
divData['pra']['text'] = '';
divData['pra']['name'] = 'Practice';

function handlePictures() {
    if (picHttp.readyState == 4) {
        divData['pic']['text'] = picHttp.responseText;
        if (picHttp.responseText.substr(0,5) == 'Sorry') {
            divData['pic']['open'] = 0;
            divData['pic']['text'] = 
               "If you have no pictures, consider emailing one or two to velo@juniorvelo.com.  Be sure to include your name.  A suggested caption would be nice, too.  I won't put you on a mailing list.  One last thing: don't send a picture if someone else owns the copyright!";
        } else {
            divData['pic']['open'] = 1;
        }
        showPic();
        //changeContent("myPictures", picHttp.responseText);
    }
}

function handleBasics() {
    if (basicsHttp.readyState == 4) {
        divData['bas']['text'] = basicsHttp.responseText;
        divData['bas']['open'] = 1;
        showBasics();
    }
}


function handleArticles() {
    if (artHttp.readyState == 4) {
        divData['art']['text'] = artHttp.responseText;
        if (artHttp.responseText == '') {
            divData['art']['open'] = 0;
            divData['art']['text'] = 'No articles found.';
        } else {
            divData['art']['open'] = 1;


        }
        showArt();
        //changeContent("myArticles", artHttp.responseText);
    }
}


function handleResults() {
    if (resHttp.readyState == 4) {
        divData['res']['text'] = resHttp.responseText;
        if (resHttp.responseText.substr(0,7) == '<b>No r') {
            divData['res']['open'] = 0;
            divData['res']['text'] = 'No results found.';
        } else {
            divData['res']['open'] = 1;
        }
        showRes();
        //changeContent("myResults", resHttp.responseText);
    }
}

function toggleArt() {
    divData['art']['open'] = 1 - divData['art']['open'];
    showArt();
}
function toggleRes() {
    divData['res']['open'] = 1 - divData['res']['open'];
    showRes();
}
function togglePic() {
    divData['pic']['open'] = 1 - divData['pic']['open'];
    showPic();
}
function toggleBas() {
    divData['bas']['open'] = 1 - divData['bas']['open'];
    showBasics();
}
function togglePra() {
    divData['pra']['open'] = 1 - divData['pra']['open'];
    showPra();
}

function showArt() {
    // Removed leading slashes so it works in temporary BlueHost acct.
    var head = 'My Articles';
    if (divData['art']['open'] == 1) {
        changeContent('myArticles', 
            '<h2><a href="javascript:toggleArt();" title="Hide"><img src="wp-content/AD.gif" width="16" height="16" alt="Hide Articles"></a>' + head + '</h2>' + divData['art']['text']);
    } else {
        changeContent('myArticles', 
            '<h2><a href="javascript:toggleArt();" title="Show"><img src="wp-content/AR.gif" width="16" height="16" alt="Show Articles"></a>' + head + '</h2>');
    }
}
function showRes() {
    var head = 'My Results';
    if (divData['res']['open'] == 1) {
        changeContent('myResults', 
            '<h2><a href="javascript:toggleRes();" title="Hide"><img src="wp-content/AD.gif" width="16" height="16" alt="Hide Results"></a>' + head + '</h2>' + divData['res']['text']);
    } else {
        changeContent('myResults', 
            '<h2><a href="javascript:toggleRes();" title="Show"><img src="wp-content/AR.gif" width="16" height="16" alt="Show Results"></a>' + head + '</h2>');
    }
}

function showPic() {
    var head = 'My Pictures';
    if (divData['pic']['open'] == 1) {
        changeContent('myPictures', 
            '<h2><a href="javascript:togglePic();" title="Hide"><img src="wp-content/AD.gif" width="16" height="16" alt="Hide Pictures"></a>' + head + '</h2>' + divData['pic']['text']);
    } else {
        changeContent('myPictures', 
            '<h2><a href="javascript:togglePic();" title="Show"><img src="wp-content/AR.gif" width="16" height="16" alt="Show Pictures"></a>' + head + '</h2>');
    }
}

function showBasics() {
    var head = 'My Basic Info';
    if (divData['bas']['open'] == 1) {
        changeContent('myBasics', 
            '<h2><a href="javascript:toggleBas();" title="Hide"><img src="wp-content/AD.gif" width="16" height="16" alt="Hide Basics"></a>' + head + '</h2>' + divData['bas']['text']);
    } else {
        changeContent('myBasics', 
            '<h2><a href="javascript:toggleBas();" title="Show"><img src="wp-content/AR.gif" width="16" height="16" alt="Show Basics"></a>' + head + '</h2>');
    }
}


function parseQueryString (str) {
  str = str ? str : location.search;
  var query = str.charAt(0) == '?' ? str.substring(1) : str;
  var args = new Object();
  if (query) {
    var fields = query.split('&');
    for (var f = 0; f < fields.length; f++) {
      var field = fields[f].split('=');
      args[unescape(field[0].replace(/\+/g, ' '))] = 

unescape(field[1].replace(/\+/g, ' '));
      //alert("Parsing field 0 " + field[0] + " and field 1 " + field[1] + ".");

    }
  }
  return args;

}

function createCookie(name,value,days)
{
	if (days)
	{
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++)
	{
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}
