////////////////////////////////////////////////////////////////////
//
// This file contains Javascript functions dealing with tables.
//
////////////////////////////////////////////////////////////////////

/*******************************************************************
 *
 * Function:    stripeTables
 *
 * Description: Finds all the tables on a page and gives them a 
 *              striped appearance by colouring each row a different
 *              colour depending on whether the row has an odd or
 *              even index.
 *              There is no need to call this function as it will be
 *              run automatically by the final line in this file.
 *
 *******************************************************************/
function stripeTables()
{
   if(!document.getElementsByTagName) 
   {
      return;
   }
   tbls = document.getElementsByTagName("table");

   for(ti = 0; ti < tbls.length; ti++) 
   {
      if(tbls[ti].id)
      {
         stripe(""+tbls[ti].id);
      }
   }
}


function stripe(id) 
{
   // the flag we'll use to keep track of 
   // whether the current row is odd or even
   var even = false;

   // if arguments are provided to specify the colours
   // of the even & odd rows, then use them;
   // otherwise use the following defaults:
   var evenColor = arguments[1] ? arguments[1] : "#bbd0dd"; //"#fff"; //"#fc9"; 
   var oddColor = arguments[2] ? arguments[2] : "#dde3ee"; // "#dde3ee"; // "#ffc";

   // obtain a reference to the desired table
   // if no such table exists, abort
   var table = document.getElementById(id);
   if (! table) 
   {
      alert("no table " + id); 
      return; 
   }
 
   //alert("hello")
   // by definition, tables can have more than one tbody
   // element, so we'll have to get the list of child
   // &lt;tbody&gt;s 
   var tbodies = table.getElementsByTagName("tbody");

   // and iterate through them...
   for (var h = 0; h < tbodies.length; h++)
   { 
      // find all the &lt;tr&gt; elements... 
      var trs = tbodies[h].getElementsByTagName("tr");
      //alert("tr.length = " + trs.length)
      // ... and iterate through them
      for (var i = 0; i < trs.length; i++) 
      {
         // avoid rows that have a class attribute
         if (!hasClass(trs[i]) || trs[i].className == "rowOdd" || trs[i].className == "rowEven") 
         {
		      trs[i].className = even ? "rowEven" : "rowOdd";
         }
         //else{alert("Not assigning a class")}
         // flip from odd to even, or vice-versa
         even =  ! even;
      }
   }
}
  
  
/*******************************************************************************
 * 
 * Data recovery functions.
 *
 * The following functions may be used to recover information about or the data
 * contained within table cells or rows. 
 *
 ******************************************************************************/

// this function is needed to work around a bug in IE related to element attributes
function hasClass(obj) 
{
   var result = false;
   if (obj.getAttributeNode("class") != null) 
   {
      result = obj.getAttributeNode("class").value;
   }
   return result;
} 

/*******************************************************************************
 *
 * getCellContents
 *
 * Recovers the contents of a cell
 *
 ******************************************************************************/

function getCellContents(tableID, row, cell)
{
   return getCellValue(tableID.rows[row].cells[cell]);
}

/////////////////////////////////////////////////////////////////
//
// getRowClass
//
// Returns whether a row has the required class.
//
///////////////////////////////////////////////////////////////// 

function getRowClass(curTable, row, classType)
{
   return hasClass(curTable.rows[row]) == classType;
}

function getCellValue(cellOrId) 
{
   var cell; 
   if(typeof cellOrId == 'string')
   { 
      cell = document.all ? document.all[cellOrId] : document.getElementById(cellOrId);
   }
   else
   {
      cell = cellOrId;
   }
   
   if (document.all)
   {
      return cell.innerText;
   }
   else 
   {
      cell.normalize();
      if (cell.firstChild.nodeType == 3)
      {
         return cell.firstChild.nodeValue;
      }
      else if (cell.firstChild.nodeType == 1)
      {
         return cell.firstChild.firstChild.nodeValue;
      }
      else 
      {
         return '';
      }
   }
}

////////////////////////////////////////////////////////////////
//
// runSummary
//
// Checks the diary table and determines if there have been any
// personal bests. This information is then written to the 
// document at the end of the table.
//
////////////////////////////////////////////////////////////////
function runSummary(year)
{
   var tableID = document.all? document.all['runs'] : document.getElementById('runs');
   var pbCount = 0;
   var curDate = new Date();
   var curYear = curDate.getYear();
   if(curYear < 1900)
   {
      curYear += 1900;
   } 
   
   for(var i = 0; i < tableID.rows.length; i++)
   {
      pbCount += getRowClass(tableID, i, "pbest");
   }
   document.write(   "<p>");

   if(parseInt(year) == curYear)
   {
      if(pbCount)
      {
         document.write("So far this year I have achieved personal bests in " + pbCount)
         if(pbCount == 1)
         {
            document.write(" event.<\/p><br><hr>");
         }
         else
         {
            document.write(" events.<\/p><br><hr>");
         }
      }
      else
      {
         document.write("No personal bests so far this year<\/p><br><hr>");
      }
   }
   else
   {
      if(pbCount)
      {
         document.write("This year I achieved personal bests in " + pbCount + " events.<\/p><br><hr>");
      }
      else
      {
         document.write("This year I achieved no personal bests.<\/p><br><hr>");
      }
   }
}

////////////////////////////////////////////////////////////////
//
// dayToDays
//
// Converts the time in milliseconds to the number of days
// since the epoch.
//
////////////////////////////////////////////////////////////////
function dayToDays(inTime)
{
   return inTime.getTime() / (1000 * 60 * 60 * 24);
}

////////////////////////////////////////////////////////////////
//
// mileage
//
// Displays the total mileage and weekly mileage for the year.
//
////////////////////////////////////////////////////////////////
function mileage(year)
{
   var tableID = document.all? document.all['runs'] : document.getElementById('runs');
   var sum = 0;
   var curDate = new Date();
   var yearStart = new Date(year, 0, 1);
   var weeks;
   
   var curYear = curDate.getYear();
   if(curYear < 1900)
   {
      curYear += 1900;
   }
   if(curYear != year)
   {
      weeks = 52;
   }
   else
   {
      weeks = Math.ceil((dayToDays(curDate) - dayToDays(yearStart)) / 7);
   }
   
   for(var r = 1; r < tableID.rows.length; r++)
   {
      sum += parseFloat(getCellContents(tableID, r, 1));
   }
   document.write("<p>Total mileage this year is <b>" + (Math.round(sum * 100)/100) + " <\/b>miles<\/p>");
   document.write("<p>Average weekly mileage is <b>" + (Math.round((sum / weeks) * 100)/100) + " <\/b>miles<\/p>");
}


function addEvent(elm, evType, fn, useCapture)
{
   if(elm.addEventListener)
   {
      elm.addEventListener(evType, fn, useCapture);
      return true;
   }
   else if(elm.attachEvent)
   {
      return elm.attachEvent('on' + evType, fn);
   }
   else
   {
      elm['on' + evType] = fn;
   }
}

// Fire up the message on loading the page.
addEvent(window, 'load', stripeTables, false);

// End of file
 
