<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
		xmlns:doc="http://www.o-xml.org/extensions/document/"
		xmlns:o="http://www.o-xml.org/lang/">

  <doc:p>
    stylesheet that produces cross-referenced HTML from an
    o:XML type definition with inline docs.
  </doc:p>

  <xsl:output method="html" indent="no" encoding="UTF-8"/>

  <xsl:template match="/">
    <html>
      <head>
        <title>o:XML <xsl:value-of select="o:type/@name"/> Type Interface</title>
        <link href="complete.css" rel="stylesheet" type="text/css"/>
            <style>
              BODY {font:x-small 'Verdana'; margin-right:1.5em}
              .c  {cursor:hand}
              .b  {color:navy; font-family:'Courier New'; font-weight:bold; text-decoration:none}
              .e  {margin-left:1em; text-indent:-1em; margin-right:1em}
              .k  {margin-left:1em; text-indent:-1em; margin-right:1em}
              .t  {color:#888888}
              .xt {color:#053d91}
              .ns {color:navy}
              .m  {color:darkblue}
              .tx {font-weight:bold}
              .db {text-indent:0px; margin-left:1em; margin-top:0px; margin-bottom:0px; padding-left:.3em; border-left:1px solid #CCCCCC; font:small Courier}
              .di {font:small Courier}
              .d  {color:blue}
              .pi {color:blue}
              .cb {text-indent:0px; margin-left:1em; margin-top:0px; margin-bottom:0px; padding-left:.3em; font:small Courier; color:#888888}
              .ci {font:small Courier; color:#888888}

              .dt {color:green}
              PRE {margin:0px; display:inline}
              .type {border:solid #888888 1px; margin-bottom:10px; margin-top:10px; padding:8px}
              .functions {width:100%; padding:0}
              .function {width:100%; border:solid 1px #888888; padding: 2px}
              .example {}
           </style>
      </head>
      <body marginwidth="40%">
        <xsl:apply-templates select="//o:type"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="o:type">
    <div class="type">
    <table border="0" width="100%" cellpadding="0" cellspacing="0">
      <!-- type name and documentation -->
      <tr><td><h3>Type <xsl:value-of select="@name"/></h3></td></tr>
      <tr><td><xsl:apply-templates select="doc:*"/></td></tr>
      <!-- parent types -->
      <xsl:apply-templates select="o:parent"/>
    </table>

    <!-- type constructors -->
    <table class="functions">
      <thead>
        <tr><th bgcolor="lightgrey">Constructors:</th></tr>
      </thead>
      <tbody>
	<xsl:apply-templates select="o:function[@name = current()/@name]"/>
      </tbody>
    </table>
    <!-- type functions declared by this type -->
    <table class="functions">
      <thead>
        <tr><th bgcolor="lightgrey">Functions:</th></tr>
      </thead>
      <tbody>
        <xsl:apply-templates select="o:function[@name != current()/@name]">
          <xsl:sort select="@name"/>
        </xsl:apply-templates>
      </tbody>
    </table>
    <!-- inherited functions -->
    <xsl:apply-templates select="o:parent" mode="inherited-functions"/>
    </div>
  </xsl:template>

  <xsl:template match="o:parent" mode="inherited-functions">
    <xsl:variable name="xref">
      <xsl:call-template name="xref">
	<xsl:with-param name="type" select="@name"/>
      </xsl:call-template>
    </xsl:variable>
    <table class="functions">
      <thead>
        <tr><th bgcolor="lightgrey">Functions inherited from <a href="../{$xref}.html"><xsl:value-of select="@name"/></a>:</th></tr>
      </thead>
      <tbody>
        <xsl:apply-templates 
          select="document(concat('../src/lib/', $xref, '.oml'))//o:type[1]/o:function[@name != ancestor::o:type/@name]"
          mode="inherited-functions">
          <xsl:sort select="@name"/>
        </xsl:apply-templates>
      </tbody>
    </table>
    <br/>
    <xsl:apply-templates select="document(concat('../src/lib/', $xref, '.oml'))//o:type[1]/o:parent"
      mode="inherited-functions"/>
  </xsl:template>

  <xsl:template match="o:function" mode="inherited-functions">
    <xsl:apply-templates select="."/>
  </xsl:template>

  <xsl:template match="o:parent">
    <xsl:variable name="xref">
      <xsl:call-template name="xref">
	<xsl:with-param name="type" select="@name"/>
      </xsl:call-template>
    </xsl:variable>
    <tr>
      <td><i>extends </i><a href="../{$xref}.html"><xsl:value-of select="@name"/></a></td>
    </tr>
  </xsl:template>

  <xsl:template match="o:function[@access = 'private']"/>
  <xsl:template match="o:function[@access = 'protected']"/>

  <xsl:template match="o:function">
    <tr><td><table class="function">
      <tr><td>
        <b><xsl:value-of select="@name"/></b>
        <xsl:text>(</xsl:text>
        <xsl:apply-templates select="o:param"/>
        <xsl:text>)</xsl:text>
      </td></tr>
      <xsl:apply-templates select="doc:*"/>
    </table></td></tr>
  </xsl:template>

  <xsl:template match="o:param">
    <xsl:variable name="type">
      <xsl:value-of select="@type"/>
      <xsl:if test="not(@type)">Node</xsl:if>      
    </xsl:variable>
    <xsl:variable name="xref">
      <xsl:call-template name="xref">
	<xsl:with-param name="type" select="@type"/>
      </xsl:call-template>
    </xsl:variable>
    <a href="../{$xref}.html"><xsl:value-of select="$type"/></a>
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name"/>
    <xsl:if test="following-sibling::o:param">, </xsl:if>
  </xsl:template>

  <xsl:template match="o:param[@type = ancestor::o:type/@name]">
    <xsl:value-of select="@type"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="@name"/>
    <xsl:if test="following-sibling::o:param">, </xsl:if>
  </xsl:template>

  <xsl:template match="o:param" mode="name">
    <xsl:text>Node </xsl:text><xsl:value-of select="@name"/>
  </xsl:template>

  <xsl:template match="o:param[@type]" mode="name">
    <xsl:value-of select="@type"/>
    <xsl:text> </xsl:text><xsl:value-of select="@name"/>
  </xsl:template>

  <xsl:template match="doc:p">
    <tr><td><xsl:apply-templates mode="inline"/></td></tr>
  </xsl:template>

  <xsl:template match="doc:return">
    <tr><td><b>Returns: </b><xsl:apply-templates mode="inline"/></td></tr>
  </xsl:template>

  <xsl:template match="doc:param">
    <tr><td><b>Parameter <tt>
      <xsl:value-of select="@name"/>
      <xsl:if test="not(@name)">
        <xsl:value-of select="ancestor::o:*/o:param/@name"/>
      </xsl:if>
    </tt>: </b>
    <xsl:apply-templates mode="inline"/></td></tr>
    <!--      <xsl:text>Parameter </xsl:text>
      <xsl:apply-templates select="../o:param[@name=current()/@name]" mode="name"/>
-->
  </xsl:template>

  <xsl:template match="doc:same">
    <tr><td><b>Same as: </b><xsl:apply-templates mode="inline"/></td></tr>
  </xsl:template>

  <xsl:template match="doc:see">
    <tr><td><b>See Also: </b><xsl:apply-templates mode="inline"/></td></tr>
  </xsl:template>

  <xsl:template match="doc:link[@url]" mode="inline">
    <a href="{@url}"><xsl:apply-templates mode="inline"/></a>
  </xsl:template>

  <xsl:template match="doc:link[@type]" mode="inline">
    <xsl:variable name="xref">
      <xsl:call-template name="xref">
	<xsl:with-param name="type" select="@type"/>
      </xsl:call-template>
    </xsl:variable>
    <a href="../{$xref}.html">
      <xsl:apply-templates mode="inline"/>
      <xsl:if test="not(./node())"><xsl:value-of select="@type"/></xsl:if>
    </a>
  </xsl:template>

  <xsl:template match="doc:param" mode="inline">
    <b><tt>
    <xsl:value-of select="ancestor::o:*/o:param/@name"/>
    </tt></b>
  </xsl:template>

  <xsl:template match="doc:param[@name]" mode="inline">
    <b><tt>
    <xsl:value-of select="@name"/>
    </tt></b>
  </xsl:template>

  <xsl:template match="doc:type" mode="inline">
    <b><tt>
    <xsl:value-of select="ancestor::o:type/@name"/>
    </tt></b>
  </xsl:template>

  <xsl:template match="doc:type[@name]" mode="inline">
    <xsl:variable name="xref">
      <xsl:call-template name="xref">
	<xsl:with-param name="type" select="@name"/>
      </xsl:call-template>
    </xsl:variable>
    <b><tt>
    <a href="../{$xref}.html"><xsl:value-of select="@name"/></a>
    </tt></b>
  </xsl:template>

  <xsl:template name="xref">
    <xsl:param name="type"/>
    <xsl:choose>
      <xsl:when test="contains($type, ':')">
	<xsl:variable name="prefix" select="substring-before($type, ':')"/>
	<xsl:variable name="path" select="substring-after(//namespace::*[name(.) = $prefix], '/lib/')"/>
	<xsl:value-of select="$path"/>
	<xsl:value-of select="substring-after($type, ':')"/>
      </xsl:when>
      <xsl:when test="$type">
	<xsl:value-of select="."/>
      </xsl:when>
      <xsl:otherwise>Node</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="doc:example">
    <div class="example">
      <tr><td><b>Example:</b></td></tr>
      <tr><td><xsl:apply-templates mode="example"/></td></tr>
    </div>
  </xsl:template>

  <xsl:template match="text()" mode="example">
      <SPAN class="tx">
        <xsl:value-of select="."/>
      </SPAN>
  </xsl:template>

  <xsl:template match="o:*" mode="name">
    <SPAN class="xt">
      <xsl:value-of select="name(.)"/>
    </SPAN>    
  </xsl:template>

  <xsl:template match="*" mode="name">
    <SPAN class="t">
      <xsl:value-of select="name(.)"/>
    </SPAN>    
  </xsl:template>

  <xsl:template match="*" mode="example">
    <DIV class="e">
      <DIV STYLE="margin-left:1em;text-indent:-2em">
        <SPAN class="m">&lt;</SPAN>
        <xsl:apply-templates select="." mode="name"/>
        <xsl:apply-templates select="@*" mode="example"/>
        <SPAN class="m">/></SPAN>
      </DIV>
    </DIV>
  </xsl:template>

  <xsl:template match="*[node()]" mode="example">
    <DIV class="e">
      <DIV class="c">
        <SPAN class="m">&lt;</SPAN>
        <xsl:apply-templates select="." mode="name"/>
        <xsl:apply-templates select="@*" mode="example"/>
        <SPAN class="m">&gt;</SPAN>
      </DIV>
        <xsl:apply-templates mode="example"/>
        <DIV>
          <SPAN class="m">
            <xsl:text>&lt;/</xsl:text>
          </SPAN>
          <xsl:apply-templates select="." mode="name"/>
          <SPAN class="m">
            <xsl:text>&gt;</xsl:text>
          </SPAN>
        </DIV>
    </DIV>
  </xsl:template>

  <xsl:template match="@*" mode="example">
    <SPAN class="x">
      <xsl:text> </xsl:text>
      <xsl:value-of select="name(.)"/>
    </SPAN>
    <SPAN class="m">="</SPAN>
    <B><xsl:value-of select="."/></B>
    <SPAN class="m">"</SPAN>
  </xsl:template>

  <xsl:template match="doc:*">
    <xsl:message>
      warning - unknown doc element: <xsl:value-of select="name(.)"/>
    </xsl:message>
    <tr><td>
      <font color="red"><xsl:value-of select="name(.)"/></font>
      <xsl:apply-templates mode="inline"/>
      <font color="red"><xsl:value-of select="name(.)"/></font>
    </td></tr>
  </xsl:template>

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

</xsl:stylesheet>
<!--
    ObjectBox - o:XML compiler and interpretor
    for more information see http://www.o-xml.org/objectbox
    Copyright (C) 2002/2003 Martin Klang, Alpha Plus Technology Ltd
    email: martin at hack.org

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-->
