<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY f  "http://xmlns.4suite.org/ext">
  <!ENTITY fres "http://xmlns.4suite.org/reserved">
]>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:cext="http://xmlns.4suite.org/demos/cards"
  xmlns:exslt="http://exslt.org/common"
  xmlns:exslt-str="http://exslt.org/strings"
  xmlns:f="&f;"
  xmlns:fcore="http://xmlns.4suite.org/4ss/score"
  xmlns:fhttp="http://xmlns.4suite.org/4ss/http"
  xmlns:fres="&fres;"
  xmlns:xupdate="http://www.xmldb.org/xupdate"
  extension-element-prefixes="cext exslt exslt-str f fcore fhttp fres"
  exclude-result-prefixes="xupdate"
>

  <!--

    4Suite repository demo application: Cribbage

    Discard processing

    Copyright 2004 Fourthought, Inc. (USA)
    http://4suite.org/

  -->

  <xsl:import href='changes.xsl'/>
  <xsl:import href='error.xslt'/>

  <xsl:output method='html'/>

  <xsl:param name='fres:uri-path'/>
  <xsl:param name='debug'/>

  <xsl:param name='DISCARD1'/>
  <xsl:param name='DISCARD2'/>
  <xsl:param name='DISCARD3'/>
  <xsl:param name='DISCARD4'/>
  <xsl:param name='DISCARD5'/>
  <xsl:param name='DISCARD6'/>

  <xsl:template match='/'>
    <xsl:choose>
      <xsl:when test="not(not($DISCARD1)) + not(not($DISCARD2)) + not(not($DISCARD3)) + not(not($DISCARD4)) + not(not($DISCARD5)) + not(not($DISCARD6)) != 2">

        <xsl:variable name='headers'>
          <fhttp:request-headers/>
        </xsl:variable>

        <xsl:variable name='referer'>
          <xsl:value-of select='substring-after(exslt:node-set($headers)/Header[Name="referer"]/Value[substring-after(.,"xslt=")],"xslt=")'/>
        </xsl:variable>
        <xsl:variable name='xslt'>
          <xsl:choose>
            <xsl:when test='$referer'>
              <xsl:value-of select='$referer'/>
            </xsl:when>
            <xsl:otherwise>
              ../draw.xsl
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:call-template name="display-error">
          <xsl:with-param name='message' select='"You must discard exactly two cards"'/>
          <xsl:with-param name='uri' select='concat($fres:uri-path,"?xslt=",string($xslt))'/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <!--
          We need to change the Game file to show the changes to the user hand
          Also, we need to select two cards for the computer to discard
        -->
        <xsl:variable name='human-changes'>
          <xsl:call-template name='discard-human'/>
        </xsl:variable>

        <xsl:variable name='computer-keep-all'>
          <xsl:call-template name='computer-discard'>
            <xsl:with-param name='human-discards' select='exslt:node-set($human-changes)/Changes/Discard/Card'/>
          </xsl:call-template>
        </xsl:variable>

        <xsl:variable name='index'>
          <xsl:choose>
            <xsl:when test='key("players",1)/@level="easy"'>
              <!-- normal-easy a random number between 1 and 7 -->
              <xsl:value-of select='f:random(6,1)+1'/>
            </xsl:when>
            <xsl:otherwise>
              <!-- normal-(normal|hard) = 1 -->
              <xsl:value-of select='1'/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:variable name='computer-keep' select='exslt:node-set($computer-keep-all)/CribbageCount[position() = number($index)]'/>
        <!-- Create the final changes -->
        <xsl:variable name='changes'>
          <Changes>
            <!-- Human -->
            <xsl:copy-of select='exslt:node-set($human-changes)/Changes/Discard'/>

            <!-- Now the computer -->
            <xsl:if test='$debug = "debug"'>
              <xsl:comment>
                COMPUTER START DISCARD!!!!
                Game Direction: <xsl:value-of select='/cribbage/game-info/@type'/>,
                Computer player level: <xsl:value-of select='key("players",1)/@level'/>,
                All of the computer's calculations:
                <xsl:apply-templates select='exslt:node-set($computer-keep-all)/CribbageCount' mode='serialize'/>
                Selecting Index: <xsl:value-of select='$index'/>
                The final selection
                <xsl:apply-templates select='exslt:node-set($computer-keep)'  mode='serialize'/>
                COMPUTER END DISCARD!!!!
              </xsl:comment>
            </xsl:if>

            <xsl:for-each select='key("players",1)/cards/Card'>
              <xsl:choose>
                <xsl:when test='exslt:node-set($computer-keep)/OriginalHand/Card[@short-name = current()/@short-name]'/>
                <xsl:otherwise>
                  <Discard player='1'>
                    <xsl:copy-of select='key("players",1)/playing-cards/Card[@short-name = current()/@short-name]'/>
                  </Discard>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each>


            <!--lastly see if the cut card gave the current dealer points -->
            <xsl:if test='/cribbage/game-info/cut-card/Card/@value-int = 11'>
              <!-- Give the dealer some points  -->
              <xsl:call-template name='award-points'>
                <xsl:with-param name='player' select='/cribbage/game-info/cur-dealer/@IDREF'/>
                <xsl:with-param name='amount' select='2'/>
                <xsl:with-param name='message' select='"Cut a Jack for 2"'/>
              </xsl:call-template>
            </xsl:if>

            <xsl:call-template name='log-message'>
              <xsl:with-param name='player' select='$initial-dealer'/>
              <xsl:with-param name='message' select='concat("Cut ",/cribbage/game-info/cut-card/Card/@short-name)'/>
            </xsl:call-template>

          </Changes>
        </xsl:variable>

        <xsl:call-template name='process-next-step'>
          <xsl:with-param name='current-changes' select='$changes'/>
        </xsl:call-template>

      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


  <xsl:template name='discard-human'>
    <!--
      Determine which two cards the human discarded.
      Not very elegant! probably should use f:request-args to make it cleaner?
    -->
    <Changes>
      <xsl:if test='$DISCARD1'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD1]'/>
        </Discard>
      </xsl:if>
      <xsl:if test='$DISCARD2'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD2]'/>
        </Discard>
      </xsl:if>
      <xsl:if test='$DISCARD3'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD3]'/>
        </Discard>
      </xsl:if>
      <xsl:if test='$DISCARD4'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD4]'/>
        </Discard>
      </xsl:if>
      <xsl:if test='$DISCARD5'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD5]'/>
        </Discard>
      </xsl:if>
      <xsl:if test='$DISCARD6'>
        <Discard player='2'>
          <xsl:copy-of select='key("players",2)/playing-cards/Card[@short-name = $DISCARD6]'/>
        </Discard>
      </xsl:if>
    </Changes>
  </xsl:template>

  <xsl:template name='computer-discard'>
    <xsl:param name='human-discards'/>


    <!--
         Find the set of four cards that the computer should keep

         Computer levels of difficulty

         easy: sort a set of results by which keeps the highest amount of points
               in the hand.  Don't use the draw card.  Then pick randomly between
               1-7 as to which one to use. (there are fifteen possible choices)

         normal:  sort the set of results by which keeps the highest
                  number of points.  Don't use the draw card.  Then keep the
                  highest.

         hard:  sort the set of results by which keeps the highest points
                in the hand.  Use the cut card in the calculations (cheating!!)
                Then, count the crib resulting crib.  If it is the computers crib
                Then add these points to the total, if it is not, then subtract these points
                from the total.

         -->

    <xsl:variable name='all-hands'>
      <AllHands>
        <xsl:for-each select='key("players",1)/cards/Card'>
          <xsl:variable name='skip-card1-pos' select='position()'/>
          <xsl:for-each select='key("players",1)/cards/Card'>
            <xsl:if test='position() > $skip-card1-pos'>

              <xsl:variable name='skip-card2-pos' select='position()'/>

              <!-- Create the set of cards to pass into count
                   -->
              <xsl:variable name='cards'>
                <xsl:for-each select='key("players",1)/cards/Card[position() != $skip-card2-pos and position() != $skip-card1-pos]'>
                  <xsl:copy-of select='.'/>
                </xsl:for-each>

                <!-- If we are in hard mode, add the discard -->
                <xsl:if test='key("players",1)/@level="hard"'>
                  <xsl:copy-of select='/cribbage/game-info/cut-card/Card'/>
                </xsl:if>
              </xsl:variable>

              <!-- If we are in hard mode, then we are add in the discard
                   -->
              <xsl:variable name='draw'>
                <xsl:choose>
                  <xsl:when test='key("players",1)/@level="hard"'>
                    <xsl:copy-of select='/cribbage/game-info/cut-card/Card'/>
                  </xsl:when>
                </xsl:choose>
              </xsl:variable>
              <xsl:variable name='cur-hand'>
                <xsl:call-template name='count-hand'>
                  <xsl:with-param name='cards' select='exslt:node-set($cards)/Card'/>
                  <xsl:with-param name='is-crib' select='0'/>
                  <xsl:with-param name='draw' select='exslt:node-set($draw)/Card'/>
                </xsl:call-template>
              </xsl:variable>
              <xsl:choose>
                <xsl:when test='key("players",1)/@level="hard"'>
                  <!-- Add in some checking to see what this does to the crib
                       -->
                  <!-- Build the cards to count the crib
                       -->
                  <xsl:variable name='crib-cards'>
                    <xsl:copy-of select='key("players",1)/cards/Card[position() = $skip-card1-pos]'/>
                    <xsl:copy-of select='key("players",1)/cards/Card[position() = $skip-card2-pos]'/>
                    <xsl:copy-of select='$human-discards'/>
                    <xsl:copy-of select='/cribbage/game-info/cut-card/Card'/>
                  </xsl:variable>

                  <xsl:variable name='cur-crib'>
                    <xsl:call-template name='count-hand'>
                      <xsl:with-param name='cards' select='exslt:node-set($crib-cards)/Card'/>
                      <xsl:with-param name='is-crib' select='1'/>
                      <xsl:with-param name='draw' select='/cribbage/game-info/cut-card/Card'/>
                    </xsl:call-template>
                  </xsl:variable>

                  <CribbageCount>
                    <!-- We really only care about the total attribute here, but copy all for debugginh -->
                    <xsl:for-each select='exslt:node-set($cur-hand)/CribbageCount/@*[local-name() != "total"]'>
                      <xsl:copy-of select='.'/>
                    </xsl:for-each>
                    <xsl:attribute name='original-total'>
                      <xsl:value-of select='exslt:node-set($cur-hand)/CribbageCount/@total'/>
                    </xsl:attribute>
                    <xsl:attribute name='total'>
                      <xsl:choose>
                        <xsl:when test='number($initial-dealer) = 1'>
                          <!-- our crib add cur-hand and cur-crib to make new total -->
                          <xsl:value-of select='number(exslt:node-set($cur-hand)/CribbageCount/@total) + number(exslt:node-set($cur-crib)/CribbageCount/@total)'/>
                        </xsl:when>
                        <xsl:otherwise>
                          <!-- Human crib, subtract -->
                          <xsl:value-of select='number(exslt:node-set($cur-hand)/CribbageCount/@total) - number(exslt:node-set($cur-crib)/CribbageCount/@total)'/>
                        </xsl:otherwise>
                      </xsl:choose>
                    </xsl:attribute>
                    <xsl:copy-of select='exslt:node-set($cur-hand)/CribbageCount/node()'/>
                    <CribCount>
                      <xsl:copy-of select='exslt:node-set($cur-crib)/CribbageCount'/>
                    </CribCount>
                  </CribbageCount>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:copy-of select='exslt:node-set($cur-hand)/CribbageCount'/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:if>
          </xsl:for-each>
        </xsl:for-each>
      </AllHands>
    </xsl:variable>

    <xsl:variable name='order'>
      <xsl:choose>
        <xsl:when test='/cribbage/game-info/@type="normal"'>
          <xsl:text>descending</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>ascending</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <!-- Sort the results  and return them-->
    <xsl:for-each select='exslt:node-set($all-hands)/AllHands/CribbageCount'>
      <xsl:sort select='@total' data-type='number' order='{$order}'/>
      <xsl:copy-of select='.'/>
    </xsl:for-each>

  </xsl:template>


</xsl:stylesheet>
