<?xml version="1.0"?>

<xsl:stylesheet
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
     xmlns:fox="http://xml.apache.org/fop/extensions"
      xmlns:svg="http://www.w3.org/2000/svg"
     xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:output indent="yes"/>

<xsl:variable name="tableWidth" select="number(15)"/>

<xsl:template match ="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

  <fo:layout-master-set>
    <fo:simple-page-master master-name="simple"
                  page-height="29.7cm" 
                  page-width="21cm"
                  margin-top="1cm" 
                  margin-bottom="2cm" 
                  margin-left="2.5cm" 
                  margin-right="2.5cm">
      <fo:region-body margin-top="3cm"/>
      <fo:region-before extent="3cm"/>
      <fo:region-after extent="1.5cm"/>
    </fo:simple-page-master>
  </fo:layout-master-set>

<!-- beginning of the PDF outline extensions --> 

  <xsl:for-each select="//h1 | //h2">
    <xsl:variable name="id"><xsl:value-of select="generate-id()"/></xsl:variable>
    <fox:outline internal-destination="{$id}">
      <fox:label><xsl:value-of select="normalize-space(.)"/></fox:label>
    </fox:outline>
  </xsl:for-each>

    <fo:page-sequence master-name="simple">

			<fo:static-content flow-name="xsl-region-before">
				<fo:block text-align="end" 
							font-size="10pt" 
							font-family="serif" 
							line-height="14pt" >
					<xsl:value-of select="/*/head/title"/> - p. <fo:page-number/>
				</fo:block>
			</fo:static-content> 

			<fo:flow flow-name="xsl-region-body">
  			  <fo:block>
  			  			    <xsl:apply-templates/> 
			  </fo:block>
			</fo:flow>

		</fo:page-sequence>
	</fo:root>
</xsl:template>


<xsl:template match="html">
  <xsl:apply-templates select="body"/>
</xsl:template>


<!-- don't output head -->
<xsl:template match ="head"/>


<!-- body -->
<xsl:template match ="body">

<!-- defines text title -->
   <fo:block font-size="18pt" 
            font-family="sans-serif" 
            line-height="24pt"
            space-after.optimum="15pt"
            background-color="#7777ff"
            color="white"
            text-align="center"
            padding-top="3pt">
      <xsl:value-of select="//head/title"/>
   </fo:block>

<!-- generates table of contents and puts it into a table -->

       <xsl:if test="//h3 | //h2 | //h1">
         <fo:block font-size="10pt" 
                  font-family="sans-serif" 
                  line-height="10pt"
                  space-after.optimum="3pt"
                  font-weight="bold"
                  start-indent="15pt">
            Content
         </fo:block>

         <fo:table>
            <fo:table-column column-width="1cm"/>
            <fo:table-column column-width="15cm"/>
            <fo:table-column column-width="1cm"/>
            <fo:table-body font-size="10pt" 
                           font-family="sans-serif">
      
            <xsl:for-each select=".//h3 | .//h2 | ..//h1">
               <fo:table-row line-height="12pt">
                  <fo:table-cell>
                     <fo:block text-align="end" >
<!-- doesn't yet work
                        <xsl:if test="name()='h3'">
                          <xsl:number value="position()" format="I.1.i"/>) 
                        </xsl:if>
                        <xsl:if test="name='h2'">
                          <xsl:number value="position()" format="I.1"/>) 
                        </xsl:if>
-->
                          <xsl:number value="position()" format="1"/>) 
                     </fo:block>
                  </fo:table-cell>
                  <fo:table-cell>
<xsl:variable name="fontStyle">
  <xsl:if test="name()='div'">italic</xsl:if>
  <xsl:if test="not(name()='div')">normal</xsl:if>
</xsl:variable>
<xsl:variable name="linkContent">
                        <xsl:if test="name()='div'">[</xsl:if>
                        <xsl:value-of select="."/>
                        <xsl:if test="name()='div'">]</xsl:if>
</xsl:variable>
                     <fo:block  text-align="start" font-style="{$fontStyle}">
                       <xsl:if test="@id">
                        <fo:basic-link color="blue" internal-destination="{@id}">
                        <xsl:value-of select="$linkContent"/>
                      </fo:basic-link>
                       </xsl:if>
                       <xsl:if test="not(@id)"><xsl:value-of select="$linkContent"/></xsl:if>
                    </fo:block>
                  </fo:table-cell>
                  <fo:table-cell>
                   <fo:block text-align="end">
                     <xsl:if test="@id"><fo:page-number-citation ref-id="{@id}"/></xsl:if>
                    </fo:block>
                  </fo:table-cell>
               </fo:table-row>
            </xsl:for-each>
            </fo:table-body>
         </fo:table>
       </xsl:if>
       
<!-- processing of the rest -->
    <xsl:apply-templates/>

</xsl:template> 
<!-- end body -->

<!-- IMG -->
<!-- you must include a width and height in pixels, divided by 60 to form cm - 
I'm assuming the XML is designed for a 800 pixel width screen and the 
FO for A4 paper, aligning images is fiddly -->
<!--
<xsl:template match="img | IMG">
  <fo:display-graphic href="file:{@src}" width="20"/>
</xsl:template>
-->

  <!-- cite  -->
  
  <xsl:template match="//cite">
   <fo:inline start-indent="1.7cm"
   	font-size="10pt"
	font-style="italic">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>
  
   
    <!-- cite  --> 

  <!-- sup  --> 
<xsl:template match="//sup/b | sup">
   <fo:inline
   	font-size="8pt"
	font-weight="bold"
	vertical-align="super">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

  <!-- sup  --> 
<xsl:template match="img">
  <fo:block>
    <fo:block text-align="center">
      <fo:external-graphic src="file:{@src}"/>
    </fo:block>
    <xsl:if test="@alt">
      <fo:block space-before="3pt" text-align="center"
		start-indent="10mm" 
		end-indent="10mm">
        <xsl:value-of select="@alt"/>
      </fo:block>
    </xsl:if>
  </fo:block>
</xsl:template>

<!--     <embed src="figure1.svg" width="90%" />-->
<xsl:template match="embed[@src]">
  <fo:block>
    <fo:block text-align="center">
      <fo:external-graphic src="file:{@src}"/>
    </fo:block>
    <xsl:if test="@alt">
      <fo:block space-before="3pt" text-align="center"
		start-indent="10mm" 
		end-indent="10mm">
        <xsl:value-of select="@alt"/>
      </fo:block>
    </xsl:if>
  </fo:block>
</xsl:template>

<!--     <svg ...>-->
<xsl:template match="svg">
    <fo:instream-foreign-object>
      <xsl:copy-of select="."/>
    </fo:instream-foreign-object>
</xsl:template>




<!-- p  -->
<xsl:template match ="p">
   <fo:block start-indent="0.7cm"
            space-before.optimum="12pt"
            font-family="serif"> 
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

<!--page_break -->
<xsl:template match ="page_break">
<fo:block break-before="page"> 
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>


<!-- h1 -->
<xsl:template match ="h1">
    <xsl:variable name="id"><xsl:value-of select="generate-id()"/></xsl:variable>

   <fo:block 
   	font-size="16pt"
   	font-weight="bold"
   	id = "{$id}"
            space-before.optimum="14pt"> 
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

<!-- h2  -->
<xsl:template match ="h2">
    <xsl:variable name="id"><xsl:value-of select="generate-id()"/></xsl:variable>
   <fo:block start-indent="0.7cm"
   	font-size="14pt"
   	font-weight="bold"
   	id = "{$id}"
            space-before.optimum="12pt"> 
        <xsl:if test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:if>
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

<!-- h3  -->
<xsl:template match ="h3">
   <fo:block start-indent="0.7cm"
   	font-size="12pt"
   	font-weight="bold"
            space-before.optimum="12pt"> 
        <xsl:if test="@id"><xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute></xsl:if>
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

<!-- i/emph  -->
<xsl:template match ="i | emph | em">
   <fo:inline
   	font-style="italic">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

<!-- b/strong  -->
<xsl:template match ="b | strong">
   <fo:inline
   	font-weight="bold">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

<!-- tt/verb  -->
<xsl:template match ="verb | tt ">
   <fo:inline
   	font-style="normal"
   	font-weight="bold"
        background-color="#ffff00"
        color="#000077"
   	font-family="monospace">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

<!-- code fragments, marked by code -->
<xsl:template match ="code">
   <fo:inline font-size="10pt" 
     	    font-style="normal"
            font-family="monospace" 
            color="#0000ff">
      <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

<!-- dl -->
<xsl:template match ="dl">
   <fo:block> 
      <xsl:apply-templates/>
   </fo:block> 
</xsl:template>

<!-- dt -->
<xsl:template match ="dt">
     <fo:block start-indent="0.7cm"
            space-before.optimum="12pt"
            font-family="serif"> 
      <xsl:apply-templates/>
   </fo:block> 
</xsl:template>

<!-- hr -->
<xsl:template match ="hr">
   <fo:block> 
   <fo:leader rule-thickness="5pt"/>
   </fo:block> 
</xsl:template>

<!-- list -->
<xsl:template match ="ul | ol">
   <fo:list-block start-indent="1cm"
                  provisional-distance-between-starts="12pt"
                  font-family="serif">
      <xsl:apply-templates/>
   </fo:list-block>
</xsl:template>



<!-- list items  -->
<xsl:template match ="li">
   <fo:list-item >
      <fo:list-item-label end-indent="label-end()">
	  <fo:block><fo:inline font-family="Symbol">&#183; </fo:inline></fo:block>
	  </fo:list-item-label>
      <fo:list-item-body start-indent="body-start()">
         <fo:block> 
            <xsl:apply-templates/>
         </fo:block>
      </fo:list-item-body>
   </fo:list-item>
</xsl:template>


<!-- code fragments,  pre[@class='code'] or just pre -->
<xsl:template match ="pre">
  <xsl:variable name="color">
    #77ffff
<!--
    <xsl:choose>
      <xsl:when test="@class='code'">#77ffff</xsl:when>
      <xsl:otherwise>#ffbbff</xsl:otherwise>
    </xsl:choose>
-->
  </xsl:variable>
   <fo:block font-size="10pt" 
            font-family="monospace" 
            line-height="12pt"
	    start-indent="0.7cm"
            background-color="{$color}"
            white-space-collapse="false"
            space-before.optimum="7pt"
            space-after.optimum="7pt">
      <xsl:apply-templates/>
   </fo:block>
</xsl:template>

<!-- table -->
<xsl:template match ="table">
  <fo:table
   start-indent="0.7cm">
    <xsl:variable name="tdcols" select="(tr[td])[1]/td"/>
    <xsl:variable name="tdwidths" select="(tr[td])[1]/td[@width]"/>
    <xsl:variable name="cols" select="count($tdcols)"/>
<!-- this appalling stuff below uses width attributes of columns to
	calculate column widths. Don't even ask! Possibly I can
	do better in the future
-->
    <xsl:variable name="width">
      <xsl:choose>
<!-- within a parent table -->
        <xsl:when test="ancestor::tr">
          <xsl:value-of select="($tableWidth div $cols) div count(ancestor::tr/td)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
<!-- are widths given? defer till later -->
            <xsl:when test="$tdwidths">
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$tableWidth div $cols"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="totalTdWidths">
      <xsl:call-template name="getTotalWidth">
        <xsl:with-param name="tdList" select="(tr[td[@width]])[1]/td"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:for-each select="$tdcols">
      <xsl:variable name="w">
        <xsl:choose>
<!-- are widths given? -->
          <xsl:when test="count($tdwidths) > 0 and $totalTdWidths > 0">
            <xsl:value-of select="($tableWidth * number(substring-before(concat(./@width,'%'),'%'))) div $totalTdWidths"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:choose>
              <xsl:when test="normalize-space($width) = ''">
                <xsl:value-of select="$tableWidth div $cols"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="$width"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>
      
      <fo:table-column>
         <xsl:attribute name="column-width"><xsl:value-of select="$w"/>cm</xsl:attribute>
      </fo:table-column>
    </xsl:for-each>
    <fo:table-body>
      <xsl:apply-templates/>      
    </fo:table-body>
  </fo:table>
</xsl:template>

<!-- table row -->
<xsl:template match ="tr">
  <fo:table-row
       border-top-style="dashed"
       border-top-color="blue"
       border-top-width="0.5pt"
       border-bottom-style="dashed"
       border-bottom-color="blue"
       border-bottom-width="0.5pt"
       border-left-style="dashed"
       border-left-color="blue"
       border-left-width="0.5pt"
       border-right-style="dashed"
       border-right-color="blue"
       border-right-width="0.5pt"
    space-before.optimum="1.5pt"
    padding-before="5pt"
    space-after.optimum="1.5pt"
    padding-after="1.5pt"
    line-height="12pt">
    <xsl:apply-templates/>      
  </fo:table-row>
</xsl:template>

<!-- table cell -->
<xsl:template match ="td">
  <fo:table-cell>
    <fo:block
    padding-top="1.5pt"
    padding-bottom="1.5pt"
>
      <xsl:apply-templates/>      
    </fo:block>
  </fo:table-cell>
</xsl:template>

<!-- table header cell -->
<xsl:template match ="th">
  <fo:table-cell>
    <fo:block font-style="italic" font-weight="bold">
      <xsl:apply-templates/>      
    </fo:block>
  </fo:table-cell>
</xsl:template>

<!-- link -->
<xsl:template match ="link[@href] | a[@href]">
  <xsl:variable name="href1"><xsl:value-of select="@href"/></xsl:variable>
  <xsl:variable name="destination">
    <xsl:if test="contains(@href, '.')">external-destination</xsl:if>
    <xsl:if test="not(contains(@href, '.'))">internal-destination</xsl:if>
  </xsl:variable>
  <fo:inline font-style="italic"
  	color="blue" font-family="serif">
	<fo:basic-link>
	  <xsl:attribute name="{$destination}"><xsl:value-of select="$href1"/></xsl:attribute>
	  <xsl:apply-templates/></fo:basic-link>
  </fo:inline>
</xsl:template>

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

<xsl:template name="getTotalWidth">
  <xsl:param name="tdList"/>
  <xsl:choose>
    <xsl:when test="$tdList">
      <xsl:variable name="total">
        <xsl:call-template name="getTotalWidth">
          <xsl:with-param name="tdList" select="$tdList[position()!=1]"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:value-of select="number(substring-before(concat($tdList[1]/@width,'%'),'%')) + $total"/>
    </xsl:when>
    <xsl:otherwise>0</xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="molecule">
  <fo:instream-foreign-object>
    <svg:svg width="500" height="500">
      <xsl:apply-templates select="*/bond"/>
      <xsl:apply-templates select="*/atom"/>
    </svg:svg>
  </fo:instream-foreign-object>
</xsl:template>

<xsl:template match="atom">
  <xsl:variable name="x2"><xsl:call-template name="getXCoord"><xsl:with-param name="atom" select="."/></xsl:call-template></xsl:variable>
  <xsl:variable name="y2"><xsl:call-template name="getYCoord"><xsl:with-param name="atom" select="."/></xsl:call-template></xsl:variable>
  <xsl:variable name="x2t"><xsl:value-of select="($x2)-3"/></xsl:variable>
  <xsl:variable name="y2t"><xsl:value-of select="$y2+3"/></xsl:variable>
  <xsl:variable name="el"><xsl:value-of select="*[@*='elementType']"/></xsl:variable>
  <!--<xsl:variable name="hy"><xsl:value-of select="*[@*='hydrogenCount']"/></xsl:variable>-->
  <xsl:variable name="color">
    <xsl:choose>
      <xsl:when test="$el='O'">red</xsl:when>
      <xsl:when test="$el='N'">blue</xsl:when>
      <xsl:otherwise>black</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>    
<!--  <svg:circle cx="{$x2}" cy="{$y2}" r="4" style="fill:blue; stroke-width:0.5 "/>-->

  <svg:text style="stroke:{$color}; fill: {$color}; font-size: 12pt; stroke-width: 0.5" x="{$x2t}" y="{$y2t}">
  		<xsl:value-of select="@id"/>		
  </svg:text>
</xsl:template>

<xsl:key name="atoms" match="atom" use="@id"/>

<xsl:template match="bond">
  <xsl:variable name="ar1"><xsl:value-of select="string[@builtin='atomRef'][1]"/></xsl:variable>
  <xsl:variable name="ar2"><xsl:value-of select="string[@builtin='atomRef'][2]"/></xsl:variable>
  <xsl:variable name="order"><xsl:value-of select="string[@builtin='order']"/></xsl:variable>
  <xsl:variable name="a1" select="key('atoms', $ar1)"/>
  <xsl:variable name="a2" select="key('atoms', $ar2)"/>
  <xsl:variable name="aa1" select="$a1[1]"/>
  <xsl:variable name="aa2" select="$a2[1]"/>
  <xsl:call-template name="plotBond">
    <xsl:with-param name="a1" select="$aa1"/>
    <xsl:with-param name="a2" select="$aa2"/>
    <xsl:with-param name="order" select="$order"/>
  </xsl:call-template>

</xsl:template>

<xsl:template name="plotBond">
  <xsl:param name="a1"/>
  <xsl:param name="a2"/>
  <xsl:param name="order"/>
  <xsl:variable name="x1"><xsl:call-template name="getXCoord"><xsl:with-param name="atom" select="$a1"/></xsl:call-template></xsl:variable>
  <xsl:variable name="y1"><xsl:call-template name="getYCoord"><xsl:with-param name="atom" select="$a1"/></xsl:call-template></xsl:variable>
  <xsl:variable name="x2"><xsl:call-template name="getXCoord"><xsl:with-param name="atom" select="$a2"/></xsl:call-template></xsl:variable>
  <xsl:variable name="y2"><xsl:call-template name="getYCoord"><xsl:with-param name="atom" select="$a2"/></xsl:call-template></xsl:variable>
  <xsl:choose>
    <xsl:when test="$order='S' or $order='1'">
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:red; stroke-width:1 "/>
    </xsl:when>
    <xsl:when test="$order='D' or $order='2'">
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:red; stroke-width:3 "/>
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:white; stroke-width:1 "/>
    </xsl:when>
    <xsl:when test="$order='T' or $order='3'">
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:red; stroke-width:5 "/>
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:white; stroke-width:3 "/>
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:red; stroke-width:1 "/>
    </xsl:when>
    <xsl:otherwise>
      <svg:line x1="{$x1}" x2="{$x2}" y1="{$y1}" y2="{$y2}" style="stroke:red; stroke-width:1 "/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<xsl:template name="getXCoord">
  <xsl:param name="atom"/>
  <xsl:value-of select="40*$atom/float[@builtin='x2']-200"/>
</xsl:template>

<xsl:template name="getYCoord">
  <xsl:param name="atom"/>
  <xsl:value-of select="40*$atom/float[@builtin='y2']+50"/>
</xsl:template>

 </xsl:stylesheet>

