<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<xsl:output method="xml" encoding="UTF-8" media-type="image/svg+xml" />
	<xsl:template match="/">
		<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
			<!-- Centre the SVG drawing at 500,500 in our 1000x1000 viewing box -->
			<g transform="translate(500,500)">
				<xsl:apply-templates />
			</g>
		</svg>
	</xsl:template>
	
	<xsl:template match="lorenz">
		<!-- Kick off recursive drawing using our Lorenz definition from the XML file -->
		<xsl:call-template name="recurse">
			<xsl:with-param name="i">
				<xsl:value-of select="practice/iterations" />
			</xsl:with-param>

			<xsl:with-param name="beta">
				<xsl:value-of select="theory/beta" />
			</xsl:with-param>

			<xsl:with-param name="rho">
				<xsl:value-of select="theory/rho" />
			</xsl:with-param>

			<xsl:with-param name="sigma">
				<xsl:value-of select="theory/sigma" />
			</xsl:with-param>
			
			<xsl:with-param name="x">
				<xsl:value-of select="practice/initialvalues/x" />
			</xsl:with-param>

			<xsl:with-param name="y">
				<xsl:value-of select="practice/initialvalues/y" />
			</xsl:with-param>

			<xsl:with-param name="z">
				<xsl:value-of select="practice/initialvalues/z" />
			</xsl:with-param>

			<xsl:with-param name="t">
				<xsl:value-of select="practice/initialvalues/t" />
			</xsl:with-param>
			
			<xsl:with-param name="dt">
				<xsl:value-of select="practice/dt" />
			</xsl:with-param>
						
			</xsl:call-template>
	</xsl:template>

	<xsl:template name="recurse">
		<!-- The main event; this recursive function actually does the drawing. This version is projecting
				 a planar view of the attractor, drawing simply x and y, looking directly along z. -->
		<xsl:param name="i" />
		<xsl:param name="beta" />
		<xsl:param name="rho" />
		<xsl:param name="sigma" />
		<xsl:param name="x" />
		<xsl:param name="y" />
		<xsl:param name="z" />
		<xsl:param name="t" />
		<xsl:param name="dt" />

		<xsl:variable name="scale">15</xsl:variable>

		<!-- If we've not yet reached our number of "iterations" on this recursion -->
		<xsl:if test="$i &gt; 0">
		
			<!-- Move on x, y, z and time -->
			<xsl:variable name="x1">
				<xsl:value-of select="$x + (( -$sigma*$x + $sigma*$y ) * $dt)" />
			</xsl:variable>
			<xsl:variable name="y1">
				<xsl:value-of select="$y + ((( $rho*$x - $x*$z) - $y) * $dt)" />
			</xsl:variable>
			<xsl:variable name="z1">
				<xsl:value-of select="$z + (( ($x)*($y) -($beta)*($z)) * $dt)" />
			</xsl:variable>
			<xsl:variable name="t1">
				<xsl:value-of select="$t+$dt" />
			</xsl:variable>
	
			<!-- Draw a line from the last x, y position to the newly-calculated x, y using the SVG's line element -->
			<xsl:element xmlns="http://www.w3.org/2000/svg" name="line">
				<xsl:attribute name="x1"><xsl:value-of select="($x)*($scale)" /></xsl:attribute>
				<xsl:attribute name="y1"><xsl:value-of select="($y)*($scale)" /></xsl:attribute>
				<xsl:attribute name="x2"><xsl:value-of select="($x1)*($scale)" /></xsl:attribute>
				<xsl:attribute name="y2"><xsl:value-of select="($y1)*($scale)" /></xsl:attribute>
				<xsl:attribute name="style"><xsl:text>stroke:rgb(99,99,99);stroke-width:2</xsl:text></xsl:attribute>
			</xsl:element>
			<xsl:text>
			</xsl:text>

			<!--	And recurse with our newly-calculated values. This should be noticed as a tail-recursion in 
						an XSL engine that can recognise that. 
			-->
			<xsl:call-template name="recurse">
				<xsl:with-param name="i"><xsl:value-of select="($i)-1" /></xsl:with-param>
				<xsl:with-param name="beta"><xsl:value-of select="$beta" /></xsl:with-param>
				<xsl:with-param name="rho"><xsl:value-of select="$rho" /></xsl:with-param>
				<xsl:with-param name="sigma"><xsl:value-of select="$sigma" /></xsl:with-param>
				<xsl:with-param name="dt"><xsl:value-of select="$dt" /></xsl:with-param>
				<xsl:with-param name="x"><xsl:value-of select="$x1" /></xsl:with-param>
				<xsl:with-param name="y"><xsl:value-of select="$y1" /></xsl:with-param>
				<xsl:with-param name="z"><xsl:value-of select="$z1" /></xsl:with-param>
				<xsl:with-param name="t"><xsl:value-of select="$t1" /></xsl:with-param>
			</xsl:call-template>
		</xsl:if>
	</xsl:template>
</xsl:transform>
