var t;
var myStampStart = 1;   // like 0 but a little more ;) so can test 0
var myStampStartTOD;
var refreshContinue = 1;
var refreshTime = 5;
var countDown = 0;
var doCountDown = 1;
var loadingCovered = 0;
var updateMessage;
var resultHeader;
var numResultsDisplayed = 9999;  // all
var resultOrder = 'Rank';
var resultTable; 
var onCourseHeader;
var onCourseTable;
var recentHeader;
var recentTable;
var numRuns = 0; numColumns = 0; 
var numOnCourseRows = 3; numRecentRows = 3;
var numIntermediates = 0; numSpeeds = 0;
var raceSource = '';
var online;
var comps = new Array();
var onCourseComps = new Array();
var bgColors = ['rgb(204, 204, 204)','rgb(198, 204, 198)','rgb(192, 204, 192)','rgb(186, 204, 186)','rgb(180, 204, 180)','rgb(174, 204, 174)','rgb(168, 204, 168)','rgb(162, 204, 162)','rgb(156, 204, 156)','rgb(150, 204, 150)','rgb(144, 204, 144)','rgb(138, 204, 138)','rgb(132, 204, 132)','rgb(126, 204, 126)','rgb(120, 204, 120)','rgb(114, 204, 114)','rgb(108, 204, 108)','rgb(102, 204, 102)','rgb(96, 204, 96)','rgb(90, 204, 90)','rgb(84, 204, 84)','rgb(78, 204, 78)','rgb(72, 204, 72)','rgb(66, 204, 66)','rgb(60, 204, 60)','rgb(54, 204, 54)','rgb(48, 204, 48)','rgb(42, 204, 42)','rgb(36, 204, 36)','rgb(30, 204, 30)','rgb(24, 204, 24)','rgb(18, 204, 18)','rgb(12, 204, 12)','rgb(6, 204, 6)','rgb(0, 204, 0)'];

function jsRaceInitAll() {
		document.body.style.cursor = 'wait';
  updateMessage = document.getElementById('updateMessage');
		resultHeader = document.getElementById('resultHeader');
		resultTable = document.getElementById('resultTable');
		onCourseHeader = document.getElementById('onCourseHeader');
		onCourseTable = document.getElementById('onCourseTable');
		recentHeader = document.getElementById('recentHeader');
		recentTable = document.getElementById('recentTable');
		online = document.getElementById('online');
		refreshCountDown()
  timedCount()
  }

function updateRefreshTime() {   // called by form to change the update rate
  var w = document.updateForm.updateSelect.selectedIndex; 
  refreshContinue = 1;
		if (w == 0) refreshTime = 5;
  else if (w == 1) refreshTime = 10;
  else if (w == 2) refreshTime = 20;
  else if (w == 3) refreshTime = 30;
  else if (w == 4) refreshTime = 60;
  else if (w == 5) refreshTime = 120;
		else refreshContinue = 0;
  timedCount()   // calls it straight away to get the count right		
		}		

function updateResultsDisplayed() {   // called by form
  var w = document.updateForm2.updateSelect.selectedIndex; 
  refreshContinue = 1;
		if (w == 0) numResultsDisplayed = 9999;  //all
  else if (w == 1) numResultsDisplayed = 30;
  else if (w == 2) numResultsDisplayed = 15;
  else if (w == 3) numResultsDisplayed = 10;
  else if (w == 4) numResultsDisplayed = 5;
  removeTableAndHeader(resultHeader, resultTable)
  displayTable(comps, resultTable, resultHeader, 3, Math.min(comps.length, numResultsDisplayed), Math.min(comps.length, numResultsDisplayed))
		}		

function doUpdateResultOrder() {  // called after function below so will set cursor to 'wait'
  removeTableAndHeader(resultHeader, resultTable)
  if (resultOrder == 'Rank')   // call this to get the order right since doesn't get resorted for Rank in displayTable
		  setRanks()
  displayTable(comps, resultTable, resultHeader, 3, Math.min(comps.length, numResultsDisplayed), Math.min(comps.length, numResultsDisplayed))
		document.body.style.cursor = 'default';
  }
		
function updateResultOrder(newOrder) {  // called by clicking on a header on result table
  resultOrder = newOrder
		document.body.style.cursor = 'wait';
		if (newOrder == 'Rank')	
		  document.getElementById("rhRank").style.cursor = "wait";
		else if (newOrder == 'Bib')	
		  document.getElementById("rhBib").style.cursor = "wait";
		else if (newOrder == 'Name')	
		  document.getElementById("rhName").style.cursor = "wait";
		else if (newOrder == 'Team')	
		  document.getElementById("rhTeam").style.cursor = "wait";
		else if (newOrder == 'Club')	
		  document.getElementById("rhClub").style.cursor = "wait";
		else if (newOrder == 'Class')	
		  document.getElementById("rhClass").style.cursor = "wait";
		else if (newOrder == 'R1')	
		  document.getElementById("rhR1").style.cursor = "wait";
		else if (newOrder == 'R2')	
		  document.getElementById("rhR2").style.cursor = "wait";
  t=setTimeout("doUpdateResultOrder()",100)
  }
		
function updateOnCourseTimes() {
  rows = onCourseTable.getElementsByTagName('tr')
		colNum = 5
		if (raceSource == 'U')
		  colNum++
		for (var i=0; i < onCourseComps.length; i++) {
		  var rowNum = i * (1 + numIntermediates + numSpeeds) + 1
 	  cols = rows[rowNum].cells
		  if (onCourseComps[i].r1 == "On Course")
				  displayElapsed(onCourseComps, i, cols[colNum])
		  else if (onCourseComps[i].r2 == "On Course") 
				  displayElapsed(onCourseComps, i, cols[colNum + 1])
    } 
  }
		
function	updateBGColors()	{
		function checkTable(table) {
  		var rows= table.getElementsByTagName('tr')
  		for (var i=rows.length; i > 1; i--) {
				  var rowStyle = rows[i - 1].style
						if (rowStyle.backgroundColor != bgColors[0]) 
      		for (var j=34; j > 0; j--)
								  if (rowStyle.backgroundColor == bgColors[j]) {
										  rowStyle.backgroundColor = bgColors[j-1]
												break
  										}		
						}
		  }  // end of checkTable
		checkTable(recentTable)
		checkTable(resultTable)
  }
		
		
function refreshCountDown() {
  if (countDown <= 0 || doCountDown == 0 || refreshContinue == 0)
    document.countDownForm.countDownBox.value=''
		else {
 		 countDown--				
    document.countDownForm.countDownBox.value = countDown
				}
  updateOnCourseTimes()
		updateBGColors()		
  t=setTimeout("refreshCountDown()",1000)
		}

function timedCount() {
		ajaxFunction()
		if (refreshContinue != 0)
    t=setTimeout("timedCount()",1000 * refreshTime)
  }		

function ajaxFunction() {
  var xmlHttp;
  try {  // Firefox, Opera 8.0+, Safari
    xmlHttp=new XMLHttpRequest();
    }
  catch (e) {  // Internet Explorer
    try  {
      xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
      }
    catch (e) {
      try {
        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
      catch (e) {
        alert("Your browser does not support AJAX!");
        return false;
        }
      }
    }
    xmlHttp.onreadystatechange=function()  {
      if(xmlHttp.readyState==4) {
 							countDown = refreshTime
        processResponse(xmlHttp.responseText);
								}
      }
    xmlHttp.open("GET","includes/aj_race.php?r=" + raceID + "&&m=" + myStampStart + '&&u=' + refreshTime,true);
    xmlHttp.send(null);
  }

function displayElapsed(c, who, cell) {
  if (refreshTime == 5) {
		  compStamp = c[who].myStamp
				var TOD = new Date();
		  var nowTOD = TOD.getTime();
		  var elapsedTODsinceUpdate = (nowTOD - myStampStartTOD) / 1000
		  var elapsed = Math.floor(myStampStart - compStamp + elapsedTODsinceUpdate) - 3
				if (numIntermediates > 0) {
				  if (numIntermediates == 1 && numRuns == 1 && c[who].i11 != '') 
						  elapsed = elapsed + (0.01 * c[who].i11AsInt)
				  else if (numIntermediates == 1 && numRuns > 1 && c[who].i21 != '') 
						  elapsed = elapsed + (0.01 * c[who].i21AsInt)
				  else if (numIntermediates == 2 && numRuns == 1) {
						  if (c[who].i12 != '') 
								  elapsed = elapsed + (0.01 * c[who].i12AsInt)
								else if (c[who].i11 != '') 
								  elapsed = elapsed + (0.01 * c[who].i11AsInt)
								}		
				  else if (numIntermediates == 2 && numRuns > 1) {
						  if (c[who].i22 != '') 
								  elapsed = elapsed + (0.01 * c[who].i22AsInt)
								else	if (c[who].i21 != '') 
								  elapsed = elapsed + (0.01 * c[who].i21AsInt)
								}		
				  else if (numIntermediates == 3) {
						  if (c[who].i13 != '') 
								  elapsed = elapsed + (0.01 * c[who].i13AsInt)
						  else if (c[who].i12 != '') 
								  elapsed = elapsed + (0.01 * c[who].i12AsInt)
								else if (c[who].i11 != '') 
								  elapsed = elapsed + (0.01 * c[who].i11AsInt)
								}		
				  else if (numIntermediates == 4) {
						  if (c[who].i14 != '') 
								  elapsed = elapsed + (0.01 * c[who].i14AsInt)
						  else if (c[who].i13 != '') 
								  elapsed = elapsed + (0.01 * c[who].i13AsInt)
						  else if (c[who].i12 != '') 
								  elapsed = elapsed + (0.01 * c[who].i12AsInt)
								else  if (c[who].i11 != '') 
								  elapsed = elapsed + (0.01 * c[who].i11AsInt)
								}		
						}		
		  elapsed = Math.floor(elapsed) // - 3
				if (elapsed <= 0)
		  		cell.innerHTML = '&nbsp;'
				else {		
						var seconds = elapsed % 60
						var minutes = Math.floor(elapsed / 60)
						if (isNaN(minutes)) minutes = 0
						if (minutes == 0)
								elapsed = seconds  
						else if (seconds < 10)
								elapsed = minutes + ':0' + seconds
						else	if (!isNaN(minutes) && !isNaN(seconds))			
								elapsed = minutes + ':' + seconds
						else
						  elapsed = ''
						cell.innerHTML = elapsed + '&nbsp; &nbsp; &nbsp; &nbsp;'
						}
  		}
		else // refreshTime != 5				
				cell.innerHTML = 'On Course&nbsp;&nbsp;&nbsp;&nbsp;'
		}		

function intermediateWithRank(bib, time, timeAsInt, runNum, intNum) {
  // not very code efficient on purpose, for speed
		var tie = ''
		var rank = 1  // until find worse
		var hold
		if (runNum == 1) {
		  if (intNum == 1) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i11AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}				
				  }
		  else if (intNum == 2) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i12AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}				
				  }
		  else if (intNum == 3) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i13AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}				
				  }
		  else if (intNum == 4) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i14AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}				
				  }
		  }
		else {  // runNum = 2
		  if (intNum == 1) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i21AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}				
				  }
		  else if (intNum == 2) {
    		for (var i = comps.length - 1; i >= 0; i--) {
						  hold = comps[i].i22AsInt
						  if (hold != '' && 1 * hold <= 1 * timeAsInt && comps[i].bib != bib)
								  if (hold == time) tie = '='; else rank++
								}		
				  }
		  }
		if (time != '')
		  return time + '&nbsp;(' + rank + tie + ')'
		else		
    return ''
		}				  
		
function displayTable(comps, table, header, tableNum, numRows, numToDisplay) {
  if (tableNum == 3 && resultOrder != 'Rank')
		  if (resultOrder == 'Bib')
    		comps.sort(sortByBib)
		  else if (resultOrder == 'Name')
    		comps.sort(sortByName)
		  else if (resultOrder == 'Team')
    		comps.sort(sortByTeam)
		  else if (resultOrder == 'Club')
    		comps.sort(sortByClub)
		  else if (resultOrder == 'Class')
    		comps.sort(sortByClass)
		  else if (resultOrder == 'R1')
    		comps.sort(sortByR1)
		  else if (resultOrder == 'R2')
    		comps.sort(sortByR2)
  rows = table.getElementsByTagName('tr')
  if (tableNum == 1 && numRows != 0)
		  if (refreshTime == 5)
      header.innerHTML = '<br>On Course:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
						  + '<span class="normalsmallred">NOTE : running time is approximate only! NOT OFFICIAL</span><br>'
				else
				  header.innerHTML = '<br>On Course:<br>'
  if (rows.length < numRows) {  // need to add rows
		  if (rows.length == 0) {  // need to add the header line
						if (tableNum == 2)
        header.innerHTML = '<br><br>Recent Results:<br>'
						else if (tableNum == 3)
        header.innerHTML = '<br><br>Results:<br>'
    		row = table.insertRow(0);
      row.style.backgroundColor=tableHeaderBG;
      row.className='tableheader';
						cell = row.insertCell(0);		
						cell.align = 'right';
				  if (tableNum == 1)
						  cell.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
						else		
  						if (tableNum == 3 && resultOrder != 'Rank') 
								  cell.innerHTML = '<span id="rhRank" onclick="updateResultOrder(\'Rank\')" style="text-decoration: underline">Rank</span>&nbsp;';
								else		
  						  cell.innerHTML = 'Rank&nbsp;';
						cell = row.insertCell(1);		
						if (tableNum == 3 && resultOrder != 'Bib') 
						  cell.innerHTML = '<span id="rhBib" onclick="updateResultOrder(\'Bib\')" style="text-decoration: underline; cursor:pointer">Bib</span>&nbsp;&nbsp;';
						else		
  						cell.innerHTML = 'Bib&nbsp;&nbsp;';  
						cell.align = 'right';
						cell = row.insertCell(2);		
						if (tableNum == 3 && resultOrder != 'Name') 
						  cell.innerHTML = '<span id="rhName" onclick="updateResultOrder(\'Name\')" style="text-decoration: underline; cursor:pointer">Name</span>';
						else		
  						cell.innerHTML = 'Name';
      cell = row.insertCell(3);		
						if (tableNum == 3 && resultOrder != 'Team') 
						  cell.innerHTML = '<span id="rhTeam" onclick="updateResultOrder(\'Team\')" style="text-decoration: underline; cursor:pointer">Team</span>';
						else		
  						cell.innerHTML = 'Team';
						colNum = 3;
						if (raceSource == 'U') {
						  colNum++; 
								cell = row.insertCell(colNum);		
  						if (tableNum == 3 && resultOrder != 'Club') 
		  				  cell.innerHTML = '<span id="rhClub" onclick="updateResultOrder(\'Club\')" style="text-decoration: underline; cursor:pointer">Club</span>';
				  		else		
		  						cell.innerHTML = 'Club';
								}
						colNum++; 
						cell = row.insertCell(colNum);
						if (tableNum == 3 && resultOrder != 'Class') 
						  cell.innerHTML = '<span id="rhClass" onclick="updateResultOrder(\'Class\')" style="text-decoration: underline; cursor:pointer">Class</span>';
						else		
        cell.innerHTML = 'Class';
						if (numRuns > 0) {
						  colNum++; cell = row.insertCell(colNum);		
  						if (tableNum == 3 && resultOrder != 'R1') 
		  				  cell.innerHTML = '<span id="rhR1" onclick="updateResultOrder(\'R1\')" style="text-decoration: underline; cursor:pointer">Result 1</span>';
								else		
				  				cell.innerHTML = 'Result 1';  
								cell.align = 'center';
								if (numRuns > 1) {
  						  colNum++; cell = row.insertCell(colNum);		
    						if (tableNum == 3 && resultOrder != 'R2') 
		    				  cell.innerHTML = '<span id="rhR2" onclick="updateResultOrder(\'R2\')" style="text-decoration: underline; cursor:pointer">Result 2</span>';
				  				else		
						  				cell.innerHTML = 'Result 2';  
										cell.align = 'center';
										colNum++; 
										cell = row.insertCell(colNum);	
										if (type2 == 'Best')	
										  cell.innerHTML = 'Best';  
										else	
										  cell.innerHTML = 'Combined';
										cell.align = 'right';
          }								  
        }								  
      rows = table.getElementsByTagName('tr')   // so the count is correct
				  }
    for (var i=rows.length; i<numRows + 1; i++) {
    		row = table.insertRow(rows.length)
      row.style.backgroundColor='#CCCCCC';
      row.className='table';
						cell = row.insertCell(0); cell.align = 'right';  // rank
						cell = row.insertCell(1); cell.align = 'right';		// bib
						cell = row.insertCell(2);		                      // name
      cell = row.insertCell(3);		                      // team
						colNum = 3;
						if (raceSource == 'U') {
						  colNum++; cell = row.insertCell(colNum);  // club
								}
      colNum++; cell = row.insertCell(colNum);		  // class
						if (numRuns > 0) {
						  colNum++; cell = row.insertCell(colNum);		cell.align = 'right';  // result1
								if (numRuns > 1) {
  						  colNum++; cell = row.insertCell(colNum);		cell.align = 'right';  // result1
  						  colNum++; cell = row.insertCell(colNum);		cell.align = 'right';  // combine/best
          } 
        }
						if (tableNum  == 1 && numIntermediates + numSpeeds != 0) {  // add extra lines for intermediates
        for (var j=0; j<numIntermediates + numSpeeds; j++) {
				    		row = table.insertRow(rows.length)
				      row.style.backgroundColor='#CCCCCC';
				      row.className='table2';
										cell = row.insertCell(0); cell.innerHTML = '&nbsp;'  // rank, not used
										cell = row.insertCell(1); cell.innerHTML = '&nbsp;'  // bib, not used
										// name - used for 'intermediate 1' etc.
										cell = row.insertCell(2); cell.align = 'left'; cell.innerHTML = '&nbsp;'; cell.style.backgroundColor = '#dcdcdc';
          // team, club, class, used for intermediate/speed result
										cell = row.insertCell(3); cell.align = 'right'; cell.colSpan = '3'; cell.innerHTML = '&nbsp;'; cell.style.backgroundColor = '#dcdcdc';
          // result1 (and maybe result2 and combined) not used
										cell = row.insertCell(4); cell.innerHTML = '&nbsp;'
										if (numRuns > 1) {
  										cell = row.insertCell(5); cell.innerHTML = '&nbsp;'
		  								cell = row.insertCell(6); cell.innerHTML = '&nbsp;'
												}
								  }
						  }		
      }
				}
		
		// now have the right number of columns and rows
		num = Math.min(numRows, numToDisplay)
  for (var i=0; i<num; i++) {
		  if (tableNum == 3)
				  var rowNum = i + 1
				else
				  var rowNum = i * (1 + numIntermediates + numSpeeds) + 1
		  cols = rows[rowNum].cells
    cols[0].innerHTML = comps[i].rank + '&nbsp;'
    cols[1].innerHTML = comps[i].bib + '&nbsp;&nbsp;'
    cols[2].innerHTML = comps[i].name + '&nbsp;' 
    cols[3].innerHTML = comps[i].team + '&nbsp;'
				colNum = 3;
				if (raceSource == 'U') {
      colNum++; cols[colNum].innerHTML = comps[i].club + '&nbsp;'
						}
    colNum++; cols[colNum].innerHTML = comps[i].cclass + '&nbsp;' 
				if (numRuns > 0) {
				  hold = comps[i].r1
      colNum++; 
				  if (tableNum == 1 && hold == "On Course") 
						  displayElapsed(comps, i, cols[colNum])
						else
								cols[colNum].innerHTML = hold + comps[i].r1Rank 
						if (numRuns > 1) {
						  hold = comps[i].r2
        colNum++; 
						  if (tableNum == 1 && hold == "On Course")
  						  displayElapsed(comps, i, cols[colNum])
								else
										cols[colNum].innerHTML = hold + comps[i].r2Rank 
        colNum++; 
								cols[colNum].innerHTML = comps[i].total + '&nbsp;' 
								}						
						}
				if (tableNum  == 1 && numIntermediates + numSpeeds != 0) {  // add intermediates stuff
      for (var j=0; j<numIntermediates; j++) {
    		  cols = rows[rowNum + j + 1].cells
						  var hold = ''
						  if (j == 0 && comps[i].i21 != '')      hold = intermediateWithRank(comps[i].bib, comps[i].i21, comps[i].i21AsInt, 2, 1) // look for run 2 first
						  else if (j == 0 && comps[i].i11 != '') hold = intermediateWithRank(comps[i].bib, comps[i].i11, comps[i].i11AsInt, 1, 1)
						  else if (j == 1 && comps[i].i22 != '') hold = intermediateWithRank(comps[i].bib, comps[i].i22, comps[i].i22AsInt, 2, 2)
						  else if (j == 1 && comps[i].i12 != '') hold = intermediateWithRank(comps[i].bib, comps[i].i12, comps[i].i12AsInt, 1, 2)
						  else if (j == 2 && comps[i].i13 != '') hold = intermediateWithRank(comps[i].bib, comps[i].i13, comps[i].i13AsInt, 1, 3)
						  else if (j == 3 && comps[i].i14 != '') hold = intermediateWithRank(comps[i].bib, comps[i].i14, comps[i].i14AsInt, 1, 4)
								if (hold == '') {
								  cols[2].innerHTML = '&nbsp;'
								  cols[3].innerHTML = '&nbsp;'
										}
								else {
								  cols[2].innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;intermediate ' + (j + 1)
										cols[3].innerHTML = hold + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
										}
						  }
      for (var j=0; j<numSpeeds; j++) {
    		  cols = rows[rowNum + numIntermediates + j + 1].cells
						  var hold = ''
						  if (j == 0 && comps[i].sp11 != '') hold = comps[i].sp11 
						  else if (j == 1 && comps[i].sp12 != '') hold = comps[i].sp12
						  else if (j == 2 && comps[i].sp13 != '') hold = comps[i].sp13
								if (hold == '') {
								  cols[2].innerHTML = '&nbsp;'
								  cols[3].innerHTML = '&nbsp;'
										}
								else {
								  cols[2].innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;speed ' + (j + 1)
										cols[3].innerHTML = hold + '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
										}
						  }
				  }		
				if (tableNum > 1) {		// set appropriate background color for fading away, but not if 'on course'
      var bgColorIndex = 34 - Math.floor(myStampStart - comps[i].myStamp)
		  		if (bgColorIndex < 0 || bgColorIndex > 34 || comps[i].r1AsInt == 2147483500 || comps[i].r2AsInt == 2147483500)
				    bgColorIndex = 0
  				rows[rowNum].style.backgroundColor = bgColors[bgColorIndex]
		    }
				}
						
  // fill any extra rows with blanks
  for (var i=num; i<numRows; i++) {
		  if (tableNum != 1)
				  var rowNum = i + 1
				else
				  var rowNum = i * (1 + numIntermediates + numSpeeds) + 1
		  cols = rows[rowNum].cells
    for (var j=numColumns; j != 0; j--)
      cols[j-1].innerHTML = '&nbsp;'
				if (tableNum == 1 && numIntermediates + numSpeeds != 0) {  // clear intermediates lines
      for (var j=0; j<numIntermediates + numSpeeds; j++) {
    		  cols = rows[rowNum + j + 1].cells
        cols[2].innerHTML = '&nbsp;'
        cols[3].innerHTML = '&nbsp;'
						  }
						}		
		  }
  }  // end of displayTable

function sortByBib(a, b) {
  return a.bib - b.bib   // by bib in ascending order when no results
		}

function sortByName(a, b) {
  var x = a.name.toLowerCase();
  var y = b.name.toLowerCase();
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));		
		}

function sortByTeam(a, b) {
  var x = a.team.toLowerCase();
  var y = b.team.toLowerCase();
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));		
		}

function sortByClub(a, b) {
  var x = a.club.toLowerCase();
  var y = b.club.toLowerCase();
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));		
		}

function sortByClass(a, b) {
  var x = a.cclass.toLowerCase();
  var y = b.cclass.toLowerCase();
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));		
		}
		
function sortByStamp(a, b) {
  return b.stamp - a.stamp
		}

function sortByMyStamp(a, b) {
  return b.myStamp - a.myStamp
		}

function sortByR1(a, b) {
  return a.r1AsInt - b.r1AsInt
		}

function sortByR2(a, b) {
  return a.r2AsInt - b.r2AsInt
		}

function sortByTotal(a, b) {
  if (a.totalAsInt >= 2147483500 && b.totalAsInt >= 2147483500)
	   if (a.r1AsInt == b.r1AsInt)
				  return b.bib - a.bib  // by bib in descending order for a tie
				else		
  		  return a.r1AsInt - b.r1AsInt
  else if (a.totalAsInt == b.totalAsInt)
		  return b.bib - a.bib
		else		
		  return a.totalAsInt - b.totalAsInt
		}

function removeTable(table) {
		for (var i = table.rows.length; i > 0; i--)
    table.deleteRow(i -1);
		}
function removeTableAndHeader(header, table) {
  header.innerHTML='';
		removeTable(table)
		}
		
function displayComps(displayAll) {   // set to Y or N
  if (numRuns > 0) {
    var recentComps = new Array();
		  onCourseComps.length = 0;
		  var onCourseCount = 0;
				var recentCount = 0;
				var compsLength = comps.length
    for (var i=0; i<compsLength; i++) {
		    if ((comps[i].r1AsInt == 2147483500 || comps[i].r2AsInt == 2147483500) && comps[i].myStamp >= myStampStart - 180) {
						  // must be set to 'on course' and must have been updated in the past 3 minutes
  				  onCourseComps[onCourseCount] = comps[i];
  						onCourseCount++
		  				}
				  if (comps[i].r1AsInt != 2147483500 && comps[i].r2AsInt != 2147483500 && comps[i].myStamp >= myStampStart - 90) {
  				  recentComps[recentCount] = comps[i];
		  				recentCount++
								}
  				}
		  if (onCourseComps.length != 0 || recentComps != 0) {
  		  onCourseComps.sort(sortByStamp)								
    		recentComps.sort(sortByMyStamp)						
		    displayTable(onCourseComps, onCourseTable, onCourseHeader, 1, numOnCourseRows, onCourseCount)
						var tempI = numIntermediates;  //12/15/2005 workaround because was messing up with recent comps for some reason, haven't worked it out yet
						var tempS = numSpeeds;
						numIntermediates = 0;
						numSpeeds = 0;
		    displayTable(recentComps, recentTable, recentHeader, 2, numRecentRows, recentCount);
						numIntermediates = tempI;
						numSpeeds = tempS;
  				}
		  else {
				  onCourseComps.length = 0
		    removeTableAndHeader(onCourseHeader, onCourseTable)
				  removeTableAndHeader(recentHeader, recentTable)
  		  }		
				}		
		if (displayAll	== "Y")
		  displayTable(comps, resultTable, resultHeader, 3, Math.min(comps.length, numResultsDisplayed), Math.min(comps.length, numResultsDisplayed))
		}  // end of displayComps


function decRecent() {
  // called by '-' button on recent
		if (numRecentRows > 0) {
		  numRecentRows--
				displayComps("")  // clumsy way to redraw
				}
  }		

function incRecent() {
  // called by '+' button on recent
  numRecentRows++
		displayComps("")
  }		

function	checkNumIntermediates(num) {   
  // called when get intermediate data to see if need to remove the tables so they can be redrawn
		if (num > numIntermediates) {
 	  numIntermediates = num
				onCourseComps.length = 0;
 	  removeTable(onCourseTable)
				}					
		}		

function	checkNumSpeeds(num) {   
  // called when get speed data to see if need to remove the tables so they can be redrawn
		if (num > numSpeeds) {
 	  numSpeeds = num
				onCourseComps.length = 0;
 	  removeTable(onCourseTable)
		  removeTable(recentTable)
				}					
		}		

function setRanks() {
  if (numRuns == 0)
		  comps.sort(sortByBib)
		else {
		  comps.sort(sortByR1)
				var last = 0
				var compsLength = comps.length
    for (var i=0; i<compsLength; i++) {
				  if (comps[i].r1AsInt >= 2147483500 || comps[i].r1AsInt == 0) {
						  comps[i].r1Rank = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
								comps[i].rank = ''
								}
						else if (comps[i].r1AsInt != last || i == 0) {
						  if (i < 9)
								  comps[i].r1Rank = '&nbsp;&nbsp; (' + (i + 1) + ')'
								else		
								  comps[i].r1Rank = ' (' + (i + 1) + ')'
						  comps[i].rank = i + 1   // will get replaced below if 2 runs
								last = comps[i].r1AsInt
								}
						else {
						  comps[i].r1Rank = comps[i - 1].r1Rank
						  comps[i].rank = comps[i - 1].rank
								}
						}		
		  if (numRuns > 1) {  // sort by 2nd run, then combined/best
	 		  comps.sort(sortByR2)
						var last = 0
	     for (var i=0; i<compsLength; i++) {
						  if (comps[i].r2AsInt >= 2147483500 || comps[i].r2AsInt == 0)
								  comps[i].r2Rank = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
								else if (comps[i].r2AsInt != last || i == 0) {
								  if (i < 9)
										  comps[i].r2Rank = '&nbsp;&nbsp; (' + (i + 1) + ')'
										else		
										  comps[i].r2Rank = ' (' + (i + 1) + ')'
										last = comps[i].r2AsInt
										}
								else
								  comps[i].r2Rank = comps[i - 1].r2Rank
								}		
      // sort by combined/best
						
	 		  comps.sort(sortByTotal)
						var last = 0
	     for (var i=0; i<compsLength; i++) {
						  if (comps[i].totalAsInt >= 2147483500 ||comps[i].totalAsInt == 0)
								  comps[i].rank = ''
								else if (comps[i].totalAsInt != last || i == 0) {
								  comps[i].rank = i + 1
										last = comps[i].totalAsInt
										}
								else
								  comps[i].rank = comps[i - 1].rank
								}		
						}				
				}		
  }  // setRanks
		
function processResponse(text) {

  function displayHeader() {
		
		  function stripImage(source, imageNumber) {
				  // strips out the image stuff and any other tags, applies the image to 
						// the correct location and returns anything left
						var sourceLower = source.toLowerCase()
						if (sourceLower.indexOf('img', 0) != -1) {  // have an image
						  if (imageNumber == 1)
      		  document.getElementById('leftImage').innerHTML=source
								else		
      		  document.getElementById('rightImage').innerHTML=source
								return ''								  
								}
						else		
  						return source
				  }  // end of stripImage
		
		  // start of displayHeader
		  var reportString = ''
    for (var i=0; i<reportID.length; i++) {
				  if (i != 0) reportString += '<br>'
				  reportString += '<a href="report.php?r=' + raceID + '&rp=' + reportID[i] + '">' + reportName[i] + '</a>&sup1;'
      //		haveattached = 'Y'
						}
    document.getElementById('reports').innerHTML=reportString;
				// create the header but extract images if they're embedded in racename and resort!
		  document.getElementById('raceHeader').innerHTML=raceName + country;
    if (leftLogo != '')
  		  document.getElementById('leftImage').innerHTML='<img src="http://www.live-timing.com/includes/logos/' + leftLogo + '">';
    if (rightLogo != '')
  		  document.getElementById('rightImage').innerHTML='<img src="http://www.live-timing.com/includes/logos/' + rightLogo + '">';
    var headerString = ''
				var newRaceName = stripImage(raceName, 2)
				if (newRaceName != '')
				  headerString += newRaceName + ' - '
				if (type1=='Individual Start' || type1=='Mass/Wave Start' || type1=='Pursuit')
				  type2='XC';   // because might have both sexes in same race for XC
				if (type1 != '' || type2 != '')
				  headerString += type1 + ', ' + type2
				if (headerString != '')
				  headerString += '<br>'
				headerString += country + ' - ' + state
				var newResort = stripImage(resort, 1)
				if (newResort != '')
				  headerString += ' - ' + resort
				headerString += '<br>' + startTime + '<br>'
    document.getElementById('raceHeader').innerHTML = headerString			
    document.getElementById('raceMessage').innerHTML= message
    }   // end of displayHeader

		function setNumColumns() {
		  // should only be called when it changes, empty all tables since redrawing
				if (raceSource == 'U')
				  numColumns = 6 + numRuns
				else		
				  numColumns = 5 + numRuns
				// delete all rows from tables		
    onCourseComps.length = 0
		  removeTable(onCourseTable)
		  removeTable(recentTable)
		  removeTable(resultTable)
				}				
				
  // start of processResponse
		var TOD = new Date();
		var startTOD = TOD.getTime();
		var outtext = "";
  var lines=text.split("|");  linesLength = lines.length
		var linecount = 0;
		var compsFound = 0;
  while (linecount < linesLength) {
    var items=lines[linecount].split("=");
				if (items[0] == "1") {
				  if (items[1] < myStampStart)
						  break    // this means getting a reply from a previous request!
				  myStampStart = items[2];
    		var TOD = new Date();
      myStampStartTOD = TOD.getTime();
						if (items[3] == 'Y')
						  online.innerHTML = "Resort Online!"
						else
						  online.innerHTML = ""
//						if (items[4] > 3)
//						  nextRefreshTime =	items[4]
						}		
				else if (items[0] == "invalidRaceID") {
				  refreshContinue = 0;
						doCountDown = 0;
      updateMessage.innerHTML='';
      document.countDownForm.countDownBox.value = ''
						onCourseComps.length = 0
				  removeTableAndHeader(onCourseHeader, onCourseTable)
				  removeTableAndHeader(recentHeader, recentTable)
				  removeTableAndHeader(resultHeader, resultTable)
      document.getElementById('raceMessage').innerHTML='';
      document.getElementById('raceHeader').innerHTML="<br>This reference is invalid or the race has been un-registered."
						  + "<blockquote><font face=\"Helvetica, Arial, sans-serif\" size=\"-1\"><b><a href=\"races.php\"><img "
								+ "src=\"images/viewraces.gif\" width=\"104\" height=\"29\" border=\"none\"></a></b></font></blockquote";
				  }
				else if (items[0] == "b") {
				  var who = -1
						if (items[1] != '' && comps.length > 0) {
						  if (comps[0].bib == '')
								  comps.length = 0  // clear out all the comps, this is the "have a bib when didn't before" situation
								var compsLength = comps.length		
        for (var i=0; i<compsLength; i++)
										if (comps[i].bib == items[1]) 
										  who = i
								}				
						if (who == -1)
  				  who = comps.length;
						comps[who] = {myStamp:0, stamp:0, rank: "", bib:"", name:"", team:"", club:"", cclass:"", r1:"", r1AsInt:0, r1Rank:"", r2:"", r2AsInt:0, r2Rank:"", total:"", totalAsInt:2147483500, i11:"", i12:"", i13:"", i14:"", i21:"", i22:"", sp11:"", sp12:"", sp13:""};
						comps[who].bib = items[1]
						}
				else if (items[0] == "m") comps[who].name = items[1]
				else if (items[0] == "t") comps[who].team = items[1]
				else if (items[0] == "c") comps[who].club = items[1]
				else if (items[0] == "s") comps[who].cclass = items[1]
				else if (items[0] == "ms") comps[who].myStamp = items[1]
				else if (items[0] == "st") comps[who].stamp = items[1]
				else if (items[0] == "r1") {
				  comps[who].r1 = items[1]
				  comps[who].r1AsInt = items[2]
						if (items[2] <= 2147483500 && numRuns == 0) {   // 2147483500 = 'on course'
						  numRuns = 1
								setNumColumns()
				    }				
						}				
				else if (items[0] == "r1") {
				  comps[who].r1 = items[1]
				  comps[who].r1AsInt = items[2]
						}				
				else if (items[0] == "r2") {
				  comps[who].r2 = items[1]
				  comps[who].r2AsInt = items[2]
						if (items[2] <= 2147483500 && numRuns < 2) {
						  numRuns = 3  // because 3 columns for 2 runs, and really care about column numbers
								setNumColumns()
								}
						}				
				else if (items[0] == "tt") {
				  comps[who].total = items[1]
						if (type2 == 'Best')
  				  comps[who].totalAsInt = Math.min(comps[who].r1AsInt,comps[who].r2AsInt)
						else	if (comps[who].r1AsInt < 2147483500 && comps[who].r2AsInt < 2147483500)
  				  comps[who].totalAsInt = 1 * comps[who].r1AsInt + 1 * comps[who].r2AsInt
						else		
					  comps[who].totalAsInt = 2147483500
						}				
				else if (items[0] == "endC") {  // end of all competitors
      setRanks()
      displayComps("Y")  // means display all
						compsFound = 1
						}
				else if (items[0] == "i11") {
				  comps[who].i11 = items[1]
				  comps[who].i11AsInt = items[2]
						checkNumIntermediates(1)
						}				
				else if (items[0] == "i12") {
				  comps[who].i12 = items[1]
				  comps[who].i12AsInt = items[2]
						checkNumIntermediates(2)
						}				
				else if (items[0] == "i13") {
				  comps[who].i13 = items[1]
				  comps[who].i13AsInt = items[2]
						checkNumIntermediates(3)
						}				
				else if (items[0] == "i14") {
				  comps[who].i14 = items[1]
				  comps[who].i14AsInt = items[2]
						checkNumIntermediates(4)
						}				
				else if (items[0] == "i21") {
				  comps[who].i21 = items[1]
				  comps[who].i21AsInt = items[2]
						checkNumIntermediates(1)
						}				
				else if (items[0] == "i22") {
				  comps[who].i22 = items[1]
				  comps[who].i22AsInt = items[2]
						checkNumIntermediates(2)
						}				
				else if (items[0] == "sp11") {
				  comps[who].sp11 = items[1]
						checkNumSpeeds(1)
						}				
				else if (items[0] == "sp12") {
				  comps[who].sp12 = items[1]
						checkNumSpeeds(2)
						}				
				else if (items[0] == "sp13") {
				  comps[who].sp13 = items[1]
						checkNumSpeeds(3)
						}				
				else if (items[0] == "hN") {
      var raceName=''; type1=''; type2=''; country=''; state=''; resort=''; startTime=''; message=''; leftLogo=''; rightLogo='';
						var reportID = [];
						var reportName = [];
						if (items[1] != raceSource) {
        raceSource = items[1] 
	  					setNumColumns()
								}
				  raceName = items[2]
						if (items.length > 3)
						  raceName += '=' + items[3]  // because may have split an '=' in an image tag!
						}
				else if (items[0] == "hT") {
				  type1 = items[1]
				  type2 = items[2]
						if (type1 == 'Dual') {
						  numOnCourseRows = 4
								numRecentRows = 4
						  }
						}
				else if (items[0] == "hC") {
				  country = items[1]
				  state = items[2]
						}
				else if (items[0] == "hR") {
				  resort = items[1]
						if (items.length > 2)
						  resort += '=' + items[2]  // because may have split an '=' in an image tag!
						}
				else if (items[0] == "hLL") leftLogo = items[1]
				else if (items[0] == "hLR") rightLogo = items[1]
				else if (items[0] == "hST") startTime = items[1]
				else if (items[0] == "hM") message = items[1]
				else if (items[0] == "hP") {
				  reportID[reportID.length] = items[1];
				  reportName[reportName.length] = items[2];
						}
				else if (items[0] == "hE")
				  displayHeader()
				linecount++
    }		  // end of while
		if (loadingCovered	== 0)
    updateMessage.innerHTML =	''
  if (compsFound == 0)
    displayComps("N")  // means display just the OnCourse & Recent		  
		document.body.style.cursor = 'default';
		
//		var TOD = new Date();
//  var endTOD = TOD.getTime();
// document.getElementById("time").innerHTML = ((endTOD - startTOD) / 1000) + ' '

/*		

  var x=document.getElementById('logTable');
		var q=x.getElementsByTagName('tr')
		var y=x.insertRow(q.length);
 	y.style.backgroundColor='#CCCCCC'
		y.className='table';
  var z=y.insertCell(0);

  for (var i=0; i<lines.length; i++) {
		  if (outtext.length > 0)
				  outtext += "<br>"
		  outtext += lines[i]
				}
		outtext += 'comps length = ' + comps.length + '<br>'
  rows = resultTable.getElementsByTagName('tr')
		outtext += 'results.length = ' + rows.length 
  z.innerHTML=outtext
*/		
  }  // end of processResponse
			
