/***************************************************************
 * Seed Calculator
 *
 * File: seedCaculator.js
 *
 * Description: Populate event data in pool table and calculate seeds.
 *
 * Ver.   Date         Author                 Comments
 * ----    --------      --------                 -------------------------------------------
 * 1.00  08-18-07  Jeff McCollough  original definition
 * 2.00  07-05-08  Jeff McCollough  V1 ~ WIN = 1 point, a LOSS = -1 point and a
 *                                                         TIE = .5 point. V2 ~ WIN = 1 point, a 
 *                                                         LOSS = 0 point and a TIE = .5 point 
 *                                                         ~ Fabio 7-05-08. 
 * SEED RULES ~ From Fabio 8-15-07
 *
 * a.       1. Total record (This is how many games are won vs. lost) 
 *                Hit ties are allowed in this tournament and should give .5 a point.
 * b.       2. Head-to-head (This is the won-loss record of one team vs. the 
 *                other when there is a tie using rule a.)
 * c.       3. Least runs allowed
 * d.      4. Most runs scored
 * e.      5. Coin flip (the program does not need to include 
 *                               this rule because it is done on the field)
 *
 **************************************************************/

// Globals ///////////////////////////////////////////////////////////
var allDocTables = document.getElementsByTagName("table");
var allTeamData = new Array();
var poolTables = new Array();
var poolDataRowIndexStart = new Array();
var eventDataRowIndexStart = new Array();
var EVENTSTART='Time';
var POOLSTART='Seed';
var POOLSIZE=0;
var FULLPOINT=1;
var HALFPOINT=.5;
var CELLWIDTH=10;
var HOMETEAMINDEX=3;  
var HOMETEAMSCOREINDEX=4;  
var AWAYTEAMINDEX=6;  
var AWAYTEAMSCOREINDEX=7;
var SWITCH_RULES_C_AND_D=false;
////////////////////////////////////////////////////////////////////


// main driver function ////////////////////////////////////////////////
function seedCalculator()
{
    getPoolAndEventTables();
    
    for( var i=0;i<poolTables.length;i++ )
    {
		populateTeams(i);
		recordEventOutcomes(i); 
	  	displayEventOutcomes(i);
	  	calculateSeeds(i);
	  	displaySeedOutcomes(i);
	  	
	  	// reset the datastructures for next pool
	  	allTeamData = new Array();
	  	POOLSIZE=0;
    }
}


// look in document tables for teams and events ///////////////////////////
function getPoolAndEventTables()
{
    for( var i=0;i<allDocTables.length;i++)
    {
	 	var curTableRows =  allDocTables[i].rows;
	 	
	    for( var j=0;j<curTableRows.length;j++)
    	{
			var firstCellContents=curTableRows[j].cells[0].innerHTML;
			
			var secondCellContents;
			
			if(curTableRows[j].cells[1])
			{
				secondCellContents=curTableRows[j].cells[1].innerHTML;
				
				// find the tables that have a row where 
	 			// the first cell contains the string "Time"
	 			// this is the list of the event outcomes
				if( secondCellContents.match(EVENTSTART) && 
				     secondCellContents.length < CELLWIDTH )
				{
					eventDataRowIndexStart.push(j+1);
				}
			}
			
			// find the tables that have a row where 
	 		// the first cell contains the string "Seed"
	 		// this is the list of teams in the pool
			if( firstCellContents.match(POOLSTART) && 
			     firstCellContents.length < CELLWIDTH )
			{
				poolTables.push(allDocTables[i]);
				poolDataRowIndexStart.push(j+1);
			}
    	}
    }
}


// initialize our datastructure ///////////////////////////////////////////
function populateTeams(i)
{
	for(var j=poolDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
	{	
		var teamKey = getKey(poolTables[i].rows[j].cells[1].innerHTML);
		
		if(!teamKey)break;
		
		allTeamData[teamKey] = new Array();
		allTeamData[teamKey]['Won'] = 0;
		allTeamData[teamKey]['Lost'] = 0;
		allTeamData[teamKey]['Tie'] = 0;
		allTeamData[teamKey]['RF'] = 0;
		allTeamData[teamKey]['RA'] = 0;
		allTeamData[teamKey]['Seed'] = 0;
		allTeamData[teamKey]['Points'] = 0;
		POOLSIZE++;
	}
}


// populate the datastructure with the event outcomes /////////////////////
function recordEventOutcomes(i)
{
	try{
		for(var j=eventDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
		{
			var homeTeamKey = getKey(poolTables[i].rows[j].cells[HOMETEAMINDEX].innerHTML);
		
			if(!homeTeamKey)break;
		
			var awayTeamKey = getKey(poolTables[i].rows[j].cells[AWAYTEAMINDEX].innerHTML);
			
			var homeTeamRuns = parseInt(poolTables[i].rows[j].cells[HOMETEAMSCOREINDEX].innerHTML.replace(/\&nbsp\;/,""));
			
			var awayTeamRuns = parseInt(poolTables[i].rows[j].cells[AWAYTEAMSCOREINDEX].innerHTML.replace(/\&nbsp\;/,""));
			
			allTeamData[homeTeamKey]['RF']+=homeTeamRuns;
			allTeamData[homeTeamKey]['RA']+=awayTeamRuns;
			allTeamData[awayTeamKey]['RF']+=awayTeamRuns;
			allTeamData[awayTeamKey]['RA']+=homeTeamRuns;	
			
			if(homeTeamRuns>awayTeamRuns)
			{
				allTeamData[homeTeamKey]['Won']++;
				allTeamData[awayTeamKey]['Lost']++;
				allTeamData[homeTeamKey]['Points']++;
				//allTeamData[awayTeamKey]['Points']--; V2
			}
			
			if(homeTeamRuns<awayTeamRuns)
			{
				allTeamData[homeTeamKey]['Lost']++;
				allTeamData[awayTeamKey]['Won']++;
				allTeamData[awayTeamKey]['Points']++;
				//allTeamData[homeTeamKey]['Points']--; V2
			}
			
			if(homeTeamRuns==awayTeamRuns)	
			{
				allTeamData[homeTeamKey]['Tie']++;
				allTeamData[awayTeamKey]['Tie']++;
				allTeamData[awayTeamKey]['Points']+=HALFPOINT;
				allTeamData[homeTeamKey]['Points']+=HALFPOINT;
			}
		}
	} 
	catch(e)
	{
		var teamsToCheck;
			
		teamsToCheck=poolTables[i].rows[j].cells[HOMETEAMINDEX].innerHTML+" or "+poolTables[i].rows[j].cells[AWAYTEAMINDEX].innerHTML;
	
		alert("Problem with team name in event list.\n\nCheck "+teamsToCheck+".\n\nTeam names in Pools and Events tables must be consistent.\n\nBrowser exception:\n\n"+e+".\n\nClick OK to continue however the calculations may contain errors until the team name is corrected."); 
	}
}


// display the table with the event data //////////////////////////////////
function displayEventOutcomes(i)
{
	for(var j=poolDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
	{
		var teamKey = getKey(poolTables[i].rows[j].cells[1].innerHTML);
		
		if(!teamKey)break;
		
		poolTables[i].rows[j].cells[2].innerHTML=allTeamData[teamKey]['Won'];
		poolTables[i].rows[j].cells[2].style.textAlign="center";
		poolTables[i].rows[j].cells[4].innerHTML=allTeamData[teamKey]['Lost'];
		poolTables[i].rows[j].cells[4].style.textAlign="center";
		poolTables[i].rows[j].cells[7].innerHTML=allTeamData[teamKey]['Tie'];
		poolTables[i].rows[j].cells[7].style.textAlign="center";
		poolTables[i].rows[j].cells[10].innerHTML=allTeamData[teamKey]['RF'];
		poolTables[i].rows[j].cells[10].style.textAlign="center";
		poolTables[i].rows[j].cells[13].innerHTML=allTeamData[teamKey]['RA'];
		poolTables[i].rows[j].cells[13].style.textAlign="center";
	}
}


// calculate seeds ////////////////////////////////////////////////////
function calculateSeeds(i)
{
	var currentSeed=1;
	
	for(var poolSize=0;poolSize<POOLSIZE;poolSize++)
	{
		var mostPoints=-100;
		var thisTopSeed="";
		
		for(var j=poolDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
		{
			var teamKey = getKey(poolTables[i].rows[j].cells[1].innerHTML);
		
			if(!teamKey)break;
			
			if(allTeamData[teamKey]['Seed']==0)
			{
				// First we get the teams points, 1 for a win, 
				// -1 for a loss, and .5 for a tie and compare
				// it to the current top seed
				var thisTeamsPoints=allTeamData[teamKey]['Points'];
			
				if(thisTeamsPoints>mostPoints)
				{
					//RULE I: This team has more points than
					// the current top seeeded team
					mostPoints = thisTeamsPoints;
					thisTopSeed=teamKey;
				}
				else if(thisTeamsPoints==mostPoints)
				{
					//RULE II: This team has the same number of points as
					// the current itterations top seed. We will look at how the teams
					// with this number of points that have fared against 
					// this team compared with how the current top seed did
					// against other teams with the same number of points
					var ts = checkHeadToHeadContest(i,thisTopSeed,teamKey,thisTeamsPoints);
					
					if(ts==0)
					{
						// RULE III: We checked the head to head matches with
						// no resolution, we proceed to see who allowed the
						// fewest runs
						
						// In case of c & d rule change
						var raSwitch = 'RA';
						var rfSwitch = 'RF';
						if(SWITCH_RULES_C_AND_D)
						{
							raSwitch = 'RF';
							rfSwitch = 'RA';
						}
						
					 	if(allTeamData[thisTopSeed][raSwitch] <
					 	    allTeamData[teamKey][raSwitch])
					 	{	
							ts=thisTopSeed;
						}
						else if(allTeamData[thisTopSeed][raSwitch] > 
						            allTeamData[teamKey][raSwitch])
						{
							ts=teamKey;
						}
						else if(allTeamData[thisTopSeed][raSwitch] == 
						           allTeamData[teamKey][raSwitch])
						{
							// RULE IV: We checked the head to head matches with
							// no resolution, we proceed to see who allowed the
							// fewest runs, and still have a tie so lets look at who scored 
							// the most runs
							if(allTeamData[thisTopSeed][rfSwitch]>allTeamData[teamKey][rfSwitch])
					 		{
								ts=thisTopSeed;
							}
							else if(allTeamData[thisTopSeed][rfSwitch]<allTeamData[teamKey][rfSwitch])
							{
								ts=teamKey;
							}
							else if(allTeamData[thisTopSeed][rfSwitch]==allTeamData[teamKey][rfSwitch])
							{
								// RULE V: We checked vs, the head to head matches 
								// we proceeded to see who allowed the
								// fewest runs, who scored the most runs
								// and we still have a tie ergo coin flip!						
								alert("Coin Flip Between "+thisTopSeed+" and "
								                                              +teamKey+".");
								ts=thisTopSeed;
							}
						}
					}
					thisTopSeed=ts;
					mostPoints = thisTeamsPoints;
				}
			}
		}
		allTeamData[thisTopSeed]['Seed']=currentSeed++;
		//displaySeedOutcomes(i);
	}
}


// check event list for vs between these teams with this record ///////////
function checkHeadToHeadContest(i,currentTopSeed,challengeSeed,thisTeamsPoints)
{
	
	var currentTopSeedPoints=0;
	var challengeSeedPoints=0;
	
	// get a list of the teams with the same record
	var listOfTeamsWithSameRecord = new Array();
	
	for( var key in allTeamData )
	{
		if(allTeamData[key]['Points']==thisTeamsPoints)
		{
			listOfTeamsWithSameRecord[key]=allTeamData[key];
		}
	}
	
	// get the record of the current team vs the other teams in this set
	// as well as the top team vs the others in the set
	for(var j=eventDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
	{
		var homeTeamKey = getKey(poolTables[i].rows[j].cells[HOMETEAMINDEX].innerHTML);
		
		if(!homeTeamKey)break;
	
		var awayTeamKey = getKey(poolTables[i].rows[j].cells[AWAYTEAMINDEX].innerHTML);
	
		var homeTeamRuns = parseInt(poolTables[i].rows[j].cells[HOMETEAMSCOREINDEX].innerHTML.replace(/\&nbsp\;/,""));
		
		var awayTeamRuns = parseInt(poolTables[i].rows[j].cells[AWAYTEAMSCOREINDEX].innerHTML.replace(/\&nbsp\;/,""));
		
		for( var key in listOfTeamsWithSameRecord )
		{
			// get the record of the current team vs the other teams in this set
			if(key==homeTeamKey &&
		     challengeSeed==awayTeamKey)
			{
				if(homeTeamRuns>awayTeamRuns)
				{
					//challengeSeedPoints--; V2
				}
				else if( homeTeamRuns<awayTeamRuns)
				{
					challengeSeedPoints++;
				}
				else
				{
					challengeSeedPoints+=HALFPOINT;
				}
			}
			else if(key==awayTeamKey && 
		            challengeSeed==homeTeamKey)
			{
			
				if(homeTeamRuns<awayTeamRuns)
				{
					//challengeSeedPoints--; V2
				}
				else if( homeTeamRuns>awayTeamRuns)
				{
					challengeSeedPoints++;
				}
				else
				{
					challengeSeedPoints+=HALFPOINT;
				}
			}
		}
		
		for( var key in listOfTeamsWithSameRecord )
		{
			// as well as the top team vs the others in the set
			if(currentTopSeed==homeTeamKey &&
		     key==awayTeamKey)
			{
				if(homeTeamRuns>awayTeamRuns)
				{
					currentTopSeedPoints++;
				}
				else if( homeTeamRuns<awayTeamRuns)
				{
					//currentTopSeedPoints--; V2
				}
				else
				{
					currentTopSeedPoints+=HALFPOINT;
				}
			}
			else if(currentTopSeed==awayTeamKey && 
		            key==homeTeamKey)
			{
			
				if(homeTeamRuns<awayTeamRuns)
				{
					currentTopSeedPoints++;
				}
				else if( homeTeamRuns>awayTeamRuns)
				{				
					//currentTopSeedPoints--; V2
				}
				else
				{
					currentTopSeedPoints+=HALFPOINT;
				}
			}
		}
	}
	
	if(currentTopSeedPoints>challengeSeedPoints)
	{
		return currentTopSeed;
	}
	else if(currentTopSeedPoints<challengeSeedPoints)
	{
		return challengeSeed;
	}
	else
	{
		// they tied here too, were going on to rule 3...
		return 0;	
	}
}


// display the seed caculation results ////////////////////////////////////
function displaySeedOutcomes(i)
{
	for(var j=poolDataRowIndexStart[i];poolTables[i].rows[j]!=null;j++)
	{
		var teamKey = getKey(poolTables[i].rows[j].cells[1].innerHTML);
		
		if(!teamKey)break;
			
		poolTables[i].rows[j].cells[0].innerHTML+="&nbsp;<b style='color:navy'>("+allTeamData[teamKey]['Seed']+")</b>";
	}
}


// make a clean key ///////////////////////////////////////////////////
function getKey(s)
{
	// After pool and event listings following cell contains only 
	// space, it's how we indicate the end of the list
	if(s=="&nbsp;")return 0;
	
	// remove spaces
	s=s.replace(/\&nbsp\;/gi,"");	
	s=removeSpaces(s);
	
	// lower case
	return s.toLowerCase();
}


// helper ////////////////////////////////////////////////////////////
function removeSpaces(string) {
	var tstring = "";
	string = '' + string;
	splitstring = string.split(" ");
	for(i = 0; i < splitstring.length; i++)
	tstring += splitstring[i];
	return tstring;
}