/***************************************************************
 **                        Stud Poetry                        **
 **                     Marko Niemi, 2006                     **
 **                  marko.niemi@helsinki.fi                  **
 ***************************************************************/

playerNames  = new Array("Arthur Rimbaud","St&eacute;phane Mallarm&eacute;","Charles Baudelaire","Paul Verlaine","Jean Mor&eacute;as","Paul Val&eacute;ry","G&eacute;rard de Nerval");
pokerhands   = new Array("Straight flush","Four of a kind","Full house","Flush","Straight","Three of a kind","Two pairs","Pair","No pair");
SpeedOptions = new Array(2000,1000,200);
SuitColors   = new Array("#f00","#f00","#000","#000");

AllWords     = new Array("nature","temple","living","pillar","escape","word","man","forest","symbol","observe","familiar","glance","like","long","echo","afar","dark","unity","vast","night","light","perfume","color","sound","respond","fresh","skin","infant","sweet","oboe","green","prairie","other","rich","have","expanse","infinite","thing","musk","incense","sing","balsam","ecstasy","mind","sense");
words        = new Array();
for (i=0; i<13; i++) {
	ChooseWord = Math.floor(Math.random()*AllWords.length);
	words[i] = AllWords[ChooseWord];
	NewWords = new Array();
	for (k=0; k<ChooseWord; k++)
		NewWords[k] = AllWords[k];
	for (k=ChooseWord+1; k<AllWords.length; k++)
		NewWords[k-1] = AllWords[k];
	AllWords = NewWords;
}
options      = new Array("Bet","Call","Raise","Check","Fold","All-in");

deck = new Array();
best = new Array();
fold = new Array();
OutOfMoney = new Array();
suit = new Array();
rank = new Array();
SuitArranged = new Array();
RankArranged = new Array();
HighCards    = new Array();
chips  = new Array();
bets   = new Array();
raises = new Array();
tightness  = new Array();
aggression = new Array();
players = new Array();
TempArray = new Array();

var NumberOfPlayers = 6;
var dealer;
var speed = 1000;
var PlayersFolded;
var YourPosition;
var YourName="&nbsp;";
var pot;
var CardsDealt;
var BetsMade;
var CurrentBetter;
var CurrentStake;
var AllIn;
var RoundOpened;
var amount;
var comment;

function Initialize() {
	dealer = 0;
	TempArray = playerNames;
	YourPosition = Math.floor(Math.random()*NumberOfPlayers);
	players[YourPosition] = YourName;
	document.getElementById("name"+YourPosition).innerHTML=YourName;
	for (i=0; i<NumberOfPlayers; i++) {
		chips[i] = 100;
		bets[i]  = 0;
		OutOfMoney[i] = false;

		document.getElementById("chips"+i).innerHTML=chips[i];
		document.getElementById("bets"+i).innerHTML=bets[i];

		if (i==YourPosition)
			continue;

		tightness[i]  = .05 + .05*Math.random();
		aggression[i] = .2 + .6*Math.random();

		ChoosePlayer = Math.floor(Math.random()*TempArray.length);
		players[i] = TempArray[ChoosePlayer];

		NewNames = new Array();
		for (k=0; k<ChoosePlayer; k++)
			NewNames[k] = TempArray[k];
		for (k=ChoosePlayer+1; k<TempArray.length; k++)
			NewNames[k-1] = TempArray[k];
		TempArray = NewNames;
		document.getElementById("name"+i).innerHTML=players[i];
	}

}
function NewDeal() {
	document.getElementById("buttonbar").innerHTML="&nbsp;"
	for (i=0; i<52; i++)
		deck[i] = i;
	pot = 0;
	CardsDealt = 2;
	AllIn = false;
	PlayersFolded = 0;
	CurrentStake  = 1;
	RoundOpened   = false;

	while (OutOfMoney[dealer]) {
		dealer++;
		dealer%=players.length;
	}
	for (i=0; i<NumberOfPlayers; i++) {
		if (OutOfMoney[i]) {
			fold[i] = true;
			PlayersFolded++;
			document.getElementById("chips"+i).innerHTML="&nbsp;"
			document.getElementById("bets"+i).innerHTML="&nbsp;"
			document.getElementById("best"+i).innerHTML="&nbsp;"
			document.getElementById("hand"+i).innerHTML="<span class='placeholder'><img src='images/hole.gif'>&nbsp;</span>";
			continue;
		}
		else
			fold[i] = false;

		chips[i]--;
		bets[i]=1;
		pot += bets[i];
		raises[i] = 0;
		if (chips[i]==0)
			AllIn = true;
		document.getElementById("chips"+i).innerHTML=chips[i];
		document.getElementById("bets"+i).innerHTML=bets[i];
		document.getElementById("best"+i).innerHTML="&nbsp;";
		document.getElementById("comment").innerHTML="&nbsp;";
		suit[i] = new Array();
		rank[i] = new Array();
		SuitArranged[i] = new Array();
		RankArranged[i] = new Array();
		for (j=0; j<5; j++) {
			nextCard = Math.floor(Math.random()*deck.length);
			suit[i][j] = Math.floor(deck[nextCard]/13);
			rank[i][j] = deck[nextCard]%13;

			SuitArranged[i][j] = Math.floor(deck[nextCard]/13);
			RankArranged[i][j] = deck[nextCard]%13;
			TakeCard(nextCard);
		}
	}
	document.getElementById("pot").innerHTML=pot;
	FirstToSpeak = (dealer+1)%NumberOfPlayers;
	while (fold[FirstToSpeak]) {
		FirstToSpeak++
		FirstToSpeak %= NumberOfPlayers;
	}
	document.getElementById("comment").innerHTML=players[dealer]+" is dealer, so "+players[FirstToSpeak]+" speaks first.";
	dealer++;
	dealer%=players.length;
	DisplayCards(2);
	BetsMade = 0;
	if (!AllIn)
		setTimeout("BettingRound()",2*speed);
	else
		setTimeout("NoBettingRound()",2*speed);
}
function BettingRound() {
	CurrentBetter = (dealer+BetsMade)%NumberOfPlayers;
	if (PlayersFolded==NumberOfPlayers-1 && !fold[CurrentBetter]) {
		NoShowdown();
	}
	else if (BetsMade>=NumberOfPlayers && StakesEqualized() && PlayersFolded<NumberOfPlayers-1) {
		CardsDealt++;
		BetsMade=0;
		if (AllIn) {
			setTimeout("NoBettingRound()",2*speed);
		}
		else if (CardsDealt<=5) {
			setTimeout("NextCard()",2*speed);
		} else
			setTimeout("Showdown()",2*speed);	
	}
	else if (fold[CurrentBetter]) {
		BetsMade++;
		BettingRound();
	}

	else if (CurrentBetter==YourPosition) {
		document.getElementById("comment").innerHTML="It is your turn now, "+YourName+".";
		if (!RoundOpened) {
			buttons = "<input type='button' value='"
			if (chips[YourPosition]==1) {
				buttons += "All-in";
			}
			else {
				buttons += "Bet";
			}
			buttons += "' onClick='Bet(0)'> <input type='button' value='Check' onClick='Bet(3)'> <input type='button' value='Fold' onClick='Bet(4)'>";
		}
		else {
			amount = CurrentStake - bets[YourPosition];
			difference = chips[YourPosition]-amount;
			if (difference<=0)
				buttons = "<input type='button' value='All-in' onClick='Bet(1)'> "
			else
				buttons = "<input type='button' value='Call' onClick='Bet(1)'> "
			if (difference>=1 && raises[YourPosition]<3 && !AllIn) 
				buttons += "<input type='button' value='Raise' onClick='Bet(2)'> "
			buttons += "<input type='button' value='Fold' onClick='Bet(4)'>";

		}
		document.getElementById("buttonbar").innerHTML=buttons;
	}

	else {
		BetsMade++;

		if (WantToFold()) {
			if (!RoundOpened)
				action = 3;
			else {
				fold[CurrentBetter] = true;
				PlayersFolded++;
				document.getElementById("hand"+CurrentBetter).innerHTML="<span class='placeholder'><img src='images/hole.gif'>&nbsp;</span>";
				action = 4;
			}
		}
		else {
			if (!RoundOpened) {
				if (Math.random()>aggression[i]/2) {
					RoundOpened = true;
					bets[CurrentBetter]++;
					pot++;
					chips[CurrentBetter]--;
					CurrentStake = bets[CurrentBetter];
					action = 0;
					if (chips[CurrentBetter]==0)
						AllIn = true;
				}
				else {
					action = 3;
				}
			}
			else {
				amount = CurrentStake - bets[CurrentBetter];
				difference = chips[CurrentBetter]-amount;
				if (difference<0) {
					TapOut();
					action = 5;
				}
				else if (difference==0) {
					AllIn = true;
					action = 5;
				}		
				else if (!AllIn && raises[CurrentBetter]<3 && Math.random()>aggression[i]) {
					amount++;
					action = 2;
					raises[CurrentBetter]++;
					if (chips[CurrentBetter]-amount==0)
						AllIn = true;
				}
				else
					action = 1;
				bets[CurrentBetter]+=amount;
				pot+=amount;
				chips[CurrentBetter]-=amount;
				CurrentStake = bets[CurrentBetter];

			}
		}
		Contribute(action);
		setTimeout("BettingRound()",speed);
	}		
}
function TapOut() {
	amount += difference;
	CurrentStake += difference;
	for (i=0; i<NumberOfPlayers; i++) {
		diff2 = bets[i]-CurrentStake;
		if (!OutOfMoney[i] && diff2>0) {
			bets[i]-=diff2;
				chips[i]+=diff2;
			pot-=diff2;
			document.getElementById("chips"+i).innerHTML=chips[i];
			document.getElementById("bets"+i).innerHTML=bets[i];
			document.getElementById("pot").innerHTML=pot;
		}
	}
	AllIn = true;
}

function NoBettingRound() {
	document.getElementById("comment").innerHTML="Since some of the players are all-in, bettings are no more allowed.";
	setTimeout("Showdown()",3000);
}
function WantToFold() {
	// check pairs
	pairs = false;
	for (i=0; i<CardsDealt-1; i++) {
		for (j=i+1; j<CardsDealt; j++) {
			if (rank[CurrentBetter][i]==rank[CurrentBetter][j]) {
				pairs = true;
				break;
			}
		}
	}
	if (pairs)
		return false;
	else if (Math.random()<tightness[CurrentBetter])
		return true;
	else
		return false;
}
function StakesEqualized() {
	equalized = true;
	for (i=0; i<NumberOfPlayers; i++) {
		if (!fold[i] && bets[i]!=CurrentStake) {
			equalized = false;
			break;
		}
	}
	return equalized;

}
function NextCard() {
	RoundOpened = false;
	document.getElementById("comment").innerHTML="&nbsp;"
	for (i=0; i<NumberOfPlayers; i++) {
		document.getElementById("best"+i).innerHTML="&nbsp;";
		raises[i]=0;
	}
	DisplayCards(CardsDealt);
	setTimeout("BettingRound()",speed);
}
function Contribute(Choice) {
	document.getElementById("chips"+CurrentBetter).innerHTML=chips[CurrentBetter];
	document.getElementById("bets"+CurrentBetter).innerHTML=bets[CurrentBetter];
	document.getElementById("pot").innerHTML=pot;
	document.getElementById("best"+CurrentBetter).innerHTML=options[Choice];
	if (Choice!=5)
		document.getElementById("comment").innerHTML=players[CurrentBetter]+" "+options[Choice].toLowerCase()+"s.";
	else 
		document.getElementById("comment").innerHTML=players[CurrentBetter]+" puts in all his money.";
}
function Bet(YourChoice) {
	BetsMade++;
	switch(YourChoice) {
		case 0:
			RoundOpened = true;
			bets[YourPosition]++;
			pot++;
			chips[YourPosition]--;
			CurrentStake = bets[YourPosition];
			if (chips[YourPosition]==0) {
				AllIn = true;
				YourChoice = 5;
			}
			break;
		case 1:
			if (difference<0)
				TapOut();
			else if (difference==0) {
				AllIn = true;
				action = 5;
			} 
			bets[YourPosition]+=amount;
			pot+=amount;
			chips[YourPosition]-=amount;
			CurrentStake = bets[YourPosition];
			break;
		case 2:
			amount++;
			raises[CurrentBetter]++;
			if (chips[CurrentBetter]-amount==0)
				AllIn = true;

			bets[YourPosition]+=amount;
			pot+=amount;
			chips[YourPosition]-=amount;
			CurrentStake = bets[YourPosition];
			break;
		case 3:
			break;
		case 4:
			fold[YourPosition] = true;
			PlayersFolded++;
			document.getElementById("hand"+YourPosition).innerHTML="<span class='placeholder'><img src='images/hole.gif'>&nbsp;</span>";
			break;
	}

	Contribute(YourChoice);

	document.getElementById("buttonbar").innerHTML="&nbsp;"
	setTimeout("BettingRound()",speed);
}
function DisplayCards(howMany) {
	for (i=0; i<NumberOfPlayers; i++) {
		if (!fold[i]) {
			if (i==YourPosition)
				hand = "<span class='card' style='color:"+SuitColors[suit[i][0]]+"'><img src='images/suit"+(suit[i][0]+1)+".gif'>"+words[rank[i][0]]+"</span>";
			else
				hand = "<span class='holecard'><img src='images/hole.gif'>&nbsp;</span>";
			for (j=1; j<howMany; j++) {
				hand += "<span class='card' style='color:"+SuitColors[suit[i][j]]+"'><img src='images/suit"+(suit[i][j]+1)+".gif'>"+words[rank[i][j]]+"</span>";
			}
			document.getElementById("hand"+i).innerHTML=hand;
		}

	}
}
function DisplayAll() {
	for (i=0; i<NumberOfPlayers; i++) {
		if (fold[i])
			continue;
		hand = "";
		for (j=0; j<5; j++) {
			hand += "<span class='card' style='color:"+SuitColors[suit[i][j]]+"'><img src='images/suit"+(suit[i][j]+1)+".gif'>"+words[rank[i][j]]+"</span>";
		}
		document.getElementById("hand"+i).innerHTML=hand;
	}
}
function TakeCard(card) {
	newDeck = new Array();
	for (k=0; k<card; k++)
		newDeck[k] = deck[k];
	for (k=card+1; k<deck.length; k++)
		newDeck[k-1] = deck[k];
	deck = newDeck;
}

function DrawTable() {
	for (i=0; i<NumberOfPlayers; i++) {
		document.write("<tr><td id='name"+i+"'>&nbsp;</td><td id='chips"+i+"' style='text-align:center;'>&nbsp;</td><td id='bets"+i+"' style='text-align:center;'>&nbsp;</td><td id='hand"+i+"'><span class='placeholder'><img src='images/hole.gif'>&nbsp;</span>");
		document.write("</td><td id='best"+i+"' style='text-align:right;'>&nbsp;</td></tr>");
	}
}
function Showdown() {
	DisplayAll();
	for (i=0; i<NumberOfPlayers; i++) {
		if (fold[i])
			continue;
		// sort cards from high to low
		for (j=0; j<4; j++) {
			for (k=j+1; k<5; k++) {
				if (RankArranged[i][k]>RankArranged[i][j]) {
					apu1 = RankArranged[i][j];
					apu2 = SuitArranged[i][j];
					RankArranged[i][j] = RankArranged[i][k];
					RankArranged[i][k] = apu1;
					SuitArranged[i][j] = SuitArranged[i][k];
					SuitArranged[i][k] = apu2;
				}
			}
		}
		straight = false;
		flush = false;
		HighCards[i] = new Array();

		if (SuitArranged[i][0]==SuitArranged[i][1] && SuitArranged[i][0]==SuitArranged[i][2] && SuitArranged[i][0]==SuitArranged[i][3] && SuitArranged[i][0]==SuitArranged[i][4])
			flush = true;
		if ((RankArranged[i][0]==RankArranged[i][1]+1 || (RankArranged[i][0]==12 && RankArranged[i][1]==3)) && RankArranged[i][1]==RankArranged[i][2]+1 && RankArranged[i][2]==RankArranged[i][3]+1 && RankArranged[i][3]==RankArranged[i][4]+1)
			straight = true;

		if (straight&&flush) {
			best[i] = 0;
			if (RankArranged[i][0]==12 && RankArranged[i][1]==3)
				HighCards[i][0] = 3;
			else
				HighCards[i][0] = RankArranged[i][0];
		}
		else if (flush) {
			best[i] = 3;
			for (j=0; j<4; j++)
				HighCards[i][j] = RankArranged[i][j];		
		}
		else if (straight) {
			best[i] = 4;
			if (RankArranged[i][0]==12 && RankArranged[i][1]==3)
				HighCards[i][0] = 3;
			else
				HighCards[i][0] = RankArranged[i][0];
		}		
		// four of a kind
		else if (RankArranged[i][0]==RankArranged[i][3] || RankArranged[i][1]==RankArranged[i][4]) {
			best[i] = 1;
			HighCards[i][0] = RankArranged[i][2];
		}
		// full house, triple first
		else if (RankArranged[i][0]==RankArranged[i][2] && RankArranged[i][3]==RankArranged[i][4]) {
			best[i] = 2;
			HighCards[i][0] = RankArranged[i][0];
			HighCards[i][1] = RankArranged[i][3];
		}
		// full house, pair first
		else if (RankArranged[i][0]==RankArranged[i][1] && RankArranged[i][2]==RankArranged[i][4]) {
			best[i] = 2;
			HighCards[i][0] = RankArranged[i][2];
			HighCards[i][1] = RankArranged[i][0];

		}
		// three of a kind
		else if (RankArranged[i][0]==RankArranged[i][2]) {
			best[i] = 5;
			HighCards[i][0] = RankArranged[i][0];
			HighCards[i][1] = RankArranged[i][3];
			HighCards[i][2] = RankArranged[i][4];
		}
		// three of a kind
		else if (RankArranged[i][1]==RankArranged[i][3]) {
			best[i] = 5;
			HighCards[i][0] = RankArranged[i][1];
			HighCards[i][1] = RankArranged[i][0];
			HighCards[i][2] = RankArranged[i][4];
		}
		// three of a kind
		else if (RankArranged[i][2]==RankArranged[i][4]) {
			best[i] = 5;
			HighCards[i][0] = RankArranged[i][2];
			HighCards[i][1] = RankArranged[i][0];
			HighCards[i][2] = RankArranged[i][1];
		}
		// two pairs or pair or nothing
		else {
			pairs=0;
			PairIndex = new Array();
			for (j=0; j<4; j++) {
				if (RankArranged[i][j]==RankArranged[i][j+1])
					PairIndex[pairs++] = j;
			
			}
			if (pairs==2) {
				best[i] = 6;
				HighCards[i][0] = RankArranged[i][PairIndex[0]];
				HighCards[i][1] = RankArranged[i][PairIndex[1]];
				if (PairIndex[0] = 1)
					HighCards[i][3] = RankArranged[i][0];
				else if (PairIndex[1]==2)
					HighCards[i][3] = RankArranged[i][4];
				else
					HighCards[i][3] = RankArranged[i][2];
			}
			else if (pairs==1) {
				best[i] = 7;
				HighCards[i][0] = RankArranged[i][PairIndex[0]];
				counter = 1;
				for (j=0; j<PairIndex[0]; j++)
					HighCards[i][counter++] = RankArranged[i][j];
				for (j=PairIndex[0]+2; j<5; j++)
					HighCards[i][counter++] = RankArranged[i][j];
			}
			else
				best[i] = 8;
		}
		document.getElementById("best"+i).innerHTML=pokerhands[best[i]];
	}
	winner = 0;
	while (fold[winner] && winner<NumberOfPlayers)
		winner++;

	for (i=1; i<NumberOfPlayers; i++) {
		if (fold[i])
			continue;
		if (best[i]<best[winner])
			winner = i;
		else if (best[i]==best[winner] && best[i]!=8) {
			for (j=0; j<HighCards[i].length; j++) {
				if (HighCards[i][j]>HighCards[winner][j]) {
					winner = i;
					break;
				}
				else if (HighCards[i][j]<HighCards[winner][j]) {
					break;
				}
			}

		}
		else if (best[i]==best[winner]) {
			for (j=0; j<5; j++) {
				if (RankArranged[i][j]>RankArranged[winner][j]) {
					winner = i;
					break;
				}
				else if (RankArranged[i][j]<RankArranged[winner][j]) {
					break;
				}
			}

		}
	}
	if (best[winner]!=8)
		winningHand = pokerhands[best[winner]].toLowerCase();
	else
		winningHand = words[RankArranged[winner][0]] + " high";
	comment = players[winner]+" wins with his "+winningHand+". ";

	CheckLosers();
}
function CheckLosers() {
	chips[winner] += pot;
	document.getElementById("chips"+winner).innerHTML=chips[winner];
	out = 0;
	LostPlayers = new Array();
	counter = 0;
	for (i=0; i<NumberOfPlayers; i++) {
		if (chips[i]<=0 && !OutOfMoney[i]) {
			LostPlayers[counter++] = i;
				
			OutOfMoney[i]=true;
		}
		if (OutOfMoney[i])
			out++;
	}


	if (LostPlayers.length>1) {
		for (i=0; i<LostPlayers.length; i++) {
			comment += players[LostPlayers[i]];
			if (i<LostPlayers.length-2)
				comment += ", ";
			else if (i==LostPlayers.length-2)
				comment += " and ";
		}
		comment += " have gone out of money. ";
	}
	else if (LostPlayers.length==1) 
		comment += players[LostPlayers[0]] + " has gone out of money. ";
	if (NumberOfPlayers-out>1) {
		if (OutOfMoney[YourPosition]) {
			comment += "Your game is over, better luck next time. ";
			document.getElementById("buttonbar").innerHTML="<input type='button' value='New game' onClick='NewGame()'>";
	
		}
		else
			document.getElementById("buttonbar").innerHTML="<input type='button' value='Next deal' onClick='NewDeal()'>";
	}
	else {
		comment += players[winner] + " wins the game. ";
		if (winner==YourPosition)
			comment += "Congratulations!";
		document.getElementById("buttonbar").innerHTML="<input type='button' value='New game' onClick='NewGame()'>";
	}
	document.getElementById("comment").innerHTML=comment;
}
function NoShowdown() {
	winner = CurrentBetter;
	comment = players[CurrentBetter]+" takes a pot of "+pot+" chips. ";
	CheckLosers();
}
function EnterName() {
	Initialize();
	YourName = window.prompt("Enter your name:","Your Name");
	if (YourName=="" || YourName=="Your Name" || YourName==null)
		YourName="Our Humble Poet";
	players[YourPosition] = YourName;
	document.getElementById("name"+YourPosition).innerHTML=YourName;
	document.getElementById("buttonbar").innerHTML="<input type='button' value='Next deal' onClick='NewDeal()'>";
}
function ChangeSpeed(newSpeed) {
	speed = SpeedOptions[newSpeed];
}
function NewGame() {
	Initialize();
	NewDeal();
}
