// Originally designed & written by: H. Kuijpers © 2001
// Contact me at: hkuijpers@xs4all.nl
// Feel free to redistribute, copy and change this code, but please make
// a reference to this code and the author.
// Please report any bugs, inconsistancies, comments or other helpful tips 
// to the mail address above

/// this module contains all functions concerning the rules
// of the klaverjas game.
// calculation of points/winners/values



function NextPlayer() {
  var Game = Match.Games[Match.GameIndex];	
	if (Match.PlayCount < 3)
	{
		Match.PlayCount++;
		Match.Status = 0; // allow next player to play
	}
	else {
		//wait 2 seconds to end the round and clear the table
		Match.Status = 3; // set to -in between- rounds
		winner = GetCurrentWinner(); // winner of the round		  		
		//s = Match.Table.getvalue(Match.Trumps.cards[Match.Trumps.index]);
		s = Match.Table.getvalue(Match.Trumps.cards[Match.Trumps.index]);
		b = Match.Table.getbonus(Match.Trumps.cards[Match.Trumps.index]);
			// set next player		
		if ((winner % 2) == 0 ) {
			Game.Score.points_us += s;			
			Game.Score.bonus_us += b;			
		} else {
			Game.Score.points_them += s;
			Game.Score.bonus_them += b;			
		}		
		window.setTimeout("NextRound()", (500 + 500 * Config.playspeed));		
	}
}


// returns the index of the winner
function GetCurrentWinner() {
		var curGame;
		var curRound;
		var curTrump;
		var winner;
		curGame = Match.Games[Match.GameIndex];	
		curRound = curGame.Rounds[curGame.RoundIndex];
		curRound.cards = Match.Table.cards;
		curTrump = Match.Trumps.cards[Match.Trumps.index];
		return curRound.getwinner(curTrump, curRound.PlayerStart);
}

// part of the flow of the match
// will set the match to the next round of the game
// calculate scores, calculate the winner,
// determine who is the start player
// turn the turncards.
function NextRound() {
	var curGame;
	var curRound;
	var startPlayer;
	var nextPlayer;
	var curTrump;
	//alert('next round');
	curGame = Match.Games[Match.GameIndex];	
	curRound = curGame.Rounds[curGame.RoundIndex];
	curTrump = Match.Trumps.cards[Match.Trumps.index];
	// copy cards on table to round
	curRound.cards = Match.Table.cards;
	
	ShowPoints(curGame.Score);		
	if (curGame.RoundIndex < 7) {
		//startPlayer = (curGame.RoundIndex) % 4 // should be of winner		
		// next player to start is winner of the round		
    ClearTable(Match.Table);
		nextPlayer = curRound.getwinner(curTrump, curRound.PlayerStart)
    //alert(nextPlayer);
		// calculate winner, determine who starts next round
		curGame.RoundIndex++;				
	} 
	else {
	  var s_r;
		if (Match.GameIndex < 16) {
			// end of game!			
		  //winner = curRound.getwinner(curTrump, curRound.PlayerStart);
		  winner = GetCurrentWinner(); // winner of the round		  
  		if ((winner % 2) == 0 ) {
  		  curGame.Score.points_us += 10; // won last round bonus
      } else {
        curGame.Score.points_them += 10; // won last round bonus
      }
      // winner is determined, now the table can be cleared
      ClearTable(Match.Table);
      // determine player that played, not necessarely started the round
      startPlayer = (Match.ColorPlayerIndex) % 4;			
    	// determine next player to start
    	nextPlayer = (curGame.Rounds[0].PlayerStart + 1) % 4;
      var s_us = curGame.Score.points_us  + curGame.Score.bonus_us;
      var s_them = curGame.Score.points_them + curGame.Score.bonus_them
		  
		  		  
		  if ((startPlayer % 2) == 0 ) { // we started
		    //alert('Wij zijn begonnen ' + s_us + ' - ' + s_them);
		    if (s_us > s_them ) { // we won		      
		      if (s_them == 0) { // bonus		        
		        s_us += 100; // 100 punten bonus
		        s_r = '<b>Wij hebben een <i>pit</i> gemaakt!!!</b>';
		      } else {
		          s_r = '<b>Wij hebben het gehaald!</b>';
		      }
		    } else { // we lost
		      s_us = 0;
		      s_them = 162 + curGame.Score.bonus_them + curGame.Score.bonus_us;
		      s_r = '<b>Ze hebben ons <i>nat</i> gespeeld!</b>';
		    }		     
		  } else { // they started		    
		    if (s_them > s_us) { // we lost -> nat
		      //alert('Zij zijn begonnen ' + s_us + ' - ' + s_them);
		      if (s_us == 0) { // bonus
		        s_them += 100; // 100 bonus punten
		        s_r = '<b>Ze hebben een <b>pit</b> gemaakt!!!</b>';
		      } else {
		          s_r = '<b>Ze hebben het gehaald!</b>';
		      }
		    } else { // they lost -> nat
		      s_us = 162 + curGame.Score.bonus_them + curGame.Score.bonus_us;
		      s_them = 0;		      
		      s_r = '<b>We hebben ze <i>nat</i> gespeeld!!</b>';
		    }		     
		  }
      
			// calculate, reset and show scores			
		  curGame.Score.total_us += s_us;		  
		  curGame.Score.total_them += s_them;		  
			//curGame.Score.bonus_us = 0;
			//curGame.Score.bonus_them = 0;			
			//curGame.Score.points_us = 0;
			//curGame.Score.points_them = 0;			
			ShowPoints(); // refresh last score			
			// should do a timer event here
			// set next player		
			ShowCallout(s_r, 0);
 			//comment.innerHTML = s_r;
			//alert(comment.innerText);
			Match.GameIndex++;			
			if (Match.GameIndex < 16) {
			  curGame = InitGame(Match);
  			//curGame = new Object();
  			//Match.Games[Match.GameIndex] = curGame;
  			//curGame.Rounds = new Array(8);
  			//curGame.RoundIndex = 0;  			  			
  		} 
		}
	}
	
	if (Match.GameIndex < 16) { // @@@ < 16
	  
  	curRound = new Object;
  	curGame.Rounds[curGame.RoundIndex] = curRound;
  	curGame.Rounds[curGame.RoundIndex].getwinner = getCardsWinner;
  	
  	curRound.PlayerStart = nextPlayer;
  	
  	Match.PlayCount = 0; // reset status
  	
  	//alert('end of round, click to continue');
  	//alert('round finished!' + Match.PlayCount);		
  	if (curGame.RoundIndex == 0) {
  	  Match.Timer = 0; //reset
  	  Match.Status = 8; // reset status, let players select a color, wait a bit before continuing
  	} else {
  	  Match.Status = 0; // reset status
  	}
  	
  	if (curGame.RoundIndex == 0) {
  	  TurnCard(Match.Trumps)
  	  Match.Deal();
  	}
  } else {	// end of match	  
    comment.innerHTML = 'Einde spel. ' + GetTotalScore(0) + ' punten tegen ' + GetTotalScore(1) + '. Druk op <b>F5</b> voor nog een spel!';
		// calculate winner here
		s_r = '';
		if (GetTotalScore(0) > GetTotalScore(1)) {
		  s_r += '<b>Wij hebben gewonnen!!!</b>'
		  //alert('Wij hebben gewonnen!!! Nog een spel?');			
  	} else if (GetTotalScore(0) < GetTotalScore(1)) { // bugfix 31/5/2004
  	  s_r += '<b>Helaas, we hebben verloren.</b>';
	    //alert('Wij hebben verloren, einde spel.');			
		} else {
		  s_r += '<b>Gelijkspel... Nog maar een potje? Druk op F5!</b>';
			//alert('Gelijkspel!');			
	  }
	  SubmitPoints(GetTotalScore(0), GetTotalScore(1));
	  ShowCallout(s_r, 0);
	  DebugPrint("Match.Status = 10 - submit score");
	  Match.Status = 3; // stop game.
	}
}

// given a trump color and the played color
// function will return the index of the highest card
function getCardsWinner(Trump, StartIndex)
{
  return CardsWinner(this.cards, Trump, StartIndex);
}

function CardsWinner(cards, Trump, StartIndex)
{
	var i;
	var w = StartIndex;
	var card, first;	
	for (i = 0; i< cards.length; i++)
	{
		first = cards[w]; // set color to first card played
		card = cards[i];		
		//alert(card.name + '-' + card.getcardindex(Trump, first) + ' > ' + first.name + '-' + first.getcardindex(Trump, first));
		if (typeof card != 'undefined') {
			if (card.getcardindex(Trump, first) > first.getcardindex(Trump, first))
			{
				w = i; // set to new winner
			}
		}
	}
	return w;
}

// will calculate the score of an 
// array of visible cards
function getCardsValue(Trump)
{
  return CardsValue(this.cards, Trump);
}

function CardsValue(cards, Trump)
{
	var i, v = 0;
	
	for (i=0; i < cards.length; i++) {	  	
	  if (typeof cards[i] != 'undefined') {						
			v = v + cards[i].getvalue(Trump);
		}
	}
	return v;
}

// calculate bonus for cards on table
function getCardsBonus(Trump)
{
   return CardsBonus(this.cards, Trump);
}

function CardsBonus(cards, Trump)
{
  var Bonus = 0;
  var i;
  for (i = 0; i < 4; i++) {
    // check on 4 cards on row
  	if (HasCard(cards, 7, i) && HasCard(cards, 8, i) && HasCard(cards, 9, i) && HasCard(cards, 10, i)) Bonus = 50;
    if (HasCard(cards, 8, i) && HasCard(cards, 9, i) && HasCard(cards, 10, i) && HasCard(cards, 11, i)) Bonus = 50;
    if (HasCard(cards, 9, i) && HasCard(cards, 10, i) && HasCard(cards, 11, i) && HasCard(cards, 12, i)) Bonus = 50;
    if (HasCard(cards, 10, i) && HasCard(cards, 11, i) && HasCard(cards, 12, i) && HasCard(cards, 13, i)) Bonus = 50;
    if (HasCard(cards, 11, i) && HasCard(cards, 12, i) && HasCard(cards, 13, i) && HasCard(cards, 14, i)) Bonus = 50;
  
    if (Bonus == 0) { // check on 3 cards on row
    	if (HasCard(cards, 7, i) && HasCard(cards, 8, i) && HasCard(cards, 9, i)) Bonus = 20;
    	if (HasCard(cards, 8, i) && HasCard(cards, 9, i) && HasCard(cards, 10, i)) Bonus = 20;
    	if (HasCard(cards, 9, i) && HasCard(cards, 10, i) && HasCard(cards, 11, i)) Bonus = 20;
    	if (HasCard(cards, 10, i) && HasCard(cards, 11, i) && HasCard(cards, 12, i)) Bonus = 20;
    	if (HasCard(cards, 11, i) && HasCard(cards, 12, i) && HasCard(cards, 13, i)) Bonus = 20;
    	if (HasCard(cards, 12, i) && HasCard(cards, 13, i) && HasCard(cards, 14, i)) Bonus = 20;
    }
  }

  for (i = 7; i < 15; i++) {
    // check on 4 of the same cards, of different colors
  	if (HasCard(cards, i, 0) && HasCard(cards, i, 1) && HasCard(cards, i, 2) && HasCard(cards, i, 3)) Bonus = 100;
  }
  // check on 'stuk' = queen + king of troef
  if (HasCard(cards, 12, Trump.colorindex) && HasCard(cards, 13, Trump.colorindex)) {
    Bonus += 20;
  }
  return Bonus;
}

// calculates the value of the card
// given a trump card/color.
function CardValue(Trump)
{
	switch(this.value) {
		case 9:
			if (this.color == Trump.color)				
				return 14; // nel
			else
				return 0;
			break;
		case 10:
			return 10;
			break;
		case 11:
			if (this.color == Trump.color)				
				return 20; // boer
			else
				return 2;
			break;
		case 12:
			return 3;
			break;
		case 13:
			return 4;
			break;
		case 14:
			return 11;
			break;
		default:
			return 0;
	}
}

// calculates the value of the card
// given a trump card/color.
function CardIndexValue(Trump, Color)
{
	//alert(this.name + ' - ' + Trump.name + ' - ' +  Color.name);
	switch(this.value) {
		case 7:
			if (this.color == Trump.color)				
				return 17
			else
				if (this.color == Color.color)				
					return 9;
				else 
					return 1;
			break;
		case 8:
			if (this.color == Trump.color)				
				return 18
			else
				if (this.color == Color.color)				
					return 10;
				else 
					return 2;
			break;
		case 9:
			if (this.color == Trump.color)				
				return 23;
			else
				if (this.color == Color.color)				
					return 11;
				else 
					return 3;
			break;
		case 10:
			if (this.color == Trump.color)				
				return 21
			else
				if (this.color == Color.color)				
					return 15;
				else 
					return 7;
			break;
		case 11: // jack
			if (this.color == Trump.color)				
				return 24; // boer
			else
				if (this.color == Color.color)				
					return 12;
				else 
					return 4;
			break;
		case 12: // queen
			if (this.color == Trump.color)				
				return 19
			else
				if (this.color == Color.color)				
					return 13;
				else 
					return 5;
			break;
		case 13: // king
			if (this.color == Trump.color)				
				return 20
			else
				if (this.color == Color.color)				
					return 14;
				else 
					return 6;
			break;
		case 14: // ace
			if (this.color == Trump.color)				
				return 22;
			else
				if (this.color == Color.color)				
					return 16;
				else 
					return 8;
			break;
		default:
			return 0; // can not happen really
	}
}

// verifies wether the playcard's color (cards[index]) is allowed to be played
// this depends on trump and first card's color, and gameplay syle (amsterdams/rotterdams)
// function returns 0 - allow to play card
//									1 - not allowed,illegal color
//									2 - not allowed, must play trump
//									3 - must play higher trump
//									4 - both 1 and 2
function VerifyPlayCard(index, player, table, trump, playerstart)
{
	var result =0; // allow initially	
	var hand = player.hand;
	var cards = hand.cards;
	var	first = table.cards[playerstart];
	var	playcard = cards[index];
	var i;
	
	// situation 1:
	if (typeof first == 'undefined') {
	  //alert('situation 1');  
		return 0; // always allowed to play first card
	}

  // situation 2: 
	var winner = GetCurrentWinner();	
	var winnercard = table.cards[winner];
	if (first.color == trump.color) {	 
	  //alert('situation 2');  
	  if (playcard.getcardindex(trump, first) > winnercard.getcardindex(trump, first)) {	    
	    return 0; // overtroeven   
	  }
	  
  	var CanPlayTrump = false;
  	for (i=0; ((i<cards.length) && (result == 0)); i++) {
  		if ((i != index) && (hand.pos[i].played == 'false')) {			
  			// check on higher trump
  			if (cards[i].getcardindex(trump, first) > winnercard.getcardindex(trump, first)) {
  				return 3;
  			}
  			
  			// check on trump card
  			if (cards[i].color == trump.color) {
  				CanPlayTrump = true;
  			}
  		}		
  	}
  	
  	if (playcard.color == first.color) {
  	  //alert('kleur bekennen, introeven');
  	   return 0; // kleur bekennen, introeven
  	}
  	if (CanPlayTrump == true) {
  	    //alert('must play trump');
  	   return 2; // must play trump
  	}
  	return 0;
  }
  
  //alert('situation 3');  
  // situation 3:	  
	if (playcard.color == first.color) {
		return 0; // kleur bekennen
	}
	
	var MateIsWinner = (winner == (player.index + 2) % 4);			
	var CanPlayColor = false;
	var CanPlayTrump = false;
	var CanPlayHigherTrump = false;
	for (i=0; ((i<cards.length) && (result == 0)); i++) {
		if ((i != index) && (hand.pos[i].played == 'false')) {
			// check on color
			if (cards[i].color == first.color) {
			  CanPlayColor = true;
			}
			
			// check on non trump card
			if (cards[i].color == trump.color) {
			  //alert('kan kleur bekennen');
				CanPlayTrump = true;
        if ((cards[i].getcardindex(trump, first) > winnercard.getcardindex(trump, first)) && (winnercard.color == trump.color)) {
          //alert('kan overtroeven');
          CanPlayHigherTrump = true;
        }
			}
		}
	}
  
  if (CanPlayColor) {
    //alert('moet kleur bekennen');
    return 1; // moet kleur bekennen
  }
  
	// check if mate is current winner of the round
	if (MateIsWinner == false)  {
	  //alert('slag ligt niet aan de maat');
  	if ((playcard.getcardindex(trump, first) > winnercard.getcardindex(trump, first)) && (winnercard.color == trump.color)) {  	  
  	  return 0;   // overtroeven
    }
    
    if (CanPlayHigherTrump) {
      return 3; // moet overtroeven
    }
    
  	if ((playcard.color == trump.color) && (winnercard.color != trump.color)) {  	  
  	  return 0;   // introeven
    }
    if (CanPlayTrump && (winnercard.color != trump.color)) {
      return 2; // moet introeven
    }
    
    return 0;
	} else {
	   //alert('slag ligt voor maat');
    if (Config.cur_playtrump == 1) { // rotterdams
      //alert('rotterdamse regels!');      
      if (CanPlayTrump && (playcard.color != trump.color)) {
        return 2; // moet introeven
      }      
      return 0;
    } else {
  	  return 0; // amsterdams, mag elke kaart opgooien
	  }
	}
	//alert('final' + result);
	return result;
}



