<?xml version="1.0"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
   <xsl:param name="ball">70</xsl:param>

   <xsl:param name="rows">15</xsl:param>

   <xsl:param name="cols">10</xsl:param>

   <xsl:variable name="nball" select="//ROOT/BALLS/BALL[@id=$ball]" />

   <xsl:template match="/">
      <xsl:variable name="nAllChain">
         <xsl:variable name="InChain">
            <CHAIN>
               <xsl:copy-of select="$nball" />
            </CHAIN>
         </xsl:variable>

         <xsl:call-template name="DoChain">
            <xsl:with-param name="Chain" select="msxsl:node-set($InChain)/CHAIN" />

            <xsl:with-param name="cnt" select="1" />
         </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="AllChain" select="msxsl:node-set($nAllChain)/CHAIN/BALL" />

      <xsl:variable name="colsUsed" select="$AllChain[not(./@x = preceding::BALL/@x)]" />

      <ROOT cnt="{count($AllChain)}">
         <COLS>
            <xsl:apply-templates select="$colsUsed">
               <xsl:with-param name="thisChain" select="$AllChain" />
            </xsl:apply-templates>
         </COLS>

         <xsl:copy-of select="//ROOT/BALLS" />
      </ROOT>
   </xsl:template>

   <xsl:template match="BALL">
      <xsl:param name="thisChain" />

      <xsl:variable name="x" select="@x" />

      <xsl:variable name="xBalls" select="$thisChain[@x = $x]" />

      <COL x="{@x}" cnt="{count($xBalls)}">
         <xsl:apply-templates select="$xBalls" mode="fred">
            <xsl:sort select="@y" data-type="number" order="descending" />

            <xsl:with-param name="thisChain" select="$thisChain" />
         </xsl:apply-templates>
      </COL>
   </xsl:template>

   <xsl:template match="BALL" mode="fred">
      <xsl:param name="thisChain" />

      <xsl:variable name="id" select="@id" />

      <xsl:variable name="x" select="@x" />

      <xsl:variable name="y" select="@y" />

      <xsl:variable name="north" select="$thisChain[@id = $id + $cols]" />

      <xsl:variable name="south" select="$thisChain[@id = $id - $cols]" />

      <xsl:variable name="east" select="$thisChain[@id = $id + 1]" />

      <xsl:variable name="west" select="$thisChain[@id = $id - 1]" />

      <BALL y="{$y}" id="{@id}" color="{@color}">
         <xsl:if test="not($north)">
            <TOP />
         </xsl:if>

         <xsl:if test="not($south)">
            <BOTTOM />
         </xsl:if>

         <xsl:if test="not($west)">
            <LEFT />
         </xsl:if>

         <xsl:if test="$x = 0">
            <LEFT />
         </xsl:if>

         <xsl:if test="not($east)">
            <RIGHT />
         </xsl:if>

         <xsl:if test="$x = $cols - 1">
            <RIGHT />
         </xsl:if>
      </BALL>
   </xsl:template>

   <xsl:template name="DoChain">
      <xsl:param name="Chain" />

      <xsl:param name="cnt" />

      <xsl:choose>
         <xsl:when test="$Chain/BALL[$cnt]">
            <xsl:call-template name="DoCell">
               <xsl:with-param name="thisBall" select="$Chain/BALL[$cnt]" />

               <xsl:with-param name="Chain" select="$Chain" />

               <xsl:with-param name="cnt" select="$cnt" />
            </xsl:call-template>
         </xsl:when>

         <xsl:otherwise>
            <xsl:copy-of select="$Chain" />
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template name="DoCell">
      <xsl:param name="thisBall" />

      <xsl:param name="Chain" />

      <xsl:param name="cnt" />

      <xsl:variable name="id" select="$thisBall/@id" />

      <xsl:variable name="color" select="$thisBall/@color" />

      <xsl:variable name="col" select="$id mod $cols" />

      <xsl:variable name="row" select="floor($id div $cols)" />

      <xsl:variable name="north" select="$id + $cols" />

      <xsl:variable name="northBall" select="//ROOT/BALLS/BALL[@id=$north and @color = $color]" />

      <xsl:variable name="east" select="$id + 1" />

      <xsl:variable name="eastBall" select="//ROOT/BALLS/BALL[@id=$east and @color = $color]" />

      <xsl:variable name="eastcol" select="$eastBall/@id mod $cols" />

      <xsl:variable name="south" select="$id - $cols" />

      <xsl:variable name="southBall" select="//ROOT/BALLS/BALL[@id=$south and @color = $color]" />

      <xsl:variable name="west" select="$id - 1" />

      <xsl:variable name="westBall" select="//ROOT/BALLS/BALL[@id=$west and @color = $color]" />

      <xsl:variable name="westcol" select="$westBall/@id mod $cols" />

      <xsl:variable name="goOn" select="$northBall or $eastBall or $southBall or $westBall" />

      <xsl:if test="$goOn">
         <xsl:variable name="nlocalChain">
            <CHAIN>
               <xsl:copy-of select="$Chain/BALL" />

               <xsl:if test="not($Chain/BALL[@id=$north]) and $northBall">
                  <xsl:copy-of select="$northBall" />
               </xsl:if>

               <xsl:if test="not($Chain/BALL[@id=$east]) and $eastBall and($col &lt; $eastcol)">
                  <xsl:copy-of select="$eastBall" />
               </xsl:if>

               <xsl:if test="not($Chain/BALL[@id=$south]) and $southBall">
                  <xsl:copy-of select="$southBall" />
               </xsl:if>

               <xsl:if test="not($Chain/BALL[@id=$west]) and $westBall and($col = $westcol + 1)">
                  <xsl:copy-of select="$westBall" />
               </xsl:if>
            </CHAIN>
         </xsl:variable>

         <xsl:variable name="localChain" select="msxsl:node-set($nlocalChain)/CHAIN" />

         <xsl:call-template name="DoChain">
            <xsl:with-param name="Chain" select="$localChain" />

            <xsl:with-param name="cnt" select="$cnt + 1" />
         </xsl:call-template>
      </xsl:if>
   </xsl:template>
</xsl:transform>


