<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl"
    xmlns:arr="http://www.edginet.org/arr"
    exclude-result-prefixes="arr"
>

<!--

  Given a list of sermon files as an xml document this transformation
  creates an index file.

-->

<xsl:output
    method="xml"
    indent="yes"
/>

<xsl:template match="/">
  <sermons>
    <xsl:for-each select="sermons/sermon">
      <xsl:variable name="file">sermons/<xsl:value-of select="@file"/></xsl:variable>
      <xsl:apply-templates select="document($file)/sermon/info"/>
    </xsl:for-each>
  </sermons>
</xsl:template>

<xsl:template match="info">
  <sermon>

    <xsl:copy-of select="name"/>
    <xsl:copy-of select="date"/>
    <xsl:copy-of select="title"/>
    <xsl:copy-of select="place"/>

    <!-- Store mainrefs for later use -->
    <xsl:variable name="refs-list">
      <xsl:apply-templates select="mainref"/>
      <xsl:apply-templates select="extraref"/>
      <xsl:apply-templates select="/sermon/body//ref[@text]"/>
    </xsl:variable>

    <!-- Now refine the refs list before outputting it -->
    <xsl:choose>
      <xsl:when test="function-available('exsl:node-set')">
        <xsl:apply-templates select="exsl:node-set($refs-list)/ref" mode="refine">
          <!-- Sort refs so that supersets come before their subsets -->
          <xsl:sort select="./start" order="ascending" data-type="number"/>
          <xsl:sort select="./end" order="descending" data-type="number"/>
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="$refs-list/ref" mode="refine">
          <!-- Sort refs so that supersets come before their subsets -->
          <xsl:sort select="./start" order="ascending" data-type="number"/>
          <xsl:sort select="./end" order="descending" data-type="number"/>
        </xsl:apply-templates>
      </xsl:otherwise>
    </xsl:choose>

  </sermon>
</xsl:template>

<xsl:template match="mainref|extraref">

  <ref>

    <xsl:attribute name="class">
      <xsl:choose>
        <xsl:when test="name()='mainref'"><xsl:text>main</xsl:text></xsl:when>
        <xsl:otherwise><xsl:text>extra</xsl:text></xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>

    <xsl:if test="name()='extraref'">
      <xsl:attribute name="num">
        <xsl:value-of select="position()"/>
      </xsl:attribute>
    </xsl:if>

    <text><xsl:copy-of select="node()"/></text>

    <xsl:variable name="start-end">
      <xsl:call-template name="translate">
        <xsl:with-param name="text" select="."/>
      </xsl:call-template>
    </xsl:variable>

    <start><xsl:value-of select="substring-before($start-end,':')"/></start>
    <end><xsl:value-of select="substring-after($start-end,':')"/></end>

  </ref>
</xsl:template>


<xsl:template match="ref[@text]">

  <xsl:variable name="start-end">
    <xsl:call-template name="translate">
      <xsl:with-param name="text" select="@text"/>
    </xsl:call-template>
  </xsl:variable>

  <ref>
    <text><xsl:value-of select="@text"/></text>
    <start><xsl:value-of select="substring-before($start-end,':')"/></start>
    <end><xsl:value-of select="substring-after($start-end,':')"/></end>
    <!-- <name>REF<xsl:value-of select="generate-id(.)"/></name> -->
    <name>REF_<xsl:value-of select="count(preceding::ref)"/></name>
  </ref>

</xsl:template>


<!-- This template cleans up the refs list a bit -->
<xsl:template match="ref" mode="refine">

  <!-- eliminate subsets of the mainref from the list
       and subsets or duplicates of preceding refs.
       Use
           $start=current()/start
           $end=current()/end
       for clarity and efficiency.
  -->
  <xsl:variable name="start" select="start"/>
  <xsl:variable name="end" select="end"/>
  <xsl:if test="not(preceding-sibling::ref[$start>=start and end>=$end])">
      <xsl:copy-of select="."/>
  </xsl:if>

</xsl:template>

<xsl:template name="translate">

  <!-- The passage reference, eg. "2 Timothy 3:16-17" -->
  <xsl:param name="text"/>

  <!-- Strip the reference off the end.  The first char may be numeric -->
  <xsl:variable name="booktmp">
    <xsl:value-of select="substring($text,1,1)"/>
    <xsl:value-of select="translate(substring($text,2), '1234567890:-', '')"/>
  </xsl:variable>

  <!-- The canonical name of the book -->
  <xsl:variable name="booknam" select="normalize-space($booktmp)"/>

  <!-- The reference within the book -->
  <xsl:variable name="bookref" select="substring-after($text,$booktmp)"/>

  <!-- The number of the book: using keys is fast. -->
  <xsl:variable name="booknum">
    <!-- change context to this stylesheet -->
    <xsl:for-each select="document('')">
      <xsl:value-of select="key('book',$booknam)/@n"/>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="s0">
    <xsl:choose>
      <xsl:when test="contains($bookref,'-')">
        <xsl:value-of select="substring-before($bookref,'-')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$bookref"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="e0">
    <xsl:choose>
      <xsl:when test="contains($bookref,'-')">
        <xsl:value-of select="substring-after($bookref,'-')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$bookref"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!--
      Insert chapter number into end ref if necessary
  -->

  <xsl:variable name="s1">
    <xsl:value-of select="$s0"/>
  </xsl:variable>
  <xsl:variable name="e1">
    <xsl:choose>
      <xsl:when test="not(contains($e0,':')) and contains($s0,':')">
        <xsl:value-of select="concat(substring-before($s0,':'),':',$e0)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$e0"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!--
      Detect whole chapters
      Make whole chapters start C:0 and end C:999.
  -->

  <xsl:variable name="s2">
    <xsl:choose>
      <xsl:when test="not(contains($s1,':'))">
        <xsl:value-of select="concat($s1,':0')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$s1"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="e2">
    <xsl:choose>
      <xsl:when test="not(contains($e1,':'))">
        <xsl:value-of select="concat($e1,':999')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$e1"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!--
      start and end refs should now be in canonical form, C:V.
      Now translate to numerical form.
  -->

  <xsl:variable name="start">
    <xsl:call-template name="trans">
      <xsl:with-param name="ref" select="$s2"/>
      <xsl:with-param name="booknum" select="$booknum"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:variable name="end">
    <xsl:call-template name="trans">
      <xsl:with-param name="ref" select="$e2"/>
      <xsl:with-param name="booknum" select="$booknum"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:value-of select="concat($start,':',$end)"/>

</xsl:template>

<xsl:template name="trans">
  
  <xsl:param name="ref"/>
  <xsl:param name="booknum"/>

  <xsl:variable name="cs" select="substring-before($ref,':')"/>
  <xsl:variable name="vs" select="substring-after($ref,':')"/>
  <xsl:value-of select="$booknum"/>
  <xsl:value-of select="substring(concat('00',$cs),string-length($cs))"/>
  <xsl:value-of select="substring(concat('00',$vs),string-length($vs))"/>

</xsl:template>

<arr:books>
  <arr:book n="01">Genesis</arr:book>
  <arr:book n="02">Exodus</arr:book>
  <arr:book n="03">Leviticus</arr:book>
  <arr:book n="04">Numbers</arr:book>
  <arr:book n="05">Deuteronomy</arr:book>
  <arr:book n="06">Joshua</arr:book>
  <arr:book n="07">Judges</arr:book>
  <arr:book n="08">Ruth</arr:book>
  <arr:book n="09">1 Samuel</arr:book>
  <arr:book n="10">2 Samuel</arr:book>
  <arr:book n="11">1 Kings</arr:book>
  <arr:book n="12">2 Kings</arr:book>
  <arr:book n="13">1 Chronicles</arr:book>
  <arr:book n="14">2 Chronicles</arr:book>
  <arr:book n="15">Ezra</arr:book>
  <arr:book n="16">Nehemiah</arr:book>
  <arr:book n="17">Esther</arr:book>
  <arr:book n="18">Job</arr:book>
  <arr:book n="19">Psalm</arr:book>
  <arr:book n="20">Proverbs</arr:book>
  <arr:book n="21">Ecclesiastes</arr:book>
  <arr:book n="22">Song of Solomon</arr:book>
  <arr:book n="23">Isaiah</arr:book>
  <arr:book n="24">Jeremiah</arr:book>
  <arr:book n="25">Lamentations</arr:book>
  <arr:book n="26">Ezekiel</arr:book>
  <arr:book n="27">Daniel</arr:book>
  <arr:book n="28">Hosea</arr:book>
  <arr:book n="29">Joel</arr:book>
  <arr:book n="30">Amos</arr:book>
  <arr:book n="31">Obadiah</arr:book>
  <arr:book n="32">Jonah</arr:book>
  <arr:book n="33">Micah</arr:book>
  <arr:book n="34">Nahum</arr:book>
  <arr:book n="35">Habakkuk</arr:book>
  <arr:book n="36">Zephaniah</arr:book>
  <arr:book n="37">Haggai</arr:book>
  <arr:book n="38">Zechariah</arr:book>
  <arr:book n="39">Malachi</arr:book>
  <arr:book n="40">Matthew</arr:book>
  <arr:book n="41">Mark</arr:book>
  <arr:book n="42">Luke</arr:book>
  <arr:book n="43">John</arr:book>
  <arr:book n="44">Acts</arr:book>
  <arr:book n="45">Romans</arr:book>
  <arr:book n="46">1 Corinthians</arr:book>
  <arr:book n="47">2 Corinthians</arr:book>
  <arr:book n="48">Galatians</arr:book>
  <arr:book n="49">Ephesians</arr:book>
  <arr:book n="50">Philippians</arr:book>
  <arr:book n="51">Colossians</arr:book>
  <arr:book n="52">1 Thessalonians</arr:book>
  <arr:book n="53">2 Thessalonians</arr:book>
  <arr:book n="54">1 Timothy</arr:book>
  <arr:book n="55">2 Timothy</arr:book>
  <arr:book n="56">Titus</arr:book>
  <arr:book n="57">Philemon</arr:book>
  <arr:book n="58">Hebrews</arr:book>
  <arr:book n="59">James</arr:book>
  <arr:book n="60">1 Peter</arr:book>
  <arr:book n="61">2 Peter</arr:book>
  <arr:book n="62">1 John</arr:book>
  <arr:book n="63">2 John</arr:book>
  <arr:book n="64">3 John</arr:book>
  <arr:book n="65">Jude</arr:book>
  <arr:book n="66">Revelation</arr:book>
</arr:books>

<!-- Using keys is an efficient way to access the book data -->
<xsl:key name="book" match="arr:book" use="."/>

</xsl:stylesheet>