<?xml version="1.0" encoding="iso-8859-1" ?>

<!--
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:err="http://www.w3.org/2005/xqt-errors">
-->

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">

<xsl:output 
method="xml" 
version="1.0" 
media-type="image/svg+xml"
encoding="iso-8859-1" 
indent="yes" /> 
<xsl:strip-space elements="*" />

<!--
<xsl:output 
method="xml"
version="1.0" 
encoding="iso-8859-1"
indent="yes"/>
-->

<!-- Paramètres -->
<!--
<xsl:param name="width">900</xsl:param>
<xsl:param name="height">900</xsl:param>
-->
<xsl:param name="titre">Arbre XML en SVG</xsl:param>
<xsl:param name="description">génération d'un arbre SVG à partir d'un fichier XML</xsl:param>
<!-- ========================== Variables =========================== -->
<xsl:variable name="tree" select="tree"/>
<xsl:variable name="nb-elements" select="count(tree/node)"/>


<xsl:variable name="nb-niveaux">
<xsl:call-template name="boucle-max">
<xsl:with-param name="n" select="$nb-elements"/>
<xsl:with-param name="valeur-courante" select="1"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="nb-max-element-niveau">
<xsl:call-template name="boucle-nb-element-niveau">
<xsl:with-param name="n" select="$nb-niveaux"/>
<xsl:with-param name="valeur-courante" select="0"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="height" select="( $nb-niveaux * 150 ) + 50"/>
<xsl:variable name="width" select="( $nb-max-element-niveau * 220 ) + 50"/>
<xsl:variable name="middle-width" select=" $width div 2"/>

<!-- ========================== Templates =========================== -->
<xsl:template name="maximum">
<!-- récupère les  deux valeurs en entrée et retourne le maximum -->
<xsl:param name="x1"/>
<xsl:param name="x2"/>


<xsl:variable name="resultat">
<xsl:choose>

<xsl:when test="string(x1) = 'NaN' and string(x2) ='NaN'">
<xsl:value-of select="$x1"/>
</xsl:when>

<xsl:when test="string(x1) = 'NaN'">
<xsl:value-of select="$x2"/>
</xsl:when>

<xsl:when test="string(x2) = 'NaN'">
<xsl:value-of select="$x1"/>
</xsl:when>

<xsl:when test="$x1 > $x2">
<xsl:value-of select="$x1"/>
</xsl:when>

<xsl:otherwise>
<xsl:value-of select="$x2"/>
</xsl:otherwise>

</xsl:choose>
</xsl:variable>

<xsl:copy-of select="$resultat"/>
</xsl:template>


<xsl:template name="boucle-max">
<xsl:param name="n"/>
<xsl:param name="valeur-courante"/>

<xsl:choose>
<xsl:when test="$n > 0">

<xsl:variable name="valeur">
<xsl:call-template name="maximum">
<xsl:with-param name="x1" select="tree/node[position() = $n ]/@level"/>
<xsl:with-param name="x2" select="$valeur-courante"/>
</xsl:call-template>
</xsl:variable>


<xsl:call-template name="boucle-max">
<xsl:with-param name="n" select="$n - 1"/>
<xsl:with-param name="valeur-courante" select="$valeur"/>
</xsl:call-template>

</xsl:when>

<xsl:otherwise>
<xsl:value-of select="$valeur-courante"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>






<xsl:template name="boucle-nb-element-niveau">
<xsl:param name="n"/>
<xsl:param name="valeur-courante"/>


<xsl:choose>
<xsl:when test="$n > 0">

<xsl:variable name="valeur">
<xsl:call-template name="maximum">
<xsl:with-param name="x1">
<xsl:call-template name="compte-elements-niveau">
<xsl:with-param name="level" select="$n"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="x2" select="$valeur-courante"/>
</xsl:call-template>
</xsl:variable>


<xsl:call-template name="boucle-nb-element-niveau">
<xsl:with-param name="n" select="$n - 1"/>
<xsl:with-param name="valeur-courante" select="$valeur"/>
</xsl:call-template>

</xsl:when>

<xsl:otherwise>
<xsl:value-of select="$valeur-courante"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


<xsl:template name="compte-elements-niveau">
<xsl:param name="level"/>
<xsl:value-of select="count($tree/node[@level = $level ])"/>
</xsl:template>

<xsl:template name="coord-parent-x">
<xsl:param name="level"/>
<xsl:param name="id"/>
<xsl:variable name="parent" select="$tree/node[ @level = $level and @id = $id ]"/>
<xsl:variable name="X" select="(($parent/@order - 1) * 220) + 25"/>
<xsl:value-of select="$X"/>
</xsl:template>

<xsl:template name="coord-parent-y">
<xsl:param name="level"/>
<xsl:param name="id"/>
<xsl:variable name="parent" select="$tree/node[ @level = $level and @id = $id ]"/>
<xsl:variable name="Y" select="(( $parent/@level - 1) * 150) + 30"/>
<xsl:value-of select="$Y"/>
</xsl:template>

<xsl:template name="width-element-niveau-parent">
<xsl:param name="level"/>
<xsl:variable name="level-parent"/>
<xsl:variable name="nb-parent" select="count($tree/node[ @level = $level-parent ])"/>
<xsl:variable name="resultat" select="( $nb-parent * 220 ) + 50"/>
<xsl:value-of select="$resultat"/>
</xsl:template>

<!-- ========================== Templates =========================== -->

<xsl:template match="/">
<svg:svg>
<xsl:attribute name="width"><xsl:value-of select="$width"/>px</xsl:attribute>
<xsl:attribute name="height"><xsl:value-of select="$height"/>px</xsl:attribute>
<xsl:attribute name="viewbox">0 0 <xsl:value-of select="$width"/><xsl:text> </xsl:text><xsl:value-of select="$height"/></xsl:attribute>
<xsl:attribute name="preserveAspectRation">xMidYMid Slice</xsl:attribute>

<svg:title><xsl:value-of select="$titre"/></svg:title>
<svg:desc><xsl:value-of select="$description"/></svg:desc>

<xsl:comment>Image SVG générée dynamiquement</xsl:comment>
<xsl:comment>XSLT réalisée par C.COMPAGNON pour AGS dans le cadre de la documentation automatique</xsl:comment>
<xsl:comment>version 1.0</xsl:comment>

<svg:defs>
<xsl:call-template name="svg-defs"/>
</svg:defs>

<xsl:call-template name="svg-trace"/>

</svg:svg>

</xsl:template>



<!-- ========================== Template =========================== -->

<xsl:template name="svg-defs">
<!-- définition des objets graphiques -->
<xsl:for-each select="$tree/node">

<svg:g>
<xsl:attribute name="id"><xsl:value-of select="concat('element_',@level,'_',@id)"/></xsl:attribute>
<svg:rect>
<xsl:attribute name="x">0</xsl:attribute>
<xsl:attribute name="y">0</xsl:attribute>
<xsl:attribute name="width">200</xsl:attribute>
<xsl:attribute name="height">30</xsl:attribute>
<xsl:attribute name="rx">15</xsl:attribute>
<xsl:attribute name="ry">15</xsl:attribute>
<xsl:attribute name="style">fill: none; stroke: black; stroke-width: 1;</xsl:attribute>
</svg:rect>

<!-- tracé du connecteur antérieur -->
<svg:line x1="100" y1="0" x2="100" y2="-30" style="fill: none; stroke: black; stroke-width: 1;" />
<svg:circle  cx="100" cy="-30" r="3"/>
<svg:path d="M 95 -15 L 105 -15 L 100 -8 Z"/>

<!-- tracé du connecteur postérieur -->
<svg:line x1="100" y1="30" x2="100" y2="60" style="fill: none; stroke: black; stroke-width: 1;" />
<svg:circle  cx="100" cy="60" r="3"/>

<svg:text x="100" y="19" style="font-family: Arial, Sans-serif; text-anchor: middle; font-size: 10px;"><xsl:value-of select="@label"/></svg:text>
</svg:g>

</xsl:for-each>
</xsl:template>



<xsl:template name="svg-trace">

<!-- tracé des noeuds -->
<xsl:for-each select="$tree/node">
<xsl:variable name="level" select="@level"/>

<!-- Pour le niveau n -->
<xsl:variable name="nb-elements">
<xsl:call-template name="compte-elements-niveau">
<xsl:with-param name="level" select="$level"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="width-niveau" select="( $nb-elements * 220 ) + 50"/>
<xsl:variable name="centre-niveau" select="$width-niveau div 2"/>
<xsl:variable name="correction" select="$middle-width - $centre-niveau"/>

<xsl:variable name="X" select="((@order - 1) * 220) + 25 + $correction"/>
<xsl:variable name="Y" select="(( @level - 1) * 150) + 30"/>

<svg:use>
<xsl:attribute name="xlink:href">#<xsl:value-of select="concat('element_',@level,'_',@id)"/></xsl:attribute>
<xsl:attribute name="transform">translate(<xsl:value-of select="$X"/>,<xsl:value-of select="$Y"/>)</xsl:attribute>
</svg:use>

<!-- tracé des liens -->
<xsl:for-each select="parent">
<xsl:variable name="x0" select="$X + 100"/>
<xsl:variable name="y0" select="$Y"/>

<xsl:variable name="x1">
<xsl:call-template name="coord-parent-x">
<xsl:with-param name="level" select="@level"/>
<xsl:with-param name="id" select="@id"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="y1">
<xsl:call-template name="coord-parent-y">
<xsl:with-param name="level" select="@level"/>
<xsl:with-param name="id" select="@id"/>
</xsl:call-template>
</xsl:variable>

<!-- Pour le niveau n - 1 -->
<xsl:variable name="nb-elements-n-1">
<xsl:call-template name="compte-elements-niveau">
<xsl:with-param name="level" select="@level"/>
</xsl:call-template>
</xsl:variable>

<xsl:variable name="width-niveau-n-1" select="( $nb-elements-n-1 * 220 ) + 50"/>
<xsl:variable name="centre-niveau-n-1" select="$width-niveau-n-1 div 2"/>
<xsl:variable name="correction-n-1" select="$middle-width - $centre-niveau-n-1"/>


<xsl:variable name="x2" select="$x1 + $correction-n-1 + 100"/>
<xsl:variable name="y2" select="$y1 + 30"/>

<svg:line>
<xsl:attribute name="x1"><xsl:value-of select="$x0"/></xsl:attribute>
<xsl:attribute name="y1"><xsl:value-of select="$y0 - 30"/></xsl:attribute>
<xsl:attribute name="x2"><xsl:value-of select="$x2"/></xsl:attribute>
<xsl:attribute name="y2"><xsl:value-of select="$y2 + 30"/></xsl:attribute>
<xsl:attribute name="style">fill: none; stroke: black; stroke-width: 1;</xsl:attribute>
</svg:line>


</xsl:for-each>



</xsl:for-each>

</xsl:template>


<!-- ================================================================== -->
</xsl:stylesheet>
