<?xml version="1.0" encoding="utf-8"?>

<!--
 template for converting darcs' `annotate` output from XML to XHTML.  This
 template expects the following external variables:

   cgi-program    - path to the CGI executable, to place in links
   sort-by        - field to sort by
   stylesheet     - path to the CSS stylesheet

-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>

  <xsl:include href="common.xslt"/>

  <xsl:template match="path">
    <h1 class="target">
      annotations for <span class="path"><xsl:apply-templates/></span>
    </h1>
  </xsl:template>

  <!-- patch annotate tags -->
  <xsl:template match="/darcs/patch">
    <xsl:call-template name="show-patch-info">
      <xsl:with-param name="patch" select="."/>
      <xsl:with-param name="show-comment" select="true()"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template match="summary">
    <xsl:variable name="hash" select="../patch/@hash"/>
      
    <table>
      <tr class="annotate">
        <th>file</th>
        <th>change</th>
        <th></th>
        <th></th>
      </tr>

      <xsl:apply-templates/>
    </table>

    <form action="{$command}" method="get">
      <p>
        <input type="submit" name="c" value="diff"/>
        <input type="hidden" name="p" value="{$hash}"/>
      </p>
    </form>
  </xsl:template>
  
  <xsl:template match="modify_file">
    <xsl:variable name="file" select="text()"/>
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
      
    <tr class="modified-file">
      <td><xsl:value-of select="$file"/></td>

      <td class="line-count">
        <xsl:for-each select="added_lines">
          +<xsl:value-of select="@num"/>/
        </xsl:for-each>
        <xsl:for-each select="removed_lines">-<xsl:value-of select="@num"/>
        </xsl:for-each>
        lines
      </td>

      <td><a href="{$command}{$file}?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$file}?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="add_file">
    <xsl:variable name="file" select="text()"/>
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$file"/></td>
      <td>added file</td>
      <td><a href="{$command}{$file}?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$file}?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="move">
    <xsl:variable name="file" select="@to"/>
    <xsl:variable name="old-file" select="@from"/>    
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$file"/></td>
      <td>moved from <xsl:value-of select="$old-file"/></td>
      <td><a href="{$command}{$file}?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$file}?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="remove_file">
    <xsl:variable name="file" select="text()"/>
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$file"/></td>
      <td>removed file</td>
      <td><a href="{$command}{$file}?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$file}?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="add_directory">
    <xsl:variable name="dir" select="text()"/>
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$dir"/></td>
      <td>added directory</td>
      <td><a href="{$command}{$dir}/?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$dir}/?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="remove_directory">
    <xsl:variable name="dir" select="text()"/>
    <xsl:variable name="hash" select="/darcs/patch/@hash" />
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$dir"/></td>
      <td>removed directory</td>
      <td><a href="{$command}{$dir}/?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$dir}/?c=patches">patches</a></td>
    </tr>
  </xsl:template>
  
  <!-- directory annotate templates -->
  <xsl:template match="/darcs/directory">
    <xsl:call-template name="show-patch-info">
      <xsl:with-param name="patch" select="modified/patch"/>
    </xsl:call-template>

    <table>
      <tr class="annotate">
        <th>file</th>
        <th>change</th>
        <th></th>
        <th></th>
      </tr>

      <xsl:apply-templates/>
    </table>
  </xsl:template>
  
  <xsl:template match="directory/modified/modified_how">
    <xsl:variable name="hash" select="../patch/@hash" />
    <xsl:variable name="how" select="substring(text(), 0, 10)"/>
    <xsl:variable name="target" select="/darcs/@target"/>

    <!--
      annotating a directory outputs the directory itself as well as
      any contents.  this ugly code checks if the matching element is
      the original directory so that the 'annotate' and 'patch' links
      don't append the directory twice.
    -->
    <xsl:variable name="last" select="//darcs/path/directory[last()]"/>
    <xsl:variable name="name" select="../../@name"/>
    <xsl:variable name="dir">
      <xsl:choose>
        <xsl:when test="$last = $name"></xsl:when>
        <xsl:otherwise><xsl:value-of select="$name"/>/</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <tr class="add-remove-file">
      <td><xsl:value-of select="$name"/></td>
      <td>
        <xsl:choose>
          <xsl:when test="$how = 'Dir added'">added directory</xsl:when>
          <xsl:when test="$how = 'Dir moved'">moved directory</xsl:when>
          <xsl:when test="$how = 'Dir remov'">removed directory</xsl:when>
        </xsl:choose>
      </td>
      <td>
        <a href="{$command}{$dir}?c=annotate&amp;p={$hash}">annotate</a>
      </td>
      <td><a href="{$command}{$dir}?c=patches">patches</a></td>
    </tr>
  </xsl:template>

  <xsl:template match="directory/file/modified/modified_how">
    <xsl:variable name="file" select="../../@name"/>
    <xsl:variable name="hash" select="../patch/@hash" />
    <xsl:variable name="how" select="substring(text(), 0, 11)"/>
    
    <tr class="add-remove-file">
      <td><xsl:value-of select="$file"/></td>
      <td>
        <xsl:choose>
          <xsl:when test="$how = 'File added'">added file</xsl:when>
          <xsl:when test="$how = 'File moved'">moved file</xsl:when>
          <xsl:when test="$how = 'File remov'">removed file</xsl:when>
        </xsl:choose>
      </td>
      <td><a href="{$command}{$file}?c=annotate&amp;p={$hash}">annotate</a></td>
      <td><a href="{$command}{$file}?c=patches">patches</a></td>
    </tr>
  </xsl:template>
   
  <!-- file annotate templates -->
  <xsl:template match="/darcs/file">
    <xsl:variable name="modified_how" select="modified/modified_how/text()"/>
    
    <xsl:call-template name="show-patch-info">
      <xsl:with-param name="patch" select="modified/patch"/>
    </xsl:call-template>

    <!-- don't display table of changes when file's contents are modified -->
    <xsl:if test="$modified_how != 'File modified'">
      <xsl:variable name="file" select="@name"/>
      <xsl:variable name="how" select="substring($modified_how, 0, 11)"/>

      <xsl:variable name="annotate-href">
        <xsl:call-template name="make-annotate-href">
          <xsl:with-param name="hash" select="modified/patch/@hash"/>
        </xsl:call-template>
      </xsl:variable>
      
      <table>
        <tr class="annotate">
          <th>file</th>
          <th>change</th>
          <th></th>
          <th></th>
        </tr>

        <tr class="add-remove-file">
          <td><xsl:value-of select="$file"/></td>
          <td>
            <xsl:choose>
              <xsl:when test="$how = 'File added'">added file</xsl:when>
              <xsl:when test="$how = 'File moved'">moved file</xsl:when>
              <xsl:when test="$how = 'File remov'">removed file</xsl:when>
            </xsl:choose>
          </td>
          <td><a href="{$annotate-href}">annotate</a></td>
          <td><a href="{$command}?c=patches">patches</a></td>
        </tr>
      </table>
    </xsl:if>

    <!-- the empty <p/> element is a Konqueror bug workaround -->
    <pre xml:space="preserve"><p/>
      <xsl:apply-templates/>
    </pre>
  </xsl:template>
  
  <xsl:template match="added_line">
    <xsl:variable name="annotate-href">
      <xsl:call-template name="make-annotate-href">
        <xsl:with-param name="hash" select="preceding::modified/patch/@hash"/>
      </xsl:call-template>
    </xsl:variable>
    
    <a class="added-line" href="{$annotate-href}">
      <pre><xsl:value-of select="text()"/></pre>
    </a>
    <xsl:call-template name="check-removed-by"/>
  </xsl:template>

  <xsl:template match="normal_line">
    <xsl:variable name="annotate-href">
      <xsl:call-template name="make-annotate-href">
        <xsl:with-param name="hash" select="*/patch/@hash"/>
      </xsl:call-template>
    </xsl:variable>

    <a class="normal-line" href="{$annotate-href}">
      <pre><xsl:value-of select="text()"/></pre>
    </a>
    <xsl:call-template name="check-removed-by"/>
  </xsl:template>

  <xsl:template match="removed_line">
    <xsl:variable name="annotate-href">
      <xsl:call-template name="make-annotate-href">
        <xsl:with-param name="hash" select="*/patch/@hash"/>
      </xsl:call-template>
    </xsl:variable>
    
    <!-- don't display removed lines when a file is removed -->
    <xsl:if test="../modified/modified_how/text() != 'File removed'">
      
      <a class="removed-line" href="{$annotate-href}">
        <pre><xsl:value-of select="text()"/></pre>
      </a>
      <xsl:call-template name="check-removed-by"/>
    </xsl:if>
  </xsl:template>

  <xsl:template name="check-removed-by">
    <xsl:variable name="hash" select="removed_by/patch/@hash"/>
    
    <xsl:variable name="annotate-href">
      <xsl:call-template name="make-annotate-href">
        <xsl:with-param name="hash" select="$hash"/>
      </xsl:call-template>
    </xsl:variable>
    
    <xsl:choose>
      <xsl:when test="$hash != ''">
        <a class="removed-by" href="{$annotate-href}">-</a>
      </xsl:when>
    </xsl:choose>

    <!-- put a newline after the hyperlink -->      
    <xsl:text xml:space="preserve">
    </xsl:text>
  </xsl:template>

  <xsl:template name="show-patch-info">
    <xsl:param name="patch"/>
    <xsl:param name="show-comment"/>
    
    <xsl:variable name="hash" select="$patch/@hash"/>
    <xsl:variable name="name" select="$patch/name"/>
    
    <h2 class="patch">
      patch "<span class="path">
      <a href="{$cgi-program}/{$repo}/?c=annotate&amp;p={$hash}">
        <xsl:value-of select="$name"/>
      </a>
      </span>"
    </h2>

    <xsl:if test="$show-comment">
      <h2 class="patch">
        comment "<span class="comment">
        <xsl:value-of select="$patch/comment"/>
        </span>"
    </h2>
      
    </xsl:if>
  </xsl:template>

  <xsl:template name="make-annotate-href" xml:space="default">
    <xsl:param name="hash"/>

    <xsl:variable name="created-as" select="/darcs/*/created_as"/>
    <xsl:variable name="creator-hash" select="$created-as/patch/@hash"/>
    <xsl:variable name="original-name" select="$created-as/@original_name"/>
    
    <xsl:value-of select="$command"/>?c=annotate&amp;p=<xsl:value-of select="$hash"/>&amp;ch=<xsl:value-of select="$creator-hash"/>&amp;o=<xsl:value-of select="$original-name"/>
  </xsl:template>

  <!-- ignore <name>, <comment> and <modified_how> children -->
  <xsl:template match="name"/>
  <xsl:template match="comment"/>
  <xsl:template match="modified_how"/>
</xsl:stylesheet>
