var suits = new Array("c", "d", "h", "s");
var hand = new Array();  //The hand of cards
var box = new Array();  //to hold discards

var gameType =1; // 0=5card singles, 1=doubles, 2=6 card singles
var dealSize = new Array(5,5,6);
var discards = new Array(2,1,2);
var options = new Array(10,5,15);



var imageArray = new Array(54);
var num_loaded_images =0;

function countImages()
{
  num_loaded_images++;
}


function preloadImages()
{
  imageArray[52] = new Image();
  imageArray[52].src = "images/cards/blank.gif"
  imageArray[53] = new Image();
  imageArray[53].src = "images/cards/BBcardback.gif"
  
  for(var i=0; i<52;i++)
  {
    imageArray[i] = new Image();
    imageArray[i].onload = countImages;
    imageArray[i].src = "images/cards/" + suit(i) + rank(i) + ".gif"
  }
}

function Score (total, fifteens, pairs, runs, runlen, flush, nob)
{
  this.total = total;
  this.fifteens = fifteens;
  this.pairs = pairs;
  this.runsize = runs;
  this.runlength = runlen;
  this.flush = flush;
  this.nob = nob; 
}

// return the suit, as a character
function suit(card)
{
  return (suits[Math.floor(card / 13)]);
}

//return the rank, as a number 1-13
function rank(card)
{
  var cardnum = card % 13;
  return(cardnum + 1);
}

// return the scoring value of a card, ie pictures=10
function value(card)
{
  var cardnum = card % 13;
  switch(cardnum)
  {
  case 10:
    cardnum=10;
    break    
  case 11:
    cardnum=10;
    break
  case 12:
    cardnum=10;
    break
  default:
    cardnum = cardnum + 1;
  }
  return(cardnum);
}

// return the title Eg 2C, JS
function cardname(card)
{
  var cardnum = card % 13;
  var cardrank;
  switch(cardnum)
  {
  case 0:
    cardrank = "A";
    break
  case 10:
    cardrank = "J";
    break    
  case 11:
    cardrank = "Q";
    break
  case 12:
    cardrank = "K";
    break
  default:
    cardrank = cardnum + 1;
  }
  return(cardrank + suit(card));
}

// draw card at current location
function writeCard (card, name)
{
  document.write("<img");
  document.write(" name=" + name);
  document.write(" onClick=cardClick(" + document.images.length + ")");
  if (card==-1)
  {
    document.write(" src='images/cards/blank.gif'");
  }
  else
  {
    document.write(" src='images/cards/" + suit(card) + rank(card) + ".gif'");
    document.write(" alt='" + cardname(card) +"'");
  }
  document.write(">");
}

// check that the card is not a duplicate
function duplicate(card)
{
  for (var j=0;j<hand.length; j++)
  {
    if (hand[j] == card) {return true}
  }
  for (var j=0;j<box.length; j++)
  {
    if (box[j] == card) {return true}
  }
  return false
}

// discard and close gap
function discard (c)
{
  box[box.length] = hand[c];

  for (card=c; card < hand.length; card++)
  {
    hand[card] = hand[card+1];
  }
  hand.length = hand.length-1;
}

// restore box card into hand
function restore (b)
{
  hand[hand.length] = box[b];

  for (card=b; card < box.length; card++)
  {
    box[card] = box[card+1];
  }
  box.length = box.length-1;
  
  sort();
}

// sort into numerical order, with suits sorted in arbitrary order
function sort ()
{
  var swap;
  for (c1 = 0; c1 < hand.length; c1++)
  {
    for (c2 = c1 + 1; c2 < hand.length; c2++)
    {
      if (rank(hand[c1]) > rank(hand[c2]))
      { 
         swap = hand[c1];
         hand[c1] = hand[c2];
         hand[c2] = swap;
      } 
      else if (rank(hand[c1]) == rank(hand[c2]))
      {
        if (hand[c1] > hand[c2])
        {
           swap = hand[c1];
           hand[c1] = hand[c2];
           hand[c2] = swap;
        }
      }
    }  
  }
}

// score the hand, assuming that the turnup is the last card
var showNoScore = 0;  //do not display the score
var showTotalScore = 1;  //just display the total
var showFullScore = 2;  //display breakdown of score
function scoreHand (showScore)
{
var total = 0;

// Count 15s
var fifteens = 0;
for (i=0; i<hand.length - 1; i++)
{
  for (j=i+1; j<hand.length; j++)
  {
    total = value(hand[i]) + value(hand[j]);
    if (total == 15)
    {
      fifteens++;
      continue;
    }
    else if (total > 15) {continue}
    
    for (k=j+1; k<hand.length; k++)
    {
      total = value(hand[i]) + value(hand[j]) + value(hand[k]);
      if (total == 15)
      {
        fifteens++;
        continue;
      }
      else if (total > 15) {continue}
      
      for (l=k+1; l<hand.length; l++)
      {
        total = value(hand[i]) + value(hand[j]) + value(hand[k]) + value(hand[l]);
        if (total == 15)
        {
          fifteens++;
          continue;
        }
        else if (total > 15) {continue}
      }
    }   
  }
}
if (value(hand[0]) + value(hand[1]) + value(hand[2]) + value(hand[3]) + value(hand[4]) == 15) {fifteens++}

// Count pairs
var pairs = 0;
for (i=0; i<hand.length - 1; i++)
{
  for (j=i+1; j<hand.length; j++)
  {
    if (rank(hand[i]) == rank(hand[j])) {pairs++}
  }
}

// Check for flush
var flush =0;
for (i=1; i<hand.length; i++)
{
  if (suit(hand[i]) != suit(hand[0])) {break}
}
if (i>=hand.length-1) {flush=i}

// Check for Nob
var nob =0;
for (jn=0; jn < hand.length-1; jn++)
{
  if ((suit(hand[jn]) == suit(hand[hand.length-1])) && (rank(hand[jn]) == 11))
  {
  nob = 1;
  break;
  }
}

// check for runs
var runs = new Array();
var totalRuns = 0;
runs[3] =0;
runs[4] =0;
runs[5] =0;
for (i=0; i<hand.length; i++)
{
  for (j=0; j<hand.length; j++)
  {
    if (rank(hand[j]) - rank(hand[i]) !=1){continue}
    for (k=0; k<hand.length; k++)
    {
      if (rank(hand[k]) - rank(hand[j]) !=1){continue}
      runs[3]++;
      for (l=0; l<hand.length; l++)
      {                                        
        if (rank(hand[l]) - rank(hand[k]) !=1){continue}
        runs[4] = runs[4]+1;
        for (m=0; m<hand.length; m++)
        {
          if (rank(hand[m]) - rank(hand[l]) !=1){continue}
          runs[5]++;
        }
      }
    }
  }
}
var runNo = 0;
var runLength = 0;

if (runs[5]==1)
{runNo=1;
 runLength=5;
}
else if (runs[4]>0)
{runNo = runs[4];
 runLength=4;}
else 
{runNo = runs[3];
 runLength=3;
 }

var total = ((pairs + fifteens) * 2) + flush + (runNo * runLength) + nob;
totalRuns = runNo * runLength;
var scoreResult = new Score(total, fifteens, pairs, runNo, runLength, flush, nob);

if (showScore == showFullScore)
{
  document.write("Fifteens: " + fifteens);
  document.write("<br>Pairs: " + pairs);
  document.write("<br>Runs: " + totalRuns);
  document.write("<br>Flush: " + flush);
  document.write("<br>Nob: " + nob);
}
if (showScore != showNoScore)
{
  //document.write("&nbsp;&nbsp;&nbsp; Total: " + total);
}

return scoreResult;
}


// display hand contents
function showHand (showScore, showTurnup, boxCards, extratext)
{
  var score;

  document.write("<table><tr>");
  for (i=0; i<hand.length; i++)
  {
  document.write("<td width=10%>");
  writeCard(hand[i], "displayhand");
  document.write("</td>");

  if ((i == hand.length-2) && (showTurnup))
  {
  document.write("<td width=10%>");
  writeCard(-1, "blank");
  document.write("</td>");

  }
  }
  document.write("<td>");
  score = scoreHand(showScore);
  document.write("</td>");
  if (showScore != showNoScore)
  {
    document.write("<td width=100>");
    document.write("Total: " + score.total);
    document.write("</td>");
  }

  for (b=0; b<boxCards.length; b++)
  {
  document.write("<td width=10%>");
  writeCard(boxCards[b], "displaybox");
  document.write("</td>");
  }

  if (extratext != null)
  {
    document.write("<td width=100>");
    document.write(extratext);
    document.write("</td>");
  }
  
  document.write("</tr></table>");
}

// Deal a hand of cards
function deal(handsize)
{
  hand.length=0;
  box.length=0;
  for (var dealtcard=0; dealtcard<handsize; dealtcard++)
  {
    hand[dealtcard] = dealCard();
  }

  sort();
  
}

// display cards ready to play
function displayGrid (showTurnup, gridTitle)
{
  document.write("<table><tr>");

  for (i=0; i<9; i++)
  {
    document.write("<td>"); 
    writeCard(-1, gridTitle);
    document.write("</td>");
  }

// span box for score text
    document.write("<td><table>");
    document.write("<tr><td align=center><span style='font-size:larger' id='" + gridTitle + "score1'>&nbsp;</span></td></tr>");
    document.write("<tr><td><span style='font-size:smaller' id='" + gridTitle + "score2'>&nbsp;</span></td></tr>");
    document.write("<tr><td><span style='font-size:smaller' id='" + gridTitle + "score3'>&nbsp;</span></td></tr>");
    document.write("<tr><td><span style='font-size:smaller' id='" + gridTitle + "score4'>&nbsp;</span></td></tr>");
    document.write("<tr><td><span style='font-size:smaller' id='" + gridTitle + "score5'>&nbsp;</span></td></tr>");
    document.write("<tr><td><span style='font-size:smaller' id='" + gridTitle + "score6'>&nbsp;</td></tr>");
    document.write("</td></tr></span></table></td>");

    document.write("</tr></table>");
}

// Change text in the named node to the string contents
function changeText (textString, elementId)
{
	var txt = document.createTextNode(textString);
	var elem = document.getElementById(elementId);
	var oldTxt = elem.replaceChild(txt, elem.firstChild);
}

function scoreString (number, value)
{
	var scoreText;
	
 	if (number == 0) {scoreText = 0}
 	else if (number == 1) {scoreText = value}
 	else scoreText = number + " x " + value;
 	
 	return (number * value);
}

// clear the displayed score text
function clearScore (gridName, verbose)
{
 	changeText("Total:  " , gridName + "score1");
 	
	if (!verbose) return;
	
	changeText("15s:  ", gridName + "score2");
	changeText("Pairs:  ", gridName + "score3");
	changeText("Runs:  ", gridName + "score4");
	changeText("Flush:  ", gridName + "score5");
	changeText("Nob:  ", gridName + "score6");
}

// display score in specified grid
function showHandScore (gridName, score, verbose)
{
 	changeText("Total: " + score.total, gridName + "score1");
 	
	if (!verbose) return;
	
	changeText("15s: " + scoreString(score.fifteens,2), gridName + "score2");
	changeText("Pairs: " + scoreString(score.pairs,2), gridName + "score3");
	changeText("Runs: " + scoreString(score.runsize, score.runlength), gridName + "score4");
	changeText("Flush: " + scoreString(1,score.flush), gridName + "score5");
	changeText("Nob: " + scoreString(score.nob,1), gridName + "score6");

}

// change displayed contents of the grid
function changeHand (gridTitle, showTurnup, showBox)
{
// Find out where the named set of cards start
  var imageIndex = 0;
  for (j=0;j<document.images.length;j++)
  {
    if (document.images[j].name==gridTitle)
    {
      imageIndex=j;
      break;
    }
  }

//alert(imageIndex);

  for (var i=0;i<document.displayhand.length;i++)
  {
    document.images[i + imageIndex].src = imageArray[52].src;
    document.images[i + imageIndex].alt = "blank";
    document.images[i + imageIndex].border = 0;
  }
  
  var gridPos = imageIndex;
  for (var i=0;i<hand.length;i++)
  {
    document.images[gridPos].src = imageArray[hand[i]].src;
    document.images[gridPos].alt = cardname(hand[i]);
    if (((hand.length - i) == 2) && showTurnup) {gridPos++}
    gridPos++;
  }

  for (var i=0;(i<box.length && showBox);i++)
  {
    document.images[i+imageIndex+7].src = imageArray[box[i]].src;
    document.images[i+imageIndex+7].alt = cardname(box[i]);
    document.images[i+imageIndex+7].style.MozOpacity = 0.5;
    document.images[i+imageIndex+7].style.filter = "alpha(opacity=50)";
  }

  for (var i=0;(i<discards[gameType] && showBox);i++)
  {
    document.images[i+imageIndex+7].border = 1;
  }
  
  
}

// get a random card, checking for duplicates
function dealCard ()
{
	var card;
	do
	{
		card = Math.floor(Math.random() * 52);
	}
	while (duplicate(card))
	return card; 
}

// get statistics for the hand
function handStats(disc1,disc2)
{
  var thisScore = 0;
  var allScores = 0;
  var allScoresSq = 0;
  var maxScore = 0;
  var minScore = 30;
  var maxHand = 0;
  var handsCounted = 0;

  for (turnup=0;turnup<52;turnup++)
  {
    if (!duplicate(turnup))
    {
      handsCounted++;
      hand[hand.length]= turnup;

      thisScore = new scoreHand();
      allScores = allScores + thisScore.total;
      allScoresSq = allScoresSq + (thisScore.total * thisScore.total);
      if (maxScore < thisScore.total)
      {
        maxScore = thisScore.total;
        maxHand = turnup;
      } 
      if (minScore > thisScore.total)
      {
       minScore = thisScore.total;
      } 
      hand.length = hand.length-1;
    }
  }

 this.maxScore = maxScore;
 this.minScore = minScore;
 this.average = (Math.round(allScores * 100 / handsCounted))/100;
 this.rms = (Math.round(Math.sqrt(allScoresSq) * 100 / handsCounted))/100;
 this.turnup = maxHand;
 this.disc = new Array(disc1, disc2);
// this.disc1 = disc1;
// this.disc2 = disc2;
}

function sortAverage(a,b)
{
  return b.average - a.average;
}

// find the best card(s) to discard
var allStats = new Array();

function bestDiscard()
{
allStats.length=0;

for (disc1 = 0;disc1<hand.length; disc1++)
{
  discard(disc1);

  for (disc2 = 0;disc2<hand.length; disc2++)
  {
    if (discards[gameType] == 2)
    {
      if (disc2<disc1){continue}
      else {discard(disc2)}
    }
    allStats[allStats.length] = new handStats(disc1,disc2);

    if (discards[gameType] == 2){restore(1)}
    else {break}
  }
  restore(0);
}
allStats.sort(sortAverage);

}

// show handtype symbols
function showSmallBack(handType)
{
	for (i=0;i<dealSize[handType]-discards[handType];i++){document.write('<img src="/images/cards/Smallback.gif">')}
	document.write(' ');
	for (i=0;i<discards[handType];i++){document.write('<img src="/images/cards/Smallback.gif">')}
}



