<?xml version="1.0" encoding="utf-8"?>
<xs:stylesheet xmlns:xs="http://www.w3.org/1999/XSL/Transform" version="1.0"
               xmlns="http://www.w3.org/1999/xhtml">
<xs:output method="xml" indent="yes" encoding="UTF-8" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>

<!-- ================ 
font family 
================= -->
<xs:variable name="tsEspy">font-family: Espy Sans, Geneva, Arial, sans-serif;</xs:variable>
<xs:variable name="tsFancy">font-family: New York, Times, serif;</xs:variable>
<xs:variable name="tsSimple">font-family: Lucida Grande, Geneva, Arial, sans-serif;</xs:variable>
<xs:variable name="tsHWFont">font-family: Apple Casual, Sand, sans-serif;</xs:variable>
<xs:variable name="defaultFamily"><xs:copy-of select="$tsEspy"/></xs:variable>

<!-- ================ 
font size default 
================= -->
<xs:variable name="defaultSize">12</xs:variable>

<!-- ================ 
font faces 
================= -->
<xs:variable name="tsBold">font-weight: bold;</xs:variable>
<xs:variable name="tsItalic">font-style: italic;</xs:variable>
<xs:variable name="tsUnderline">text-decoration: underline;</xs:variable>
<xs:variable name="tsOutline">color: #6F0; background-color: #060;</xs:variable>
<xs:variable name="tsSuperScript">font-size: x-small; vertical-align: super;</xs:variable>
<xs:variable name="tsSubScript">font-size: x-small; vertical-align: sub;</xs:variable>

<!-- ================ 
html template 
================= -->
<xs:template match="/">
<html><head>
<title><xs:apply-templates select="//slot[@symbol='title']/string"/></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
body {margin: 0; background-color: #6F0; background-image: url(lines.gif);}
</style>
</head>
<body>
<xs:apply-templates select="//frame/slot[@symbol='text']"/>
</body>
</html>
</xs:template>

<!-- ================ 
get title 
================= -->
<xs:template match="slot[@symbol='title']/string/value">
<xs:value-of select="text()"/>
</xs:template>

<!-- ================ 
determine position & style encoding
================= -->
<xs:template match="frame/slot[@symbol='text']">
<xs:for-each select="../slot[@symbol='text']/string/value">
<xs:element name="div">
<xs:attribute name="style">position: absolute; overflow: display; top: <xs:value-of select="../../../slot[@symbol='viewBounds']/frame/slot[@symbol='top']/int"/>px; left: <xs:value-of select="../../../slot[@symbol='viewBounds']/frame/slot[@symbol='left']/int"/>px; z-index: 1;</xs:attribute>
<xs:apply-templates select="ancestor::node()/slot[@symbol='styles']"/>
<xs:apply-templates select="ancestor::node()/slot[@symbol='viewFont']"/>
</xs:element>
</xs:for-each>
</xs:template>

<!-- ================ 
deal with styles in viewFont slots
================= -->
<xs:template match="slot[@symbol='viewFont']/int">
<xs:variable name="x" select="../int/text()"/>
<xs:call-template name="process-text">
  <xs:with-param name="val"><xs:value-of select="$x"/></xs:with-param>
</xs:call-template>
</xs:template>

<xs:template match="slot[@symbol='viewFont']/frame">
<xs:variable name="x" select="../slot[@symbol='text']/string/value"/>
<xs:call-template name="frame-o-matic">
  <xs:with-param name="val"><xs:value-of select="$x"/></xs:with-param>
</xs:call-template>
</xs:template>

<!-- ================ 
process contents of array of styles slot
================= -->
<xs:template match="slot[@symbol='styles']/array">
<p><xs:apply-templates select="*[(position() mod 2) = 0]" mode="shuffle"/></p>
</xs:template>

<!-- ================ 
process even items in array
================= -->
<xs:template match="array/*[(position() mod 2) = 0]" mode="shuffle">
<xs:variable name="x" select="."/>
	<xs:call-template name="process-text">
	<xs:with-param name="val"><xs:value-of select="$x"/></xs:with-param>
	</xs:call-template>
</xs:template>

<!-- ================ 
process odd items in array (text nodes)
determine style position and convert line feeds to <br/>
================= -->
<xs:template match="array/*[(position() mod 2) = 1]" mode="shuffle">
  <xs:variable name="txt" select="./ancestor-or-self::frame/slot[@symbol='text']/string/value"/>
  <xs:variable name="n" select="number(.)"/>
  <xs:variable name="d" select="sum(preceding-sibling::*[(position() mod 2) = 0]) + 1"/>
	<xs:call-template name="br-scanner">
	<xs:with-param name="word" select="substring($txt,$d,$n)"/>
	</xs:call-template>
</xs:template>

<!-- ================ 
format styles in frame and process preceding sibling element (text it belongs to)
================= -->
<xs:template match="frame[slot[@symbol='face']]" name="frame-o-matic" mode="shuffle">
<xs:variable name="f" select="slot[@symbol='face']/."/>
<xs:variable name="face">
	<xs:call-template name="face-decoder">
	<xs:with-param name="f"><xs:value-of select="$f"/></xs:with-param>
	</xs:call-template>
</xs:variable>
<xs:variable name="s" select="slot[@symbol='size']/."/>
<xs:variable name="size">
<xs:choose>
  <xs:when test="$s &lt; 8"><xs:value-of select="$defaultSize"/></xs:when>
  <xs:otherwise><xs:copy-of select="$s"/></xs:otherwise>
</xs:choose>
</xs:variable>
<xs:element name="span">
<xs:attribute name="style">font-family: <xs:copy-of select="normalize-space(slot[@symbol='family']/.)"/>, serif; font-size: <xs:copy-of select="normalize-space($size)"/>px; <xs:copy-of select="normalize-space($face)"/></xs:attribute>
<xs:choose>
  <xs:when test="preceding-sibling::int[1]"><!-- frame relates to integer -->
	<xs:apply-templates select="preceding-sibling::*[1]" mode="shuffle"/>
  </xs:when>
  <xs:when test="ancestor::node()/slot[@symbol='text']"><!-- frame relates to text slot -->
    <xs:variable name="t" select="ancestor::node()/slot[@symbol='text']/string/value"/>
	<xs:call-template name="br-scanner"><xs:with-param name="word" select="$t"/></xs:call-template>
  </xs:when>
</xs:choose>
</xs:element>
</xs:template>

<!-- ================ 
process precedents (there's got to be way to pass it to frame-o-matic...)
================= -->
<xs:template match="array/precedent" mode="shuffle">
<xs:variable name="f" select="id(@idref)/*[@symbol='face']/."/>
<xs:variable name="face">
	<xs:call-template name="face-decoder">
	<xs:with-param name="f"><xs:value-of select="$f"/></xs:with-param>
	</xs:call-template>
</xs:variable>
<xs:variable name="s" select="id(@idref)/slot[@symbol='size']/."/>
<xs:variable name="size">
<xs:choose>
  <xs:when test="$s &lt; 8"><xs:value-of select="$defaultSize"/></xs:when>
  <xs:otherwise><xs:copy-of select="$s"/></xs:otherwise>
</xs:choose>
</xs:variable>
<xs:element name="span">
<xs:attribute name="style">font-family: <xs:copy-of select="normalize-space(id(@idref)/slot[@symbol='family']/.)"/>, serif; font-size: <xs:copy-of select="normalize-space($size)"/>px; <xs:copy-of select="normalize-space($face)"/></xs:attribute>
	<xs:apply-templates select="preceding-sibling::*[1]" mode="shuffle"/>
</xs:element>
</xs:template>

<!-- ================ 
decode style from binary, format and wrap it around the text
================= -->
<xs:template name="process-text">
<xs:param name="val"/>
<xs:variable name="x"><xs:value-of select="$val" /></xs:variable>
<xs:variable name="p" select="$x mod 1024"/>
<xs:variable name="font">
  <xs:call-template name="font-decoder">
  <xs:with-param name="p"><xs:value-of select="$p"/></xs:with-param>
  </xs:call-template>
</xs:variable>
<xs:variable name="s" select="(($x - $p) div 1024) mod 1024"/>
<xs:variable name="size">
<xs:choose>
  <xs:when test="number($s)"><xs:copy-of select="$s"/></xs:when>
  <xs:otherwise><xs:copy-of select="$defaultSize"/></xs:otherwise>
</xs:choose>
</xs:variable>
<xs:variable name="f" select="((($x - $p) div 1024) - $s) div 1024"/>
<xs:variable name="face">
  <xs:call-template name="face-decoder">
  <xs:with-param name="f"><xs:value-of select="$f"/></xs:with-param>
  </xs:call-template>
</xs:variable>
<xs:choose>
  <xs:when test="ancestor::node()/slot[@symbol='styles']">
  <xs:element name="span"><xs:attribute name="style"><xs:copy-of select="$font"/> font-size: <xs:copy-of select="$size"/>px; <xs:copy-of select="$face"/></xs:attribute>
  <xs:apply-templates select="preceding-sibling::*[1]" mode="shuffle"/></xs:element>
  </xs:when>
  <xs:otherwise>
  <xs:element name="span"><xs:attribute name="style"><xs:copy-of select="$font"/> font-size: <xs:copy-of select="$size"/>px; <xs:copy-of select="$face"/></xs:attribute>
  <xs:value-of select="ancestor::node()/slot[@symbol='text']/string/value"/></xs:element>
  </xs:otherwise>
</xs:choose>
</xs:template>

<!-- ================ 
font decoder 
================= -->
<xs:template name="font-decoder">
<xs:param name="p"/>
<xs:choose>
  <xs:when test="$p = 0"><xs:copy-of select="$tsEspy"/></xs:when>
  <xs:when test="$p = 1"><xs:copy-of select="$tsFancy"/></xs:when>
  <xs:when test="$p = 2"><xs:copy-of select="$tsSimple"/></xs:when>
  <xs:when test="$p = 3"><xs:copy-of select="$tsHWFont"/></xs:when>
  <xs:otherwise><xs:copy-of select="$defaultFamily"/></xs:otherwise>
</xs:choose>
</xs:template>

<!-- ================ 
face decoder 
================= -->
<xs:template name="face-decoder">
<xs:param name="f"/>
<xs:choose>
  <xs:when test="$f = 1"><xs:copy-of select="$tsBold"/></xs:when>
  <xs:when test="$f = 2"><xs:copy-of select="$tsItalic"/></xs:when>
  <xs:when test="$f = 4"><xs:copy-of select="$tsUnderline"/></xs:when>
  <xs:when test="$f = 8"><xs:copy-of select="$tsOutline"/></xs:when>
  <xs:when test="$f = 128"><xs:copy-of select="$tsSuperScript"/></xs:when>
  <xs:when test="$f = 256"><xs:copy-of select="$tsSubScript"/></xs:when>
  <xs:otherwise><!-- tsPlain --></xs:otherwise>
</xs:choose>
</xs:template>

<!-- ================ 
br scanner 
================= -->
<xs:template name="br-scanner">
<xs:param name="word"/>
<xs:variable name="cr"><xs:text>
</xs:text></xs:variable>
<!-- </xs:text> must be on new line -->
<xs:choose>
  <xs:when test="contains($word,$cr)">
  <xs:value-of select="substring-before($word,$cr)"/><br/>
  <xs:call-template name="br-scanner">
  <xs:with-param name="word" select="substring-after($word,$cr)"/>
  </xs:call-template>
  </xs:when>
  <xs:otherwise><xs:value-of select="$word"/></xs:otherwise>
</xs:choose>
</xs:template>

<xs:strip-space elements="*"/>
</xs:stylesheet>