// 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


// improvements since first release:
// 31/5/2001 Preloading card images
// 1/6/2001  Added talking figures
// 2/6/2001  fixed incompatibility with ie5.0, now also works with ie5.0
// 6/6/2001  now bot will not waste any trumps anymore -> higher probability of getting last round
// 9/6/2001  added setup option, click settings (single or double click to throw card)
// 9/6/2001  redesigned gui, grouped together items in more windows style
// 9/6/2001  added scores overview form

// how to roll out:
// 1 - set IsDebug to false;
// 2 - set cheat to 'false'
// 3 - set debug to null
// 4 - activate nedstat counter
// 5 - set IsOnline to true;
// copy to beta

var IsDebug = false;
var cheat = 'false';
var IsOnline = true;

var dir = '../images'; // set global
var decks = new Array('Deck1.gif', 'Deck2.gif', 'Deck3.gif', 'Deck4.gif', 'Deck5.jpg');
var IsFirstTime;
// will trim trailing spaces from the string
// currently not yet implemented
function trim() {
   // not yet implemented
   return this;
}

// overload the array push function, since it is not supported for ie5.0
String.prototype.trim = trim;

// will order the cards of player hand
function OrderHand(a, b) {
	//alert(a.value + ',' + b.value)
	if  (a.index < b.index)
		return 1;
	else if (a.index > b.index)
		return -1;
	else return 0;
}

function Shuffle(cards)
{
	var i, t, r;
	for (i = 0; i<cards.length; i++) {
		r = Math.floor(Math.random() * cards.length);
		t = cards[i];
		cards[i] = cards[r];
		cards[r] = t;
	}
}

// window timer event handler
// will evualuate the Match every timeloop
// this the main engine that controls the game process
function onMatchControl() {	
	Match.Timer = Match.Timer + 100; // increase with 100ms
	var curGame
	var curRound
	var i;
	var ImgLoaded;
	if (Match.Status != 3) {
  	curGame = Match.Games[Match.GameIndex];
  	curRound = curGame.Rounds[curGame.RoundIndex];	
  	if (Match.PlayCount < 4) {
  		Match.PlayerIndex = ((curRound.PlayerStart + Match.PlayCount) % 4); // index of the current players' turn.
  	} else {
  		//round finished, calculate winners, init new round
  		Match.Status = 3; // in between rounds!		
  	}
    
		switch (Match.Status) {
			case 1: // processing stage
				break;
			case 2: // finished signaling, now throw card
      	var curGame;
      	var curRound;
      	var curTrump;
      	var first;
      	var p;
      	curGame = Match.Games[Match.GameIndex];
      	curRound = curGame.Rounds[curGame.RoundIndex];	
      	curTrump = Match.Trumps.cards[Match.Trumps.index];	
      	first = Match.Table.cards[curRound.PlayerStart];
      	p = Match.Players[Match.PlayerIndex];
      	if (typeof first != 'undefined') {
        	if (first.colorindex != p.hand.cards[p.hand.playcardindex].colorindex) {
        	  p.hand.colors[first.colorindex] = false; // player does not have color        	  
        	}
        }
				//score.innerHTML = 'punten: ' + Match.Table.getvalue(Match.Trumps.cards[Match.Trumps.index]);
				//Match.Players[Match.PlayerIndex].hand.colors[i]				
	      //ShowCallout(p.hand.cards[p.hand.playcardindex].name, p.index);
				Match.Players[Match.PlayerIndex].playcard();	
				break;
			case 3: // -in between rounds- state, do nothing here				
				break;
			case 4: // evaluate troef color				
        //Match.ColorPlayCount = 0; // will make to rounds of 4, 0..7, on 8 the current player must select a color
                
    		Match.ColorPlayerIndex = ((curRound.PlayerStart + Match.ColorPlayCount) % 4); // index of the current players' turn.    		
			  if (Config.cur_turnrounds == 0) {
 				  Match.Status = 6; // select color directly
 				  break;
  			}
    		if (Config.cur_turnrounds == 3) {
    		  Match.Status = 7; // start game automatically without selecting a color
    		  break;
    		} else {
				  Match.Players[Match.ColorPlayerIndex].onevaluatecolor();					
 				  break;
				}
				break;
			case 5: // select next player							
			  Match.Status = 3;
			  if (Config.cur_turnrounds == 1) {
  				Match.ColorPlayCount++;
  				if (Match.ColorPlayCount == 4) {
  				  Match.ColorPlayCount = 0; // reset to first
  				  Match.ColorPlayerIndex = ((curRound.PlayerStart + Match.ColorPlayCount) % 4); // index of the current players' turn.    		
  				  Match.Status = 6; // select color
  				} else {				  
  				  Match.Status = 4; // next player
  				}				
  			}
			  if (Config.cur_turnrounds == 2) {
  				Match.ColorPlayCount++;
  				if (Match.ColorPlayCount == 4) {
  				  TurnCard(Match.Trumps);
          }
  				if (Match.ColorPlayCount == 8) {
  				  Match.ColorPlayCount = 0; // reset to first
  				  Match.ColorPlayerIndex = ((curRound.PlayerStart + Match.ColorPlayCount) % 4); // index of the current players' turn.    		
  				  Match.Status = 6;
  				} else {				  
  				  Match.Status = 4;
  				}				
  			}
				break;
			case 6: // select troef color				
			  Match.ColorPlayerIndex = ((curRound.PlayerStart + Match.ColorPlayCount) % 4); // index of the current players' turn.    		
				Match.Players[Match.ColorPlayerIndex].onselectcolor();					
				break;
			case 7: // set scoreboard			  
			  Match.ColorPlayerIndex = ((curRound.PlayerStart + Match.ColorPlayCount) % 4); // index of the current players' turn.    		
			  Match.ColorPlayCount = 0; // reset for next game			  
			  Match.Status = 0; // let the games begin
			  ShowPoints(Match.Games[Match.GameIndex].Score);
			  break;
			case 8: // wait to go to next round
			  if ((Match.Timer % (1500 * Config.playspeed)) == 0) {
			    Match.Status = 4; // reset
			  }
			  break;
			case 9: // wait until all images are loaded
			  ImgLoaded = 0;
			  for (i=0; i < 4; i++) {
			    if (Match.Players[i].image.complete)
			      ImgLoaded++;
			  }
			  for (i=0; i < 52; i++) {
          if (Match.Deck[i].image.complete)
            ImgLoaded++;
        }        
        if (ImgLoaded < 52) {          
          comment.innerHTML = '<p style="color:black">Spel laden... ' + Math.ceil(ImgLoaded*100/56)+'%</p>';
        } else {
          // load the statistics counters,after the game images are loaded, this will
          // speed up loading the initial page
          if (IsOnline) {
            //imgStats1.src = 'http://www.PageAides.com/cgi-bin/StatsLog.cgi?user=hkuijpers';
            //imgStats2.src = 'http://www.stats4you.com/scripts/counter.asp?ID=hkuijpers&page=home&js=no';
            imgStats3.src = 'http://m1.webstats4u.com/n?id=AA883QDspbl3aj5Q3uU6KX0ef7cg';
          }
          comment.innerHTML = '';
          HideCallout();
          
          if (IsFirstTime) 
            Match.Status = 3; // images were loaded, wait for user to continue
          else
            Match.Status = 4; // images were loaded, start game          
        }
        break;
			case 10: // end of game, submit scores		
	  	  DebugPrint("SubmitPoints(" + GetTotalScore(0) + ", " + GetTotalScore(1) + ")");
			  SubmitPoints(GetTotalScore(0), GetTotalScore(1));
			  Match.Status = 3; // stop game.
				break;
			case 0:				
				Match.Players[Match.PlayerIndex].onturn();
		}		
	}		
}

function onPlayerSelectColor() {
    // make comment flash
    
		if ((Match.Timer % 3000) == 1000)	{
		  ShowCallout('<b>Kies een troefkleur</b>', 0, HideCallout);
			comment.innerHTML = '<a href="javascript:SelectedColor(this, 0);">Harten</a> | <a href="javascript:SelectedColor(this, 1);">Klaveren</a> | <a href="javascript:SelectedColor(this, 2);">Ruiten</a> | <a href="javascript:SelectedColor(this, 3);">Schoppen</a>';
		}	 
}

function onPlayerEvaluateColor() {
      // make comment flash
			if ((Match.Timer % 3000) == 1500)				
				ShowCallout('<b>Wil je <a href="javascript:PassColor(this);">passen</a> of<br><a href="javascript:PlayColor(this);">spelen</a>?</b>', 0);
}

// event handler for interactive player
// will need to select a card to play
// and will need to call PlayCard (dblclick on card)
function onPlayerTurn() {
      // make comment flash
			if ((Match.Timer % 30000) == 3000) {
			  if (Config.mouse_click == 0) {
				  ShowCallout('<b>klik op de te spelen kaart</b>', 0, HideCallout);				
				} else {
				  ShowCallout('<b>dubbelklik op de te spelen kaart</b>', 0, HideCallout);				
				}
			}
			if ((Match.Timer % 30000) == 10000)				
				HideCallout();
}

// help function for the beginner
// will ask the bot player for advice
// on which card to throw.
function AskAdvice() {      
  if ((Match.PlayerIndex == 0) && (Match.Status == 0)) { // check to see if it is my turn
    Match.Timer = 5000;    
    ShowCallout('<b>hmmm even denken...</b>', 0);				
    window.setTimeout("ReturnAdvice();", 10);
  }  
}

function ReturnAdvice() {  
  var player;
  player = Match.Players[0]; // set to human player
  playcardindex = player.selectcard(); //determine which card to play    
  ShowCallout('Ik zou de ' + player.hand.cards[playcardindex].name + ' opgooien', 0, HideCallout);				
  Match.Timer = 5000;    
  
}  

// event handler for computer player
// will select a card to play
// and call PlayCard
function onBotTurn() {

  HideCallout();
	comment.innerHTML = '';
	// throw up first card.
	var playcardindex;
	playcardindex = this.selectcard();
	if (Match.Status == 0)
	{
		Match.Status = 1;
		this.hand.playcardindex = playcardindex;
		this.hand.flashcard(this.hand.playcardindex);	
		window.setTimeout("Match.Status = 2", (100 + Config.playspeed*300));
    player_img1.src = Match.Players[0].image.src;
    player_img2.src = Match.Players[1].image.src;
    player_img3.src = Match.Players[2].image.src;
    player_img4.src = Match.Players[3].image.src;
	}
}

// used when the player's card is clicked
function onClick(index) {
  if ((Match.PlayerIndex == 0) && (Match.Status == 0)) {
    if (typeof this.hand.playcardindex != 'undefined') {
      this.hand.flashcard(this.hand.playcardindex, false);	
    }
    this.hand.playcardindex = index; // set to new index
    this.hand.flashcard(this.hand.playcardindex);	
  }

  if (Config.mouse_click == 0) { // throw card
  	if ((Match.PlayerIndex == 0) && (Match.Status == 0)) {
  	  this.hand.playcardindex = index;
  	  Match.Status = 2; // playcard	  
  		//this.playcard(index)
  	}
	}
}

// event handler of player.hands
function onDblClick(index) {		
  if (Config.mouse_click == 1) { // throw card  
  	if ((Match.PlayerIndex == 0) && (Match.Status == 0)) {
  	  this.hand.playcardindex = index;
  	  Match.Status = 2; // playcard	  
  		//this.playcard(index)
  	}
  }
}

function onBotSelectColor() {
  if ((Match.Timer % (1000 * Config.playspeed)) == 0)	{
    SetTrump(Match.Trumps, this.selectcolor());  
    ShowCallout('<b>Ik speel op ' + Match.Trumps.cards[Match.Trumps.index].colorname + '</b>', this.index);
    Match.Status = 7; // let the games begin
  }
}

function onBotEvaluateColor() {
  var s;
  if ((Match.Timer % (1000 * Config.playspeed)) == 0)	{
    s = this.playcolor(Match.Trumps.cards[Match.Trumps.index]);
    if (s > this.playcolor_treshold) {
      ShowCallout('<b>Ik speel op ' + Match.Trumps.cards[Match.Trumps.index].colorname + '</b>', this.index);
      Match.Status = 7; // let the games begin
    } else {
      //comment.innerHTML = '<p style="color:black">' + this.name + ' heeft gepast (' + s + ')</p>';
      ShowCallout('<b>Ik pas voor ' + Match.Trumps.cards[Match.Trumps.index].colorname + '</b>', this.index);
      Match.Status = 5; // pass
    }    
  }
}

// bot player. plays card 
function PlayBotCard() {
	
   var pos, cards, index;	
	index = this.hand.playcardindex	
	
	this.hand.hidecard(index);
	this.hand.pos[index].played = 'true';
	
	Match.Deck[this.hand.cards[index].index].played = 'true';		
	Match.Table.cards[this.index] = this.hand.cards[index];
	Match.Table.pos[this.index].see = 'true';
	Match.Table.showcard(this.index);	

	// delete played bot card	
	pos = this.hand.pos.slice(0, index);
	cards = this.hand.cards.slice(0, index);
	this.hand.pos = pos.concat(this.hand.pos.slice(index+1,8));
	this.hand.cards = cards.concat(this.hand.cards.slice(index+1,8));		
	
	//alert('count: ' + Match.PlayCount + 'status: ' + Match.Status);

	NextPlayer();	
	
}

function SelectedColor(player, color) {
  SetTrump(Match.Trumps, color);
  comment.innerHTML=''
  Match.Status = 7; // let the games begin
  void(0);
}

function PassColor(player) {
  Match.Status = 5;
  HideCallout();
  void(0);
}

function PlayColor(player) {
  Match.Status = 7; // let the games begin
  Match.Timer = 0; // reset
  HideCallout();
  void(0);
}

// player. plays card 
function PlayCard() {

	var curGame;
	var curRound;
	var curTrump;
	var first;
	var verify;	
	var index = this.hand.playcardindex;	
	curGame = Match.Games[Match.GameIndex];
	curRound = curGame.Rounds[curGame.RoundIndex];	
	curTrump = Match.Trumps.cards[Match.Trumps.index];
	first = Match.Table.cards[curRound.PlayerStart];
	
	verify = VerifyPlayCard(index, this, Match.Table, curTrump, curRound.PlayerStart);
	if (verify == 1) 
	{
	  //ShowCallout('<b>Dubbelklik de te spelen kaart</b>', 0, HideCallout);				
		//ShowCallout('Ik moet kleur te bekennen.\nDe gevraagde kleur is ' + first.colorname.toLowerCase() + '.',0, HideCallout);
		ShowCallout('<b>Ik moet kleur bekennen</b>',0, HideCallout);
		Match.Timer = 0
		Match.Status = 0; // reset, make player choose new card again
		return;
	}	
	if (verify == 2) 
	{
		ShowCallout('<b>Ik moet in troeven</b>', 0, HideCallout);
		Match.Timer = 0
		Match.Status = 0; // reset, make player choose new card again
		return;
	}	
	if (verify == 3) 
	{
		ShowCallout('<b>Ik moet over troeven</b>', 0, HideCallout);
		Match.Timer = 0
		Match.Status = 0; // reset, make player choose new card again
		return;
	}	
	if (verify == 4) 
	{
		ShowCallout('<b>Ik moet kleur bekennen of in troeven</b>', 0, HideCallout);
		Match.Timer = 0
		Match.Status = 0; // reset, make player choose new card again
		return;
	}	
	
	this.hand.hidecard(index);
	this.hand.pos[index].played = 'true';
	
	Match.Deck[this.hand.cards[index].index].played = 'true';	
	Match.Table.cards[this.index] = this.hand.cards[index];
	Match.Table.pos[this.index].see = 'true';
	Match.Table.showcard(this.index);	
	NextPlayer();
}

function Deal()
{
	var i, j;

  //if (!IsDebug)
  	this.Shuffle(this.Cards);
	
	for (j = 0; j<4; j++) {		
		this.Players[j].hand = new Object();
		this.Players[j].hand.cards = new Array(8);
		this.Players[j].hand.pos = new Array(8);			
		this.Players[j].hand.show = ShowCards;		
		this.Players[j].hand.showcard = ShowCardByIndex;
		this.Players[j].hand.hidecard = HideCardByIndex;
		this.Players[j].hand.flashcard = FlashCardByIndex;
		this.Players[j].hand.getvalues = getCardsValue;
		this.Players[j].hand.colors = new Array(4);
		for (i = 0; i<4; i++) {
		  this.Players[j].hand.colors[i] = true; // assume all players have cards in all colors
    }
		for (i = 0; i<8; i++) {
			this.Players[j].hand.pos[i] = new Object();
			this.Players[j].hand.pos[i].visible = 'false';
		}
	}
	
	// now deal the shuffled cards
	for (i = 0; i<8; i++) {			
	  var p1 = i;
	  var p2 = i +8;
	  var p3 = i + 16;
	  var p4 = i + 24;

    if (IsDebug) {
/*
  	  if (i==0) {p1=7; p2=27; p3=12; p4=27;}
  	  if (i==1) {p1=12; p2=31; p3=9; p4=27;}
  	  if (i==2) {p1=10; p2=5; p3=20; p4=27;}
  	  if (i==3) {p1=0; p2=3; p3=20; p4=27;}
  	  if (i==4) {p1=8; p2=29; p3=20; p4=27;}
  	  if (i==5) {p1=30; p2=29; p3=20; p4=27;}
  	  if (i==6) {p1=30; p2=29; p3=20; p4=27;}
  	  if (i==7) {p1=30; p2=29; p3=11; p4=27;}
*/
    }
    
		this.Players[0].hand.cards[i] = this.Cards[p1];
		this.Cards[i].played = 'false';
		this.Players[0].hand.pos[i].imgid = 'imghand0card' + i;
		this.Players[0].hand.pos[i].divid = 'divhand0card' + i;		
		InsertCardInPage(this.Players[0].hand.pos[i].divid, this.Players[0].hand.pos[i].imgid, i);
		div = document.getElementById(this.Players[0].hand.pos[i].divid);
		div.style.zIndex=8-i;
		this.Players[0].hand.pos[i].left = (65 - i * 5) + '%';
		this.Players[0].hand.pos[i].top = '75%';
		this.Players[0].hand.pos[i].see = 'true';
		this.Players[0].hand.pos[i].played = 'false';
	
		this.Players[1].hand.cards[i] = this.Cards[p2];
		this.Cards[i+8].played = 'false';
		this.Players[1].hand.pos[i].imgid = 'imghand1card' + i;
		this.Players[1].hand.pos[i].divid = 'divhand1card' + i;
		InsertCardInPage(this.Players[1].hand.pos[i].divid, this.Players[1].hand.pos[i].imgid);
		div = document.getElementById(this.Players[1].hand.pos[i].divid);
		div.style.zIndex=16-i;
	
		this.Players[1].hand.pos[i].left = (15 - i * 1) + '%';
		this.Players[1].hand.pos[i].top = '40%';
		this.Players[1].hand.pos[i].see = cheat;
		this.Players[1].hand.pos[i].played = 'false';

		this.Players[2].hand.cards[i] = this.Cards[p3];
		this.Cards[i+16].played = 'false';
		this.Players[2].hand.pos[i].imgid = 'imghand2card' + i;
		this.Players[2].hand.pos[i].divid = 'divhand2card' + i;
		InsertCardInPage(this.Players[2].hand.pos[i].divid, this.Players[2].hand.pos[i].imgid);
		div = document.getElementById(this.Players[2].hand.pos[i].divid);
		div.style.zIndex=24-i;

		this.Players[2].hand.pos[i].left = (50 - i * 1) + '%';
		this.Players[2].hand.pos[i].top = '12%';
		this.Players[2].hand.pos[i].see = cheat;
		this.Players[2].hand.pos[i].played = 'false';

		this.Players[3].hand.cards[i] = this.Cards[p4];		
		this.Cards[i+24].played = 'false';
		this.Players[3].hand.pos[i].imgid = 'imghand3card' + i;
		this.Players[3].hand.pos[i].divid = 'divhand3card' + i;
		InsertCardInPage(this.Players[3].hand.pos[i].divid, this.Players[3].hand.pos[i].imgid);
		div = document.getElementById(this.Players[3].hand.pos[i].divid);
		div.style.zIndex=32-i;
		this.Players[3].hand.pos[i].left = (85 - i * 1) + '%';
		this.Players[3].hand.pos[i].top = '40%';
		this.Players[3].hand.pos[i].see = cheat;
		this.Players[3].hand.pos[i].played = 'false';
	}	
	// show cards in the end	
	
	for (j=0; j<4; j++){	
		this.Players[j].hand.cards.sort(OrderHand);		
		this.Players[j].hand.show();
		
	}

	
	ShowPoints(Match.Games[Match.GameIndex].Score);	
}

function InsertCardInPage(divid, imgid, i)
{	
  
	var img, div;
	var onc; // clicks event handler
	var cur; // cursor type
	img = document.getElementById(imgid);
	div = document.getElementById(divid);
	if ((typeof i) == 'undefined') {
		onc = ''; 
		cur = '"';
	} else {
		//onc = ' onclick="alert(\'' + i + '\')"';
		onc = ' onclick="Match.Players[0].onclick(\'' + i + '\')" ondblclick="Match.Players[0].ondblclick(\'' + i + '\')"';		
		cur = ' cursor: hand;"';
	}
	if (div == null || img == null) {
			string = '<DIV class=card id="' + divid;
			string = string + '" style="DISPLAY: none;' + cur + onc;
			string = string + '> ';
			string = string + '<IMG id="' + imgid + '" src= Match.Deck.backside.src;">';
			string = string + '</DIV>';			
			document.body.innerHTML += string;
			
	} else {		
		div.style.display = 'none';		
	}			
}

// opens a new window to show the scores of the current match
function ShowScore() {
    var scores;
    var string;
    var i;
    var t0 = 0;  
    var t1 = 0;
    
  	string = '<br><center><div><table width=80% cellpadding=0 cellspacing=0>';
    string += '<tr><td colspan=2 class=caption>Puntenoverzicht</td><td class=caption align=right>&nbsp;</td></tr>'
    string += '<tr><td width=50 colspan=3 class=topic>&nbsp;</td></tr>'
  	string += '<tr><td width=50 class=topic align=center>Ronde</td><td id=team_us width=50 class=topic align=center>Wij</td><td id=team_them class=topic width=50 align=center>Zij</td></tr>'
  	//string += '<tr><td width=50 class=topic>Punten:</td><td id="points_us" width=50 class=topic align=right></td><td id="points_them" class=topic width=50 align=right></td></tr>'
  	//string += '<tr><td width=50 class=topic>Roem:</td><td id="bonus_us" class=topic width=50 align=right></td><td id="bonus_them" class=topic width=50 align=right></td></tr>'
  	string += '<tr><td bgcolor=black colspan=3 align=right></tr>'
    for (i=0; i < Match.GameIndex; i++) {
      t0 += Match.Games[i].Score.total_us;
      t1 += Match.Games[i].Score.total_them;
    	string += '<tr><td width=50 class=topic align=center>' + (i+1) + '</td><td id="total_us" class=topic width=50 align=center>'+t0+'</td><td id="total_them" class=topic width=50 align=center>'+t1+'</td></tr>'	  	
    }  
    for (i=Match.GameIndex; i < 16; i++) {
    	string += '<tr><td width=50 class=topic align=center>' + (i+1) + '</td><td id="total_us" class=topic width=50 align=center>-</td><td id="total_them" class=topic width=50 align=center>-</td></tr>'	  	
    }  
   	string += '<tr></tr>'	  	
   	string += '<tr><td colspan=3 align=right><a href="javascript:window.close();">Sluiten</a></td></tr>'	  	

  	string += '</table>';
  	string += '</div>';

    scores = window.open('', 'scores', 'alwaysRaised=yes; dependent=yes; height=350; width=230; location=no; menubar=no; resizable=yes; status=no; toolbar=no');
    scores.document.createStyleSheet('webfx.css')
  	scores.document.body.innerHTML=string;
  	scores.document.title = 'Puntenoverzicht'
  	scores.focus();
}

function InitPage(players)
{
	var string;
	if (typeof(comment) == 'undefined') {
  	string = '<div id="comment" class="comment" STYLE="width=50%; left:28%; top:68%;"></div>'
  	document.body.innerHTML += string;
  
  	string = '<div id="score" class="comment" STYLE="color:blue; left:3%; top:60%;"></div>'
  	document.body.innerHTML += string;

    // names should really be centered... hardcoded on name lengths for now
  	string =  '<div id="player_name1" class="" STYLE="left:49%; top:91%; position: absolute;"> <img id="player_img1" src="' + players[0].image.src + '" width=100 height=55 alt="' + players[0].name + '" ondblclick="AskAdvice();"></div>';
  	string += '<div id="player_name2" class="" STYLE="left:10%; top:29%; position: absolute;"><img id="player_img2" src="' + players[1].image.src + '" width=100 height=55 alt="' + players[1].name + '"></div>';
  	string += '<div id="player_name3" class="" STYLE="left:47%; top:25; position: absolute;"> <img id="player_img3" src="' + players[2].image.src + '" width=100 height=55 alt="' + players[2].name + '"></div>';
  	string += '<div id="player_name4" class="" STYLE="left:82%; top:29%; position: absolute;"><img id="player_img4" src="' + players[3].image.src + '" width=100 height=55 alt="' + players[3].name + '"></div>';  	
  	string += '<div id="scores" class="comment" STYLE="left:2%; top:65%;">';
  	string += '<table width=200 cellpadding=0 cellspacing=0>';
    string += '<tr><td colspan=2 class=caption>Punten</td><td class=caption align=right><img vspace=2 src="../images/q.gif" style="cursor:hand" onclick="ShowScore()" alt="puntenoverzicht">&nbsp;</td></tr>'
    string += '<tr><td id=round_begin colspan=3 class=topic>&nbsp;</td></tr>'
    string += '<tr><td id=round_play colspan=3 class=topic>&nbsp;</td></tr>'
    string += '<tr></tr>'
    string += '<tr><td width=50 class=topic>Ronde:</td><td id=round class=topic width=50 colspan=2>&nbsp;</td></tr>'
    string += '<tr><td width=50 colspan=3 class=topic>&nbsp;</td></tr>'
  	string += '<tr><td width=50 class=topic></td><td id=team_us width=50 class=topic align=right>Wij</td><td id=team_them class=topic width=50 align=right>Zij</td></tr>'
  	string += '<tr><td width=50 class=topic>Punten:</td><td id="points_us" width=50 class=topic align=right></td><td id="points_them" class=topic width=50 align=right></td></tr>'
  	string += '<tr><td width=50 class=topic>Roem:</td><td id="bonus_us" class=topic width=50 align=right></td><td id="bonus_them" class=topic width=50 align=right></td></tr>'
  	string += '<tr><td bgcolor=black colspan=3 align=right></tr>'
  	string += '<tr><td width=50 class=topic>Totaal:</td><td id="total_us" class=topic width=50 align=right>0</td><td id="total_them" class=topic width=50 align=right>0</td></tr>'	  	
  	string += '</table>';
  	string += '</div>';

    string += '<div id=callout_left class=callout style=\"display:none;z-index:1000;\">)<br>'
    string += ' <table valign=middle ><tr><td id=callout_text_left class="speech" align=middle>'
    string += ' </td></tr></table>'
    string += '</div>'

    string += '<div id=callout_right class=callout style="display:none;z-index:1000;">(<br>'
    string += ' <table valign=middle ><tr><td id=callout_text_right class="speech" align=middle>';    
    string += ' </td></tr></table>';
    string += '</div>';

  	document.body.innerHTML += string;
  	
  } 
}

function ShowCallout(text, playerindex, onMouseFunc) {
  HideCallout();
  if (typeof onMouseFunc == 'undefined') {
    onMouseFunc = null;
  }
  switch (playerindex) {
  case 0:
    callout_left.style.display = 'block';
    callout_left.style.left = '60%';
    callout_left.style.top = '75%'
    callout_left.onmouseover = onMouseFunc;
    callout_text_left.innerHTML = text;
    break;
  case 1:
    callout_left.style.display = 'block';
    callout_left.style.left = '17%';
    callout_left.style.top = '15%'
    callout_left.onmouseover = onMouseFunc;
    callout_text_left.innerHTML = text;
    break;
  case 2:
    callout_right.style.display = 'block';
    callout_right.style.left = '30%';
    callout_right.style.top = '-40'
    callout_right.onmouseover = onMouseFunc;
    callout_text_right.innerHTML = text;
    break;
  case 3:
    callout_right.style.display = 'block';
    callout_right.style.left = '65%';
    callout_right.style.top = '15%'
    callout_right.onmouseover = onMouseFunc;
    callout_text_right.innerHTML = text;
    break;
  }
}

function HideCallout() {
  callout_text_left.innerHTML = '';
  callout_text_right.innerHTML = '';
  callout_left.style.display = 'none';
  callout_right.style.display = 'none';
}

function GetTotalScore(team)
{
  var i;
  var t = 0;
  for (i=0; i <= Match.GameIndex && i < 16; i++) {
    if (team == 0) {
      t += Match.Games[i].Score.total_us
    } else {
      t += Match.Games[i].Score.total_them
    }      
  }  
  return t;
}

function CreateMatch()
{
   // to see the cards of the other players
   // set the 'cheat' variable in 'Deal()' to 'true'
	var Match = new Object

	Match.Name = 'Klaverjas 1.5';
	Match.Status = 9; // load cards
	Match.Cards = new Array(32) // these are the high play cards
	Match.TurnCards = new Array(22) // these are the low turn cards
	Match.Trumps = new Object(); // this will represent the current trump, based on the turncards
	Match.Deck = new Array(54)
	Match.Players = new Array(8);
	Match.Table = new Object();
	Match.Shuffle = Shuffle;
	Match.Deal = Deal;		
	Match.Games = new Array(16); // set to 16 games

	Match.GameIndex = 0; // set to first game
	Match.PlayCount = 0;
	Match.PlayerIndex = 0;
	Match.ColorPlayCount = 0; // will make to rounds of 4, 0..7, on 8 the current player must select a color
	Match.ColorPlayerIndex = 0; // index of the player that decided to play with this color
	Game = InitGame(Match)

	InitCards(Match.Deck, Match.Cards, Match.TurnCards);	
	InitPlayers(Match.Players);					
	InitPage(Match.Players);	
	Match.Timer = 0; // reset play time of Match
	setInterval(onMatchControl, 100); // evaluate Match control loop every 100ms
  
  if (IsFirstTime) {
      ShowWelcomeMessage();
  }
	return Match;
}

function InitGame(Match) {
	var Game
	
	Game = new Object();
	Match.Games[Match.GameIndex] = Game;

  // initialise scores here	
	Game.Score = new Object
	Game.Score.points_us = 0;
	Game.Score.points_them = 0;
	Game.Score.bonus_us = 0;
	Game.Score.bonus_them = 0;
	Game.Score.total_us = 0;
	Game.Score.total_them = 0;

	Game.Rounds = new Array(8);
	Game.RoundIndex = 0;
	InitRound(Game)

	 // defines start player
	 //should be random inially, or based on former round/game
	if (Config.cur_random_player) {
	  Game.Rounds[Game.RoundIndex].PlayerStart = Math.floor(Math.random() * 4);
	} else {	  
	  Game.Rounds[Game.RoundIndex].PlayerStart = 0;
	}
	Game.Rounds[Game.RoundIndex].getwinner = getCardsWinner;
	return Game;
}

function InitRound(Game) {
	var Round
	Round = new Object();
	Game.Rounds[Game.RoundIndex] = Round;			

}

function ClearTable(Table) {
	var i;
	Table.cards = new Array(4);
	for (i = 0; i<4; i++) {
      Table.hidecard(i, Match.Deck.backside);   
   }
}

function InitTable(Table) {
	var i;
	Table.pos = new Array(4);			
	Table.showcard = ShowCardByIndex;
	Table.hidecard = HideCardByIndex;
	Table.getvalue = getCardsValue;
	Table.getbonus = getCardsBonus;
	Table.getwinner = getCardsWinner;
	Table.name = 'Table';
	
	for (i = 0; i<4; i++) {
		Table.pos[i] = new Object();
		Table.pos[i].imgid = 'imgtablecard' + i;
		Table.pos[i].divid = 'divtablecard' + i;
		InsertCardInPage(Table.pos[i].divid, Table.pos[i].imgid);
		Table.pos[i].see = 'false';
	}
	Table.pos[0].left = '48%';
	Table.pos[0].top =  '50%';
	Table.pos[1].left = '35%';
	Table.pos[1].top =  '40%';
	Table.pos[2].left = '48%';
	Table.pos[2].top =  '30%';
	Table.pos[3].left = '61%';
	Table.pos[3].top =  '40%';
	
	ClearTable(Table);	
}

function InitPlayers(players) 
{

	var i;
	for (i=0; i<4; i++) {
		players[i] = new Object;
		players[i].index = i;
		players[i].hand = new Array(8);
		players[i].playcard = PlayBotCard;				
		players[i].selectcard = SelectPlayCard;
		players[i].selectcolor = SelectPlayColor;
		players[i].playcolor = EvaluatePlayColor;		
		players[i].playcolor_treshold = 45;
		players[i].image = new Image();
	}
	
	// player 0 is the interactive player
	// player will have some additional event handlers
	
	players[0].name = "Koekiemonster";
	players[0].image.src = dir + "/koekiemonster.gif";
	players[0].onclick = onClick;
	players[0].ondblclick = onDblClick;
	players[0].onselectcolor = onPlayerSelectColor; // is called when human player needs select the troef color
	players[0].onevaluatecolor = onPlayerEvaluateColor; // is called when human player needs to pass or play on current troef color
	players[0].onturn = onPlayerTurn; // will be called when the human player needs to throw a card
	players[0].playcard = PlayCard;				

	//players[0].name = "Arina";
	//players[0].onturn = onBotTurn;
	
	players[1].name = "Ernie";
	players[1].image.src = dir + "/ernie.gif";
	players[1].onselectcolor = onBotSelectColor; // is called when bot player needs select the troef color
	players[1].onevaluatecolor = onBotEvaluateColor; // is called when bot player needs to pass or play on current troef color
	players[1].onturn = onBotTurn; // will be called when the bot player needs to throw a card
	players[1].playcolor_treshold = 28; // dearing character
	players[2].name = "Grover";
	players[2].image.src = dir + "/grover.gif";
	players[2].onselectcolor = onBotSelectColor; // is called when bot player needs select the troef color
	players[2].onevaluatecolor = onBotEvaluateColor; // is called when bot player needs to pass or play on current troef color
	players[2].onturn = onBotTurn;
	players[2].playcolor_treshold = 30; // medium dearing character
	players[3].name = "Bert";
	players[3].image.src = dir + "/bert.gif";
	players[3].onselectcolor = onBotSelectColor; // is called when bot player needs select the troef color
	players[3].onevaluatecolor = onBotEvaluateColor; // is called when bot player needs to pass or play on current troef color
	players[3].onturn = onBotTurn;
	players[3].playcolor_treshold = 32; // not so dearing character
}


function ShowCards()
{
	var i;
	for (i=0; i<8; i++)
		this.showcard(i);
}

// function of hand
function ShowCardByIndex(i)
{
		var pos, card;
		pos = this.pos[i];
		card = this.cards[i];		
		ShowCard(pos, card);
}

function ShowCard(pos, card)
{
		var img, div;
		img = document.getElementById(pos.imgid);
		div = document.getElementById(pos.divid);		
		if (pos.see != 'false') {
         img.src = card.image.src;
			img.alt = card.name;
		}
		else {
			img.src = Match.Deck.backside.src;
		}
		div.style.left = pos.left;
		div.style.top = pos.top;		
		div.style.display = 'block';	
		pos.visible= 'true';
		//alert(div.style.display + ',' +	div.style.left + ',' + div.style.top + ',' + this.image.src);
}

// will display the scores
function ShowPoints(Score)  
{
  var curGame = Match.Games[Match.GameIndex];
 	var curRound = curGame.Rounds[0];	//get first player to start the game
  Score = curGame.Score;
  
  playing = (Match.ColorPlayerIndex) % 4;	// player that selected the playcolor
  started = curRound.PlayerStart; // player to begin the round
  	// determine next player to start
  if ((playing % 2)== 0 ) { // we started
    team_us.innerHTML = '<b>Wij</b>';
    team_them.innerHTML = 'Zij';
  } else {
    team_us.innerHTML = 'Wij';
    team_them.innerHTML = '<b>Zij</b>';
  }
	points_us.innerHTML = Score.points_us;
	points_them.innerHTML = Score.points_them;
	if (Score.bonus_us > 0 || Score.bonus_them > 0) {
	  bonus_us.innerHTML = Score.bonus_us;
		bonus_them.innerHTML = Score.bonus_them;
	} else {
	  bonus_us.innerHTML = '';
		bonus_them.innerHTML = '';
	}
	total_us.innerHTML = GetTotalScore(0);
	total_them.innerHTML = GetTotalScore(1);

 	round.innerHTML = Match.GameIndex + 1;
 	if (Match.Status <= 3) {
    round_begin.innerHTML = Match.Players[started].name + ' is begonnen'
    round_play.innerHTML = Match.Players[playing].name + ' speelt'
  } else {
    round_begin.innerHTML = Match.Players[started].name + ' moet beginnen'
    round_play.innerHTML = '&nbsp;'
  }

}

// function of hand
function HideCardByIndex(i, turnback)
{
		var pos;
		pos = this.pos[i];
		HideCard(pos, turnback);
}

// function of hand
function HideCard(pos, turnback)
{
	var div
   var img
   img = document.getElementById(pos.imgid);
	div = document.getElementById(pos.divid);
	div.style.display = 'none';
	div.style.backgroundColor = 'white'	;
	pos.visible= 'false';
   if (typeof(turnback) != 'undefined') {
	   img.src = turnback.src
   }
}

// function of hand
function FlashCardByIndex(i, flash)
{
		var pos;
		pos = this.pos[i];
		FlashCard(pos, flash);
}

// function of hand
function FlashCard(pos, flash)
{
	var div;
	var i;
	div = document.getElementById(pos.divid);				
	if (flash == false) {
	  div.style.backgroundColor = 'white';
	} else {
	  div.style.backgroundColor = 'red';
	}
}

function TurnCard(Trumps) {	
  var c;
  do {
    c = Trumps.cards[Trumps.index].colorindex;
  	if (Trumps.index < 19) {		
  		Trumps.index = Trumps.index + 1;		
  	}
  	else {
  		Trumps.index = 0;
  		Shuffle(Trumps.cards);		
  	}
  } while (c == Trumps.cards[Trumps.index].colorindex);
	ShowTurnCards(Trumps)	
}

function SetTrump(Trumps, ColorIndex) {	
  while (Trumps.cards[Trumps.index].colorindex != ColorIndex) {
  	if (Trumps.index < 19) {		
  		Trumps.index = Trumps.index + 1;		
  	}
  	else {
  		Trumps.index = 0;
  		Shuffle(Trumps.cards);		
  	}
  }
	ShowTurnCards(Trumps)	
}

function InitTrumps(Match) {
	var T, N, skip;
	var i;
	T = Match.Trumps;
	T.cards = new Array(20);
	N = new Array(19);
	T.pos = new Array(20);			
	T.showcard = ShowCardByIndex;
	T.hidecard = HideCardByIndex;

	skip =0;
	for (i = 0; i<19; i++) {		
		if (i == 5)  // skip the 2 spades, will be added to the beginning later
			skip = 1;
		N[i] = Match.TurnCards[i + skip];		
	}	
	Shuffle(N);
	
	T.index = 0; // set to first card (= 2 spades)
	T.cards[0] = Match.TurnCards[5];
	for (i = 0; i<19; i++) {		
		T.cards[i+1] = N[i];		
	}	
	ShowTurnCards(T)
}

function ShowTurnCards(Trumps) {
	var T = Trumps;
	var i;
	for (i = 0; i<=Trumps.index; i++) {		
		T.pos[i] = new Object();
		T.pos[i].imgid = 'imgturncard' + i;
		T.pos[i].divid = 'divturncard' + i;
		InsertCardInPage(T.pos[i].divid, T.pos[i].imgid);
		div = document.getElementById(T.pos[i].divid);
		div.style.zIndex=40-i;

		T.pos[i].left = (79	+ (i * .05)) + '%';
		T.pos[i].top =  (9 + (i * .02)) + '%';
		T.pos[i].see = 'false';				
		//T.showcard(i);
		ShowCard(T.pos[i], T.cards[i]);

		//T.pos[i].left = (87 - (i * 2.05)) + '%';
		//T.pos[i].top =  (3 + (i * .02)) + '%';
	}	
	for (i = Trumps.index+1; i<20; i++) {		
		T.pos[i] = new Object();
		T.pos[i].imgid = 'imgturncard' + i;
		T.pos[i].divid = 'divturncard' + i;
		InsertCardInPage(T.pos[i].divid, T.pos[i].imgid);
		T.pos[i].left = (67 + (i * .05)) + '%';
		T.pos[i].top =  (9 + (i * .02)) + '%';
		T.pos[i].see = 'false';				
		T.showcard(i);
	}
	T.pos[0].see = 'true';				
	ShowCard(T.pos[0], T.cards[T.index]);
}

// returns the card index with the given value and color
// return -1 if the card is not in the cards array
function GetCard(cards, value, color) 
{   
    // colorindex 
    //  0 - hearts
    //  1 - clubs
    //  2 - diamonds
    //  3 - spades
  for (i = 0; i<cards.length; i++) {
    if (cards[i].value == value && cards[i].colorindex == color) {
      return i;
    }
  }
  return -1; // not found
}

// returns true if the card is in the array, false otherwise
function HasCard(cards, value, color) {
  return GetCard(cards, value, color) >= 0;
}


function InitCards(cards, high, low) 
{		
      
		var i 
		cards.backside = new Image();
		cards.backside.src = dir + '/' + decks[Config.carddeck];
		for (i = 0; i<52; i++) {		
			cards[i] = new Object;
			cards[i].hidden = false;
			cards[i].display = false;
			cards[i].index = i;
			cards[i].id = 'card' + i;
			cards[i].played = 'false';
			cards[i].getvalue = CardValue;
			cards[i].getcardindex = CardIndexValue
			cards[i].image = new Image();
		}			

		for (i = 0; i<13; i++) {
			// hearts
			cards[i].value = i+2;
			cards[i].colorindex = 0;
			cards[i].color = "hearts";
			cards[i].colorname = "Harten";
			cards[i].name = "Harten " + (i+2);
			cards[i].image.src = dir + '/Harten' + (i+2) +'.gif';
			// clubs
			cards[i + 13].value = i+2;
			cards[i + 13].colorindex = 1;
			cards[i + 13].color = "clubs"
			cards[i + 13].colorname = "Klaveren";
			cards[i + 13].name = "Klaveren " + (i+2);
			cards[i + 13].image.src = dir + '/Klaver' + (i+2) +'.gif';
			// diamonds
			cards[i + 26].value = i+2;			
			cards[i + 26].colorindex = 2;
			cards[i + 26].color = "diamonds"
			cards[i + 26].colorname = "Ruiten";
			cards[i + 26].name = "Ruiten " + (i+2);
			cards[i + 26].image.src = dir + '/Ruiten' + (i+2) +'.gif';
			// spades
			cards[i + 39].value = i+2;
			cards[i + 39].colorindex = 3;
			cards[i + 39].color = "spades"
			cards[i + 39].colorname = "Schoppen";
			cards[i + 39].name = "Schoppen " + (i+2);
			cards[i + 39].image.src = dir + '/Schoppen' + (i+2) +'.gif';
		}		
		for (i = 0; i<4; i++) {		
			cards[9 + i*13].name = cards[9 + i*13].colorname + " boer";
			cards[10 + i*13].name = cards[10 + i*13].colorname + " dame";
			cards[11 + i*13].name = cards[11 + i*13].colorname + " heer";
			cards[12 + i*13].name = cards[12 + i*13].colorname + " aas";
		}		

		for (i = 0; i<5; i++) {
			low[i] = cards[i];				
			low[i+5] = cards[13 + i];	
			low[i+10] = cards[26 + i];	
			low[i+15] = cards[39 + i];	
		}
		
		for (i = 0; i<20; i++) {
		low[i].name = low[i].colorname + ' is troef';
		}
    
		for (i = 0; i<8; i++) {
			high[i] = cards[5 + i];				
			high[i+8] = cards[18 + i];	
			high[i+16] = cards[31 + i];	
			high[i+24] = cards[44 + i];	
		}

		SetupPlayableMatrix();
}

var playcolormatrix;
var playtrumpmatrix;

function SetupPlayableMatrix()
{
	playcolormatrix = new Array();
	playcolormatrix[1] = new Array(0, 0, 0, 0, 0, 0, 0, 11);
	playcolormatrix[2] = new Array(0, 0, 0, 5, 0, 0, 0, 8);
	playcolormatrix[3] = new Array(0, 0, 0, 6, 0, 0, 2, 7);

	playtrumpmatrix = new Array();
	playtrumpmatrix[1] = new Array(0, 0, 0, 0, 8, 0, 0, 0);
	playtrumpmatrix[2] = new Array(0, 0, 8, 0, 14, 0, 0, 6);
	playtrumpmatrix[3] = new Array(2, 2, 12, 8, 17, 3, 4, 11);
}


function ShowWelcomeMessage()
{ 
 	string = '<div id="welcome" class="welcome" STYLE="left:30%; top:20%; width:13% height=20%"></div>'
 	document.body.innerHTML += string;
  
  var c = '<table width=400 border=0 cellpadding=3><tr><td align=left>';
  c = c + 'Welkom op Sesamstraat Klaverjas. ';
  c = c + 'Weet je niet hoe je moet klaverjassen? Geen probleem, lees de spelregels en laat Koekiemonster je hints geven ';
  c = c + 'door op hem te dubbelklikken<br><br>';
  c = c + 'Wil je liever met andere regels spelen? Het is nu mogelijk om zelf de spelregels in te stellen!<br><br>';
  c = c + 'Laat tevens weten wat je van Sesamstraat Klaverjas vindt en hoe je denkt dat het spel verbeterd kan worden door commentaar te leveren!<br><br>';
  c = c + 'Dan wens ik je nu alvast heel veel speelplezier! Druk op OK om het spel te beginnen. ';
  c = c + '</td></tr>' ;
  c = c + '<tr><td align=center>' ;
  c = c + '<a href="javascript:StartGame()">OK</a>';
  c = c + '</td></tr>' ;
  welcome.innerHTML = c
}

function StartGame() {
    // welcome message was displayed, user clicked OK so wait till all images are loaded 
    // then start game
   IsFirstTime = false; 
   Match.Status = 9; 
   welcome.style.display = 'none'
}

// after the game has ended, the points won will be submitted to the server
// to see if the user has gained a highscore
function SubmitPoints() { 		
  var win=window.open('', 'highscore', 'alwaysRaised=yes; dependent=1; height=550; width=550; location=no; menubar=no; resizable=1; status=no; toolbar=no; scrollbars=1');
  win.focus(); // set focus to the window if it was already opened;
  //frmPoints.submit();
  //void(0);
}

//set to default configuration -> should use client side cookie
function SetupConfig() {
  var arr;
  var pairs;
  var c;
  var i;
  var version;
  var cfg = new Object();  
  // set the default values here
  
  Config = cfg; // set reference
  cfg.version = '1.3' // set version number!!  
  cfg.mouse_click = 0; // use single click by default  
  cfg.random_player = true;

  cfg.carddeck = 0; // set default to different deck
  cfg.playtrump = 0;
  cfg.turnrounds = 2;
  cfg.playspeed = 3; // normal
  
  
  var cookie = document.cookie;
  
  if (cookie != '') {
    IsFirstTime = false;
    c = document.cookie;
    c = c.replace(/ASPSESSIONID/,"//");
    //alert(c);
    arr = c.split("|");
    for (i=0; i<arr.length; i++) {
       //pairs = arr[i].split("=");
       //alert(arr[i]);
       eval(arr[i]); // will execute the cookie!, will set the config object to the correct values
    }          
  } else {      
        // create initial cookie with default values
        var date = new Date(9999,9,9); // set date to end of times
        var c = 'cfg.version=' + cfg.version + ';';
        c = c + 'expires=' + date.toGMTString()  + ';'; 
        document.cookie = c; // save the config in a cookie. makes it persistant
        //Show greetings for the first time user.
        IsFirstTime = true;                
  }
  
  // set the current values for this game
  cfg.cur_playtrump = cfg.playtrump;
  cfg.cur_turnrounds = cfg.turnrounds;
  cfg.cur_random_player = cfg.random_player;
  
  return cfg;
}

function StartDebug() {
  if (IsDebug)
    Debug = window.open('', 'debugwindow');
  else
    Debug = null;
  DebugClear()
}

function DebugClear() {
	if (Debug != null) { 
		Debug.document.body.innerHTML = '<h2>Debug window</h2><br>'; // clear body
	}
}

function DebugPrint(str) {
  if (Debug != null)
    Debug.document.body.innerHTML += str + '<br>';
}
