// with dcwp.js at bottom







//---------------------------------------------------------------------------
//---------------------------------------------------------------------------





/**
 * Setting the global "usepoisson"
 */
function changeAlgorithm(radiobutton){
    if(radiobutton.value.toLowerCase() == "poisson"){
        usepoisson = true;
    }else{
        usepoisson = false;
    }
}





/**
 * Protoype Function to provide searching in an Array
 */
Array.prototype.inArray = function (value){
    var i;
    for (i=0; i < this.length; i++){
        if (this[i] === value) {
            return true;
        }
    }
    return false;
};


/**
 * Starting the whole thing
 */ 
function startCalculation(){
	//
	deactivateButtons2();
	//
    if(!cachingDone){
        cache();
        cachingDone = true;
    }
    timerMethod    = window.setInterval("compute()", computeInterval);
    timerCountdown = window.setInterval("autosave()", autosaveInterval);

	// ATTN: mouser, 06/01/06
	// Initialize Simulation data with user data
	Simulation_RunBegins();

	// initialize display
	Simulation_UpdateAllDisplays();
}


/** 
 * Stopping the Timeouts
 */
function stop(){
	//
	activateButtons2();
	//
    window.clearInterval(timerMethod);
    window.clearInterval(timerCountdown);

	// ATTN: mouser, 06/01/06
	// Round of Iteration stops - this should NOT be called on a pause
	Simulation_RunEnds();
}

/**
 * Stop - save - start again :)
 */
function autosave(){

// ATTN: mouser disable
	return;



    stop();
//    document.matrix.action = 'posthandler.php';
//    document.matrix.target = 'server';
//    document.matrix.submit();


    alert('autosave should fire here');

    window.setTimeout("startCalculation()",3000);
}


/**
 * Callingfunction for the real Algorithm - takes care of the GUI updating
 * This Function is call in setIntervall
 */
function compute(){



	// ATTN: mouser, 06/01/06
	// Initialize Simulation data with user data
	var FinalWinner=Simulation_Iterate();

	// update display
	Simulation_UpdateOutputDisplay(FinalWinner);

/*
	// Dummy test results
    var randomNumbers = new Array();
    for(var i=0; i<32; i++){
        randomNumbers[i] = doTheMath();
        resultsCache[i]['D'].value = Math.round(randomNumbers[i]*10);
        resultsCache[i]['H'].value = randomNumbers[i];
    }
*/
}
   
   
/**
 * Dummy for the real Algorithm ;)
 */
function doTheMath(){
    var n = Math.random()*10;
    for(i=0; i<10; i++){
        n = Math.ceil(n);
        n = n + 21;
        n = n * 7;
        n = Math.sqrt(n);
        n = Math.pow(n,3);
        n = n + Math.random()*10;
        n = n / 3;
        n = Math.pow(n,2);
        n = n % 2;
        n = n + 1;
    }
    return n;
}


/**
 * Ask the User for a Filename before Saving the File the first time
 * The saving the secondtime will overwrite the old file...
 */ 
function askForTitle(){
    if(document.forms["matrix"].elements["title"].value == ''){
        alert("Please enter a Title for this setting")
        return false;
    }else{

		// progress
		//var responsetext=document.getElementById("response");
		//responsetext.innerHTML = "Saving file, please wait..";
        //return true;
    }
    /*
        var description = window.prompt('Please enter a Name for the Savefile','');
        if(description == ''){
            description = 'noname';
        }else{
            document.forms["matrix"].elements["description"].value = description;
        }
    }
    return true;
    */
}



function editThisSetting(){
    document.controllexpert.action = 'edit.php';
    document.controllexpert.submit();
    return true;
}


function createNewSetting(){
    document.controllexpert.action = 'edit.php?new';
    document.controllexpert.submit();
    return true;
}




function editThisSettingN(){
    document.controll.action = 'edit.php';
    document.controll.submit();
    return true;
}

function createNewSettingN(){
    document.controll.action = 'edit.php?new';
    document.controll.submit();
    return true;
}










/**
 * Fills the 32 ResultFields with Random Numbers
 */
function fillWithRandomResults(t){
    if(deactivateButtons()){
        var start = new Date();
        for(var i=0; i<32; i++){
            if(document.forms['matrix'].elements['resD_'+i].value == ''){
                document.forms['matrix'].elements['resD_'+i].value = Math.round(Math.random()*100);
            }
        }
        var done = new Date();
        alert('Finished Filling the Results - it took '+(done-start)/1000+' seconds');
        activateButtons();
    }
}   

        
/**
 * This Function cashes all the References to the Formfields
 * The alert() is for Debugging only and should be disabled 
 * before going life
 *
 * THIS MUST BE CALLED AFTER THE PAGELOAD
 */
function cache(){
    var start = new Date();
    var count = 0;

/*
    for(var i=0; i<32; i++){
        for(var j=0; j<32; j++){
            if(i < j){
                inputCache[i] = new Array();
                inputCache[i][j] = new Array();
                inputCache[i][j][1]    = document.forms['matrix'].elements['s'+i+'_'+j+'_1'];
                inputCache[i][j][2]    = document.forms['matrix'].elements['s'+i+'_'+j+'_2'];
                inputCache[i][j]['p1'] = document.forms['matrix'].elements['s'+i+'_'+j+'_p1'];
                inputCache[i][j]['p2'] = document.forms['matrix'].elements['s'+i+'_'+j+'_p2'];
                count += 3;
            }
        }
    }
*/

    
    for(var i=0; i<32; i++){
        resultsCache[i]      = new Array();
        resultsCache[i]['D'] = document.forms['matrix'].elements['resD_'+i];
        resultsCache[i]['H'] = document.forms['matrix'].elements['resH_'+i];
        count += 2;            
    }
    var done = new Date();


/*
	// ATTN: mouser, 06/01/06
	// Initialize Simulation data with user data
	Simulation_RunBegins();

	// initialize display
	Simulation_UpdateAllDisplays();
*/
}




/**
 * Deactivates all Buttons on the Page. The change is not vissible during the
 * caching, but it should provide at least a little security for interrupting 
 * the caching...
 */
function deactivateButtons(){
    if(buttonCache.length == 0){
        var inputs = document.getElementsByTagName('input');
        for (var x=0; x<inputs.length; x++){
            if((inputs[x].type == 'button' || inputs[x].type == 'submit')){
                inputs[x].disabled = true;
                buttonCache.push(inputs[x]);
            }
        }
        return true;
    }else{
        for (var x=0; x<buttonCache.length; x++){
            if((buttonCache[x].type == 'button' || buttonCache[x].type == 'submit')){
                buttonCache[x].disabled = true;
            }
        }    
    }
}
        
    
/**
 * ReActivtes the Buttons 
 */
function activateButtons(){
    if(buttonCache.length == 0){
        var inputs = document.getElementsByTagName('input');
        for (var x=0; x<inputs.length; x++){
            if((inputs[x].type == 'button' || inputs[x].type == 'submit')){
                inputs[x].disabled = false;
                buttonCache.push(inputs[x]);
            }
        }    
    }else{
        for (var x=0; x<buttonCache.length; x++){
            if((buttonCache[x].type == 'button' || buttonCache[x].type == 'submit')){
                buttonCache[x].disabled = false;
            }
        }
    }
}  







//---------------------------------------------------------------------------
/**
 * Deactivates all Buttons on the Page. The change is not vissible during the
 * caching, but it should provide at least a little security for interrupting 
 * the caching...
 */
function deactivateButtons2(){
	document.forms['matrix'].elements['startbutton'].disabled = true;
    document.forms['matrix'].elements['stopbutton'].disabled = false;
}
        
    
/**
 * ReActivtes the Buttons 
 */
function activateButtons2(){
	document.forms['matrix'].elements['startbutton'].disabled = false;
    document.forms['matrix'].elements['stopbutton'].disabled = true;
}  


function deactivateButtonsAll(){
	//document.forms['matrix'].elements['startbutton'].disabled = true;
    //document.forms['matrix'].elements['stopbutton'].disabled = true;
}
//---------------------------------------------------------------------------










































//---------------------------------------------------------------------------
// DonationCoder.com World Cup Simulator
// Javascript Markov Chain Monte Carlo Code by mouser, June 1st, 2006
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// global display level (set to 9 for testing)
var DebugDisplay=0;
// debugging output window
var dcwcpw;
// global teams array
var teams = new Array();
// display update counters
var results_updaterate_quick=10;
var results_updaterate_full=100;
var results_updaterate_counter_quick=0;
var results_updaterate_counter_full=0;
// tournaments run in this batch
var tournamentsrun=0;
var max_tournamentswon=0;
// use poisson or gaussians?
var usepoisson=true;
// show results
var showresultcounts=false;
// width of graph
var graphbarwidth=150;
//---------------------------------------------------------------------------















//---------------------------------------------------------------------------
function Simulation_RunBegins()
{
	// Called after team ratings have been adjusted, before begining
	//  a series of iterations.
	// Can be called each time a reset is desired of stats.

	// open debug window
	if (DebugDisplay>0)
		OpenDebugWindow();

	// initialize data
	InitializeTeams(true);
}


function Simulation_Iterate()
{
	// perform a single iteration
	var FinalWinner=PlayATournament();
	if (DebugDisplay>0)
		dcwcpw.document.write('FINAL CUP WINNER: ',teams[FinalWinner].IdName,'<br/>\n');
	return FinalWinner;
}


function Simulation_RunEnds()
{
	if (DebugDisplay>0)
		CloseDebugWindow();
}
//---------------------------------------------------------------------------






































//---------------------------------------------------------------------------
function OpenDebugWindow()
{
    dcwcpw = window.open("","Simulated Games","resizable,scrollbars,menubar,width=400,heigth=250");
    dcwcpw.document.open();
    dcwcpw.document.write('<h1>Simulated Games</h1>');
    dcwcpw.document.write('Results of the Simulated Games you requested.<p>');
}


function CloseDebugWindow()
{
	// end stuff
    dcwcpw.document.write('<form><center>');
    dcwcpw.document.write('<input type=button value="Close" onClick=window.close()>');
    dcwcpw.document.write('</form></center>');
    dcwcpw.document.write('<hr>\n');
    dcwcpw.document.close();
}
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
function output_playgames() {
	// TEST FUNCTION USED FOR STANDALONE TESTING

	// open debugging output window
	OpenDebugWindow();

	// INIT - do this once before iterations
	InitializeTeams(true);

	// ITERATION LOOP
	var tournamentcount=document.inputpar.tournamentruns.value;
	var FinalWinner;
	for (var t=0;t<tournamentcount;t++)
		{
		// choose a winner
		FinalWinner=PlayATournament();
		//
		if (DebugDisplay>1)
			dcwcpw.document.write('FINAL CUP WINNER: ',teams[FinalWinner].IdName,'<br/>\n');
		}

	// close debugging output window
	CloseDebugWindow();

    return false;
}
//---------------------------------------------------------------------------














//---------------------------------------------------------------------------
function PlayRoundOneGroup(grouptitle,groupteamlist,top2list)
{
	// play a round robin for all teams in grouplist against each other

	// mean and variance values
	var mean1,mean2;
	var variance1,variance2;

	// number of teams
	var teamcount=groupteamlist.length;

	// display
	if (DebugDisplay>2)
		dcwcpw.document.write('GROUP ',grouptitle,' - ROUND ONE GAMES<br/>\n');

	// round robin games
    for (var team1 = 0; team1 < teamcount; team1++)
		{
    	for (var team2 = team1+1; team2 < teamcount; team2++)
			{
			// now play the teams against each other
			PlaySimulatedGame(teams[groupteamlist[team1]],teams[groupteamlist[team2]],true,true);
			}
		}


	// summaries
	if (DebugDisplay>2)
		{
		dcwcpw.document.write('<br/>\n');
		for (var i = 0; i<teamcount; i++)
			{
			dcwcpw.document.write(teams[groupteamlist[i]].IdName,': ',teams[groupteamlist[i]].Points,' points, ',teams[groupteamlist[i]].Goals,' goals, and ',teams[groupteamlist[i]].GoalDifference,' goal differential.<br/>\n');
			}
		// separator
		dcwcpw.document.write('<br/>\n');
		}

	// now get top 2 rankings
	RankRoundOneGroupTeams(groupteamlist,top2list);

	if (DebugDisplay>2)
		{
		// and display them
		dcwcpw.document.write('1st Rank Team is ',teams[top2list[0]].IdName,'<br/>\n');
		dcwcpw.document.write('2nd Rank Team is ',teams[top2list[1]].IdName,'<br/>\n');
		// separator
		dcwcpw.document.write('<br/>\n');
		dcwcpw.document.write('<br/>\n');
		}
}
//---------------------------------------------------------------------------







//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
function RankRoundOneGroupTeams(teamidlist,top2list)
{
	// take the 4 teamidlist[0] through teamidlist[3] and set ranklist[0] to first ranked, and ranklist[1] to 2nd rank
	// Since 1994, three points have been awarded for a win, one for a draw and none for a loss (prior to this, winners only received two points).
	//  The top two teams from each group advance to the second stage (the knockout stage).
	//  If two or more teams finish level on points, tie-breakers are used: first is goal difference, then total goals scored, then head-to-head results, and finally drawing of lots.
	// NOTE: we don't obey the penultimate tiebreaker (head to head)

	// this isnt the most efficient sort but we could replace it with a custom object sort later - for 4 objects it doesnt make much of a difference

	// init
	var bestid,bestnum;
	var tempid;
	var thisid;

	// loop and find best two
	for (var j=0; j<2; j++)
		{
		// pick the jth top
		bestid=teamidlist[j];
		bestnum=j
	    for (var i = j+1; i < 4; i++)
			{
			thisid=teamidlist[i];
			if (teams[bestid].Points<teams[thisid].Points)
				{
				bestid=thisid;
				bestnum=i;
				}
			else if (teams[bestid].Points==teams[thisid].Points)
				{
				if (teams[bestid].GoalDifference<teams[thisid].GoalDifference)
					{
					bestid=thisid;
					bestnum=i;
					}
				else if (teams[bestid].GoalDifference==teams[thisid].GoalDifference)
					{
					if (teams[bestid].Goals<teams[thisid].Goals)
						{
						bestid=thisid;
						bestnum=i;
						}
					else if (teams[bestid].Goals==teams[thisid].Goals)
						{
						// rules say we should choose based on head to head, but instead we do it randomly
						if (Math.random()<0.5)
							{
							bestid=thisid;
							bestnum=i;
							}
						}
					}
				}
			}
		// ok now store away the top one into the top teamidlist slot
		tempid=teamidlist[j];
		teamidlist[j]=bestid;
		teamidlist[bestnum]=tempid;
		}

	// now top 2
	top2list[0]=teamidlist[0];
	top2list[1]=teamidlist[1];
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
function TeamObjectContruct(teamIdName,teamIdIndex,grabstats)
{
	this.IdName = teamIdName;
	this.IdIndex = teamIdIndex;
	this.LastScore = 0;
	this.Points = 0;
	this.Goals = 0;
	this.GoalDifference = 0;
	this.TournamentWins = 0;
	//
	this.OddsPrediction = 31;
	//this.OddsBettingLine = Math.round(Math.random()*400+30)/10;
	this.OddsBettingLine = 100;

	// now grab mean and variance table data
	this.MeanArrayUs = new Array();
	this.MeanArrayUsR2 = new Array();
	this.VarianceArrayUs = new Array();
	this.DidPlayArrayUs = new Array();
	this.DidPlay2ArrayUs = new Array();

	if (grabstats)
		{
		// grab data from FORM
		for (var i=0;i<=31;i++)
			{
			if (teamIdIndex<i)
				{
				this.MeanArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+teamIdIndex+'_'+i+'_1'].value);
				this.VarianceArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+teamIdIndex+'_'+i+'_p1'].value);
				this.DidPlayArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+teamIdIndex+'_'+i+'_dp'].value);
				this.DidPlay2ArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+teamIdIndex+'_'+i+'_dp2'].value);
				if (this.DidPlay2ArrayUs[i]==1)
					{
					this.MeanArrayUsR2[i]=parseFloat(document.forms['matrix'].elements['s'+teamIdIndex+'_'+i+'_1_r2'].value);
					}
				else
					this.MeanArrayUsR2[i]=0;
				}
			else if (teamIdIndex>i)
				{
				this.MeanArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+i+'_'+teamIdIndex+'_2'].value);
				this.VarianceArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+i+'_'+teamIdIndex+'_p2'].value);
				this.DidPlayArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+i+'_'+teamIdIndex+'_dp'].value);
				this.DidPlay2ArrayUs[i]=parseFloat(document.forms['matrix'].elements['s'+i+'_'+teamIdIndex+'_dp2'].value);
				if (this.DidPlay2ArrayUs[i]==1)
					{
					this.MeanArrayUsR2[i]=parseFloat(document.forms['matrix'].elements['s'+i+'_'+teamIdIndex+'_2_r2'].value);
					}
				else
					this.MeanArrayUsR2[i]=0;
				}
			}
		}

	// reset tournaments won
	tournamentsrun=0;
	max_tournamentswon=0;
}









function ClearTeamScores()
{
	var teamcount=teams.length;
	for (var i=0;i<teamcount;i++)
		{
		teams[i].LastScore = 0;
		teams[i].Points = 0;
		teams[i].Goals = 0;
		teams[i].GoalDifference = 0;
		// note we dont clear tournament win count
		}
}
//---------------------------------------------------------------------------




//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
function PlaySimulatedGame(team1,team2,tieallowed,isroundone)
{
	// play a simulated game between two teams and create an object to hold the results
	// update team stats and
	// return team id of winner or -1 on tie

	// set values
	var team1Mean,team2Mean,team1Variance,team2Variance;

	// ATTN: DUMMY VALUES!!!
	team1Mean=team1.MeanArrayUs[team2.IdIndex];
	team2Mean=team2.MeanArrayUs[team1.IdIndex];
	team1Variance=team1.VarianceArrayUs[team2.IdIndex];
	team2Variance=team2.VarianceArrayUs[team1.IdIndex];
	DidPlay=team1.DidPlayArrayUs[team2.IdIndex];
	DidPlay2=team1.DidPlay2ArrayUs[team2.IdIndex];
	team1MeanR2=team1.MeanArrayUsR2[team2.IdIndex];
	team2MeanR2=team2.MeanArrayUsR2[team1.IdIndex];

	if (DebugDisplay>10)
		{
		// display results
		//dcwcpw.document.write('t1m=',team1Mean,' t2m=',team2Mean,' t1v=',team1Variance,' t2v=',team2Variance,'<br>\n');
		}



	// ATTN: temporary hack to handle case of 100 variance meaning 0
	if (team1Variance==100)
		team1Variance=0;
	if (team2Variance==100)
		team2Variance=0;


	if (team1Variance==0 && team2Variance==0)
		{
		score1=team1Mean;
		score2=team2Mean;
		}
	else if (DidPlay==1 && isroundone)
		{
		score1=team1Mean;
		score2=team2Mean;
		}
	else if (DidPlay2==1 && !isroundone)
		{
		score1=team1MeanR2;
		score2=team2MeanR2;
		}
	else
		{
		// compute scores
		if (usepoisson)
			{
			score1=PrngPoisson(team1Mean+0.1);
			score2=PrngPoisson(team2Mean+0.1);
			}
		else
			{
			score1=gauss(team1Mean,team1Variance);
			score2=gauss(team2Mean,team2Variance);

			// never less than 0 (this does disturb the probability distribution a bit, but i think in a reasonable way)
			// a	lways integer? (we could leave these decimaled and only round on display, to each tie comparisons?)
			score1=Math.round(Math.max(score1,0.0));
			score2=Math.round(Math.max(score2,0.0));
			}

		}


	// ATTN: TODO
	// IMPORTANT!! a better way should be chosen to favor one team over another instead of randomly picking a winner
	if (!tieallowed && score1==score2)
		{
		// break the tie - simulate a guess about who would win free kicks

		// we use means+variances to again run the tie resolution
		var score1e=gauss(team1Mean,team1Variance);
		var score2e=gauss(team2Mean,team2Variance);
		if (score1e>score2e)
			score1+=1;
		else if (score2e>score1e)
			score2+=1;
		else
			{
			// still no resolution!!
			if (Math.random()<0.5)
				score1+=1;
			else
				score2+=1;
			}
		}


	// store values
	team1.LastScore=score1;
	team2.LastScore=score2;
	team1.Goals+=score1;
	team2.Goals+=score2;
	team1.GoalDifference+=(score1-score2);
	team2.GoalDifference+=(score2-score1);


	if (DebugDisplay>2)
		{
		// display results
		dcwcpw.document.write(team1.IdName,' v. ',team2.IdName,' -> ',team1.LastScore,' - ',team2.LastScore,'<br>\n');
		}


	// points and return value
	// Since 1994, three points have been awarded for a win, one for a draw and none for a loss (prior to this, winners only received two points). The top two teams from each group advance to the second stage (the knockout stage). If two or more teams finish level on points, tie-breakers are used: first is goal difference, then total goals scored, then head-to-head results, and finally drawing of lots.[13]

	if (score1==score2)
		{
		team1.Points+=1;
		team2.Points+=1;
		return -1;
		}
	else if (score1>score2)
		{
		team1.Points+=3;
		return team1.IdIndex;
		}
	else
		{
		team2.Points+=3;
		return team2.IdIndex;
		}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
function InitializeTeams(grabstats)
{
	// create the team array
	
	// create teams
	var teamindex=0;
	teams[0]= new TeamObjectContruct('Angola',teamindex++,grabstats);
	teams[1]= new TeamObjectContruct('Argentina',teamindex++,grabstats);
	teams[2]= new TeamObjectContruct('Australia',teamindex++,grabstats);
	teams[3]= new TeamObjectContruct('Brazil',teamindex++,grabstats);
	teams[4]= new TeamObjectContruct('Costa Rica',teamindex++,grabstats);
	teams[5]= new TeamObjectContruct('Croatia',teamindex++,grabstats);
	teams[6]= new TeamObjectContruct('Czech Republic',teamindex++,grabstats);
	teams[7]= new TeamObjectContruct('Ecuador',teamindex++,grabstats);
	teams[8]= new TeamObjectContruct('England',teamindex++,grabstats);
	teams[9]= new TeamObjectContruct('France',teamindex++,grabstats);
	teams[10]= new TeamObjectContruct('Germany',teamindex++,grabstats);
	teams[11]= new TeamObjectContruct('Ghana',teamindex++,grabstats);
	teams[12]= new TeamObjectContruct('Holland/Netherlands',teamindex++,grabstats);
	teams[13]= new TeamObjectContruct('Iran',teamindex++,grabstats);
	teams[14]= new TeamObjectContruct('Italy',teamindex++,grabstats);
	teams[15]= new TeamObjectContruct('Ivory Coast',teamindex++,grabstats);
	teams[16]= new TeamObjectContruct('Japan',teamindex++,grabstats);
	teams[17]= new TeamObjectContruct('Mexico',teamindex++,grabstats);
	teams[18]= new TeamObjectContruct('Paraguay',teamindex++,grabstats);
	teams[19]= new TeamObjectContruct('Poland',teamindex++,grabstats);
	teams[20]= new TeamObjectContruct('Portugal',teamindex++,grabstats);
	teams[21]= new TeamObjectContruct('Saudi Arabia',teamindex++,grabstats);
	teams[22]= new TeamObjectContruct('Serbia+Montenegro',teamindex++,grabstats);
	teams[23]= new TeamObjectContruct('South Korea',teamindex++,grabstats);
	teams[24]= new TeamObjectContruct('Spain',teamindex++,grabstats);
	teams[25]= new TeamObjectContruct('Sweden',teamindex++,grabstats);
	teams[26]= new TeamObjectContruct('Switzerland',teamindex++,grabstats);
	teams[27]= new TeamObjectContruct('Togo',teamindex++,grabstats);
	teams[28]= new TeamObjectContruct('Trinidad+Tobago',teamindex++,grabstats);
	teams[29]= new TeamObjectContruct('Tunisia',teamindex++,grabstats);
	teams[30]= new TeamObjectContruct('Ukraine',teamindex++,grabstats);
	teams[31]= new TeamObjectContruct('USA',teamindex++,grabstats);


	// update betting lines
	UpdateBettingLines();
}
//---------------------------------------------------------------------------


// group H - 24,30,29,21




//---------------------------------------------------------------------------

// group A - 10,7,4,19
// group B - 8,25,28,18
// group C - 1,12,15,22
// group D - 17,20,0,13
// group E - 6,14,11,31
// group F - 2,3,5,16
// group G - 9,26,23,27
// group H - 24,30,29,21
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
function PlayATournament()
{
	// return the id of final winner

	// clear scores before teach tournament
	ClearTeamScores();

	// PLAY THE ROUND ROBIN STAGE 1 GAMES
	//var Agrouplist = new Array(11,4,20,8);
	var Agrouplist = new Array(10,7,4,19);
	var Agrouptop2 = new Array();
	PlayRoundOneGroup('A',Agrouplist,Agrouptop2);
	//
	//var Bgrouplist = new Array(9,19,28,25);
	var Bgrouplist = new Array(8,25,28,18);
	var Bgrouptop2 = new Array();
	PlayRoundOneGroup('B',Bgrouplist,Bgrouptop2);
	//
	//var Cgrouplist = new Array(1,5,23,18);
	var Cgrouplist = new Array(1,12,15,22);
	var Cgrouptop2 = new Array();
	PlayRoundOneGroup('C',Cgrouplist,Cgrouptop2);
	//
	//var Dgrouplist = new Array(17,13,0,21);
	var Dgrouplist = new Array(17,20,0,13);
	var Dgrouptop2 = new Array();
	PlayRoundOneGroup('D',Dgrouplist,Dgrouptop2);
	//
	//var Egrouplist = new Array(14,12,30,7);
	var Egrouplist = new Array(6,14,11,31);
	var Egrouptop2 = new Array();
	PlayRoundOneGroup('E',Egrouplist,Egrouptop2);
	//
	//var Fgrouplist = new Array(3,6,2,15);
	var Fgrouplist = new Array(2,3,5,16);
	var Fgrouptop2 = new Array();
	PlayRoundOneGroup('F',Fgrouplist,Fgrouptop2);
	//
	//var Ggrouplist = new Array(10,26,16,27);
	var Ggrouplist = new Array(9,26,23,27);
	var Ggrouptop2 = new Array();
	PlayRoundOneGroup('G',Ggrouplist,Ggrouptop2);
	//
	//var Hgrouplist = new Array(24,31,29,22);
	var Hgrouplist = new Array(24,30,29,21);
	var Hgrouptop2 = new Array();
	PlayRoundOneGroup('H',Hgrouplist,Hgrouptop2);

	// LAST16 Round
	// indices from http://en.wikipedia.org/wiki/Football_World_Cup_2006
	var R1 = PlaySimulatedGame(teams[Agrouptop2[0]],teams[Bgrouptop2[1]],false,false);
	var R2 = PlaySimulatedGame(teams[Cgrouptop2[0]],teams[Dgrouptop2[1]],false,false);
	var R3 = PlaySimulatedGame(teams[Bgrouptop2[0]],teams[Agrouptop2[1]],false,false);
	var R4 = PlaySimulatedGame(teams[Dgrouptop2[0]],teams[Cgrouptop2[1]],false,false);
	var R5 = PlaySimulatedGame(teams[Egrouptop2[0]],teams[Fgrouptop2[1]],false,false);
	var R6 = PlaySimulatedGame(teams[Ggrouptop2[0]],teams[Hgrouptop2[1]],false,false);
	var R7 = PlaySimulatedGame(teams[Fgrouptop2[0]],teams[Egrouptop2[1]],false,false);
	var R8 = PlaySimulatedGame(teams[Hgrouptop2[0]],teams[Ggrouptop2[1]],false,false);
	//
	if (DebugDisplay>2)
		{
		// display results
		dcwcpw.document.write('<br/>\n');
		dcwcpw.document.write('R1 Winner is ',teams[R1].IdName,'<br/>\n');
		dcwcpw.document.write('R2 Winner is ',teams[R2].IdName,'<br/>\n');
		dcwcpw.document.write('R3 Winner is ',teams[R3].IdName,'<br/>\n');
		dcwcpw.document.write('R4 Winner is ',teams[R4].IdName,'<br/>\n');
		dcwcpw.document.write('R5 Winner is ',teams[R5].IdName,'<br/>\n');
		dcwcpw.document.write('R6 Winner is ',teams[R6].IdName,'<br/>\n');
		dcwcpw.document.write('R7 Winner is ',teams[R7].IdName,'<br/>\n');
		dcwcpw.document.write('R8 Winner is ',teams[R8].IdName,'<br/>\n');
		}


	// QUARTER FINALS
	var Q1 = PlaySimulatedGame(teams[R1],teams[R2],false,false);
	var Q2 = PlaySimulatedGame(teams[R5],teams[R6],false,false);
	var Q3 = PlaySimulatedGame(teams[R3],teams[R4],false,false);
	var Q4 = PlaySimulatedGame(teams[R7],teams[R8],false,false);
	if (DebugDisplay>2)
		{
		// display results
		dcwcpw.document.write('<br/>\n');
		dcwcpw.document.write('Q1 Winner is ',teams[Q1].IdName,'<br/>\n');
		dcwcpw.document.write('Q2 Winner is ',teams[Q2].IdName,'<br/>\n');
		dcwcpw.document.write('Q3 Winner is ',teams[Q3].IdName,'<br/>\n');
		dcwcpw.document.write('Q4 Winner is ',teams[Q4].IdName,'<br/>\n');
		}


	// SEMI FINALS
	var S1 = PlaySimulatedGame(teams[Q1],teams[Q2],false,false);
	var S2 = PlaySimulatedGame(teams[Q3],teams[Q4],false,false);
	if (DebugDisplay>2)
		{
		// display results
		dcwcpw.document.write('<br/>\n');
		dcwcpw.document.write('S1 Winner is ',teams[S1].IdName,'<br/>\n');
		dcwcpw.document.write('S2 Winner is ',teams[S2].IdName,'<br/>\n');
		}


	// FINAL
	var FinalWinner = PlaySimulatedGame(teams[S1],teams[S2],false,false);
	if (DebugDisplay>2)
		{
		// display results
		dcwcpw.document.write('<br/>\n');
		dcwcpw.document.write('FINAL WINNER: ',teams[FinalWinner].IdName,'<br/>\n');
		}


	// update count for final winner
	teams[FinalWinner].TournamentWins++;

	// and count of tournaments
	++tournamentsrun;

	// return final winner
	return FinalWinner;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------













//---------------------------------------------------------------------------
function Simulation_UpdateOutputDisplay(FinalWinner)
{
	// update display on form
	// FinalWinner is last winner
	++results_updaterate_counter_quick;
	++results_updaterate_counter_full;

	if (FinalWinner>-1 && teams[FinalWinner].TournamentWins>max_tournamentswon)
		max_tournamentswon=teams[FinalWinner].TournamentWins;
	
	// tournament counter
	if (true)
		{
		document.forms['matrix'].elements['TournamentsRun'].value=tournamentsrun;
		}


	// always display quick counter, count of wins for last winner
	if (FinalWinner>-1 && showresultcounts)
		{
		document.forms['matrix'].elements['resD_'+FinalWinner].value=teams[FinalWinner].IdName+' '+(teams[FinalWinner].TournamentWins).toString();
		}


	//
	if (results_updaterate_counter_quick>=results_updaterate_quick)
		{
		// quick display update
		results_updaterate_counter_quick=0;
		}

	//
	if (results_updaterate_counter_full>=results_updaterate_full || FinalWinner==-1)
		{
		// full update of probabilities
		results_updaterate_counter_full=0;

		// display all updated probabilities
		var chartoutput=graphit(graphbarwidth);
		// move this to a one-time thing for efficiency later?
		var divdocel=document.getElementById("divResultChart");
		divdocel.innerHTML = chartoutput;
		// divdocel.style.display = "block";
		}

}



function Simulation_UpdateAllDisplays()
{
	Simulation_UpdateOutputDisplay(-1);

//	for (var i=0;i<=31;i++)
//		{
//		Simulation_UpdateOutputDisplay(i);
//		}
}
//---------------------------------------------------------------------------















//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// normal, gauss functions are from http://www.umiacs.umd.edu/users/liberato/software/gauss.html 
// Vincenzo Liberatore

/* 
   Function normal.
   Generator of pseudo-random number according to a normal distribution with mean=0 and variance=1. Use the Box-Mulder (trigonometric) method, and discards one of the two generated random numbers. 
*/
function normal() { 
  var u1,u2; 
  u1 = u2 = 0.; 
  while (u1 * u2 == 0.) { 
    u1 = Math.random(); 
    u2 = Math.random(); 
  } 
  return Math.sqrt(-2. * Math.log(u1)) * Math.cos(2 * Math.PI * u2); 
} 


/* 
  Function gauss 
  Generator of pseudo-random number according to a normal distribution with given mean and variance. Normalizes the outcome of function normal. 
*/ 
function gauss(mean,stdev) { 
  return stdev * normal() + 1. * mean; 
} 
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------











//---------------------------------------------------------------------------
/* ================================================== 
 * Returns a Poisson distributed non-negative integer. 
 * NOTE: use m > 0
 * ==================================================
 */

function PrngPoisson(m)
{ 
  var t = 0.0;
  var x = 0;

  while (t < m) {
    t += PrngExponential(1.0);
    x++;
  }
  return (x - 1);
}



/* =========================================================
 * Returns an exponentially distributed positive real number. 
 * NOTE: use m > 0.0
 * =========================================================
 */
function PrngExponential(m)
{
  return (-m * Math.log(1.0 - Math.random()));
}
//---------------------------------------------------------------------------























//---------------------------------------------------------------------------
function output_TestPoisson()
{
	// open window?
	OpenDebugWindow();

	var tournamentcount=document.inputpar.tournamentruns.value;
	var goals;
	var goalcount = new Array();
	var meanval=parseFloat(document.inputpar.mean.value);

	// init
	for (var i=0;i<=100;i++)
		{
		goalcount[i]=0;
		}

	// run
	for (var t=0;t<tournamentcount;t++)
		{
		// choose a winner
		goals=PrngPoisson(meanval+0.1);
		if (goals<100)
			goalcount[goals]++;
		}


	// find max
	var maxindex=0;
	for (var i=100;i>=0;i--)
		{
		if (goalcount[i]!=0)
			{
			maxindex=i;
			break;
			}
		}

	// now display
	for (var i=0;i<=maxindex;i++)
		{
		goals=goalcount[i];
		dcwcpw.document.write(i,' \t ',goals,'<br/>\n');		
		}


	// close window?
	CloseDebugWindow();
}
//---------------------------------------------------------------------------



























//---------------------------------------------------------------------------
// from http://www.javascriptkit.com/script/script2/graphit.shtml
function graphit(gwidth)
{
	var graphimage="poll.gif"
	var output='';
	var total=tournamentsrun;
	var ncount=teams.length;
	var barcolwidth=gwidth+60;
	var maxval=max_tournamentswon;



	output='<table border="0" cellspacing="0" cellpadding="0" align="center">\n';
	output+='<tr><td><b><u>Team</u></b></td><td><b><u>Predicted Chance of Winning</u></b></td><td><b><u>Bet Line</u></b></td><td align="center"><b><u>Exp. Profit</u></b></td></tr>\n';

	for (i=0;i<ncount;i++)
		{
		if (total==0)
			{
			bettinglineodds=teams[i].OddsBettingLine;
			bettinglineoddsp=teams[i].OddsBettingLine-1.0;
			output+='<tr><td>'+teams[i].IdName+'&nbsp;</td><td align="center" width="'+barcolwidth+'">to be determinded</td> <td align="center">'+bettinglineodds+':1</td><td align="center">to be determined</td></tr>\n';
			}
		else
			{
			calpercentage=Math.round(teams[i].TournamentWins*100/total);
			calpercentagemax=Math.round(teams[i].TournamentWins*100/maxval);
			calwidth=Math.round(gwidth*(calpercentagemax/100));
			bettinglineodds=teams[i].OddsBettingLine;
			bettinglineoddsp=teams[i].OddsBettingLine-1.0;
			profitcalc=Math.round((calpercentage*bettinglineoddsp)-(100.0-calpercentage))/100.0;
			if (profitcalc<=0.0)
				output+='<tr><td>'+teams[i].IdName+'&nbsp;</td><td align="left" width="'+barcolwidth+'"><img src="'+graphimage+'" width="'+calwidth+'" height="10"> '+calpercentage+'%</td> <td align="center">'+bettinglineodds+':1</td><td align="center">'+profitcalc+'x</td></tr>\n';
			else
				output+='<tr><td>'+teams[i].IdName+'&nbsp;</td><td align="left" width="'+barcolwidth+'"><img src="'+graphimage+'" width="'+calwidth+'" height="10"> '+calpercentage+'%</td> <td align="center">'+bettinglineodds+':1</td><td align="center"><font color="red"><b>'+profitcalc+'</b></font>x</td></tr>\n';
			}
		}

	output+='</table>';
	return output;
}
//---------------------------------------------------------------------------










//---------------------------------------------------------------------------
function SimulationOnLoadInitialize()
{
	// initialize data
	InitializeTeams(false);
	// initialize and display
	Simulation_UpdateAllDisplays();
	//

	if(document.forms['controll'].elements['dataexists'].value=='no')
		{
		deactivateButtonsAll();
		}
	else
		{
		activateButtons2();
		}
}
//---------------------------------------------------------------------------



















//---------------------------------------------------------------------------
/**
 * Fills the 32 Tables with Random Numbers 
 */ 
function fillWithRandomData(t){

    for(var i=0; i<32; i++){
        for(var j=0; j<32; j++){
            if(i < j){
				if (document.forms['matrix'].elements['s'+i+'_'+j+'_dp'].value!="1")
					{
                	document.forms['matrix'].elements['s'+i+'_'+j+'_1'].value=Math.round(Math.random()*50)/10.0;
                	document.forms['matrix'].elements['s'+i+'_'+j+'_2'].value=Math.round(Math.random()*50)/10.0;
					}
                document.forms['matrix'].elements['s'+i+'_'+j+'_p1'].value=Math.round(Math.random()*20)/10.0;
                document.forms['matrix'].elements['s'+i+'_'+j+'_p2'].value=Math.round(Math.random()*20)/10.0;
            }
        }
    }
    return true;
}   


/**
 * Fills the 32 Tables with Random Numbers 
 */ 
function fillVariances(t){
	var varianceval = document.forms['matrix'].elements['allvariance'].value;
	var ename;

    for(var i=0; i<32; i++){
        for(var j=0; j<32; j++){
            if(i < j){
				ename='s'+i+'_'+j+'';
                document.forms['matrix'].elements[ename+'_p1'].value=varianceval;
                document.forms['matrix'].elements[ename+'_p2'].value=varianceval;
            }
        }
    }
    return true;
}   


/**
 * Fills the 32 Tables with Random Numbers 
 */ 
function fillWithInitData(t){
    for(var i=0; i<32; i++){
        for(var j=0; j<32; j++){
            if(i < j){
				if (document.forms['matrix'].elements['s'+i+'_'+j+'_dp'].value!="1")
					{
                	document.forms['matrix'].elements['s'+i+'_'+j+'_1'].value='1.0';
                	document.forms['matrix'].elements['s'+i+'_'+j+'_2'].value='1.0';
					}
                document.forms['matrix'].elements['s'+i+'_'+j+'_p1'].value='1.5';
                document.forms['matrix'].elements['s'+i+'_'+j+'_p2'].value='1.5';
            }
        }
    }
    return true;
}   
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
function UpdateBettingLines()
{
	// this javascript sets betting lines from hidden form data

	var teamcount=teams.length;
	for (var i=0;i<teamcount;i++)
		{
		teams[i].OddsBettingLine = document.forms['matrix'].elements['betline_'+i].value;
		}
}
//---------------------------------------------------------------------------












//---------------------------------------------------------------------------
function TestProbabilities()
{
	// called from test php 
	var gp1,gp2,gpt,pp1,pp2,ppt;
	var pp1count,pp2count,pptcount;
	var gp1count,gp2count,gptcount;
	var mean1,mean2,std1,std2;
	var score1,score2;

	var games=2000;

	mean1=parseFloat(document.forms['matrix'].elements['mean1'].value);
	mean2=parseFloat(document.forms['matrix'].elements['mean2'].value);
	std1=parseFloat(document.forms['matrix'].elements['stddev1'].value);
	std2=parseFloat(document.forms['matrix'].elements['stddev2'].value);

	pp1count=0;
	pp2count=0;
	pptcount=0;
	gp1count=0;
	gp2count=0;
	gptcount=0;

	for (var i=0;i<games;++i)
		{
		score1=PrngPoisson(mean1+0.1);
		score2=PrngPoisson(mean2+0.1);
		if (score1>score2)
			++pp1count;
		else if (score1<score2)
			++pp2count;
		else
			++pptcount;
		//
		score1=gauss(mean1,std1);
		score2=gauss(mean2,std2);
		score1=Math.round(Math.max(score1,0.0));
		score2=Math.round(Math.max(score2,0.0));

		if (score1>score2)
			++gp1count;
		else if (score1<score2)
			++gp2count;
		else
			++gptcount;
		}

	gp1=Math.round((gp1count/games)*100.0);
	gp2=Math.round((gp2count/games)*100.0);
	gpt=Math.round((gptcount/games)*100.0);
	pp1=Math.round((pp1count/games)*100.0);
	pp2=Math.round((pp2count/games)*100.0);
	ppt=Math.round((pptcount/games)*100.0);

	document.forms['matrix'].elements['gausswin1'].value=gp1+"%";
	document.forms['matrix'].elements['gausswin2'].value=gp2+"%";
	document.forms['matrix'].elements['gausswint'].value=gpt+"%";
	document.forms['matrix'].elements['poissonwin1'].value=pp1+"%";
	document.forms['matrix'].elements['poissonwin2'].value=pp2+"%";
	document.forms['matrix'].elements['poissonwint'].value=ppt+"%";
}
//---------------------------------------------------------------------------


