<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:sp="http://www.w3.org/2005/sparql-results#">

  <xsl:template match="/">
    <ul>
      <!-- Step through row keys -->
      <xsl:for-each select="/sp:sparql/sp:results/sp:result">
        <!--<xsl:variable name="previous" select="/sp:sparql/sp:results/sp:result[$position -1]/sp:binding[1]/*"/>-->
        <xsl:param name="previous" select="(preceding-sibling::sp:result[1])/sp:binding[1]/*"/>
        <xsl:param name="subject" select="sp:binding[1]/*"/>
        <!-- Make sure we haven't seen it before... -->
        <xsl:if test="($subject != $previous) or (position() = 1)">
          <xsl:apply-templates select="." mode="search">
            <xsl:with-param name="position" select="1"/>
          </xsl:apply-templates>
        </xsl:if>
      </xsl:for-each>
    </ul>
  </xsl:template>
 
  <!-- Search for end of contiguous subjects -->
  <xsl:template mode="search" match="sp:result">
    <xsl:param name="subject" select="sp:binding[1]/*"/>
    <xsl:param name="nextSubject" select="following-sibling::sp:result[1]/sp:binding[1]/*"/>
    <xsl:param name="atEnd" select="count(following-sibling::sp:result[1]) = 0"/>
    <xsl:choose>
      <xsl:when test="($nextSubject != $subject) or $atEnd">
        <xsl:param name="nodes" select=".|preceding-sibling::sp:result[$position > position()]"/>
        <xsl:apply-templates select="$subject" mode="listing">
          <xsl:with-param name="nodes" select="$nodes"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="following-sibling::sp:result[1]" mode="search">
          <xsl:with-param name="position" select="$position + 1"/>
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <!-- List each key -->
  <xsl:template mode="listing" match="*">
    <li><xsl:apply-templates select="." mode="display"/>
      <!--
      <xsl:text> (rows </xsl:text>
      <xsl:value-of select="$nodes[1]"/>
      <xsl:text>:</xsl:text>
      <xsl:value-of select="$end"/>
      <xsl:text>)</xsl:text>
      -->
      <!-- List properties -->
      <ul>
        <xsl:apply-templates select="/sp:sparql/sp:head/sp:variable[position()>1]/@name"
                             mode="properties">
          <xsl:with-param name="nodes" select="$nodes"/>
        </xsl:apply-templates>
      </ul>
    </li>
    <xsl:text>
</xsl:text>
  </xsl:template>
  
  <!-- List out the properties per row -->
  <xsl:template mode="properties" match="@name">
    <xsl:variable name="attr_name"><xsl:value-of select="."/></xsl:variable>
    <xsl:variable name="values" select="$nodes/sp:binding[@name=$attr_name]/*[text()]"/>
    <xsl:if test="count($values) > 0">
      <li><xsl:value-of select="."/><xsl:text>: </xsl:text>
        <ul>
          <xsl:apply-templates select="$values" mode="values"/>
        </ul>
      </li>
    </xsl:if>
  </xsl:template>

  <xsl:template mode="values" match="*">
    <li>
      <xsl:apply-templates mode="display" select="."/>
    </li>
  </xsl:template>

  <!-- Various node display templates -->
  <xsl:template match="sp:uri" mode="display">
    <a>
      <xsl:attribute name="href"><xsl:value-of select="./text()"/></xsl:attribute>
      <xsl:value-of select="./text()"/>
    </a>
  </xsl:template>

  <xsl:template match="sp:literal" mode="display">
    <xsl:value-of select="./text()"/>
  </xsl:template>

  <xsl:template match="sp:bnode" mode="display">
    <xsl:text>_:</xsl:text><xsl:value-of select="./text()"/>
  </xsl:template>

  <xsl:template match="sp:unbound" mode="display">
    <xsl:text>Unknown</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>
