<xsl:stylesheet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" version="1.0" exclude-result-prefixes="xalan">
    <xsl:import href="common.xsl"/>
    <xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/>

	<!--
		Utilisation du document referentiel NSA passe en parametre dans scenario.xsl
		<xsl:param name="pathReferentiel" select="'http://xml.sandre.eaufrance.fr/exist/sandre/Referentiels/NSA.xml'"/>
	 -->
    <xsl:variable name="referentiel" select="document($referentielURL)"/>
    <xsl:key name="objetsReferentiels" match="*[local-name() = 'Referentiel']" use="./*[local-name() = 'CdReferentiel']"/>
 
    <!-- HEADERS DU TABLEAU DES NOMENCLATURES-->
	
	<!-- Header pour le code d'une nomenclautre -->
    <xsl:variable name="nomHeaderValue1">Code</xsl:variable>
	<!-- Header pour le mnémonique d'une nomenclautre -->
    <xsl:variable name="nomHeaderValue2">Mnémonique</xsl:variable>
	<!-- Header pour le libéllé d'une nomenclature -->
    <xsl:variable name="nomHeaderValue3">Libellé</xsl:variable>
	<!-- Header pour la définition d'une nomenclature -->
    <xsl:variable name="nomHeaderValue4">Définition</xsl:variable>
	<!-- Header pour la date de création d'une nomenclautre -->
    <xsl:variable name="nomHeaderValue5">Date de création</xsl:variable>
	<!-- Header pour la date de mis à jour d'une nomenclature -->
    <xsl:variable name="nomHeaderValue6">Date de mise à jour</xsl:variable>

	<!-- 
		Traitement du scenario.xsd 
	-->
    <xsl:template name="computeNomenclature">
	<!-- <scenario> -->
		
<!-- DEBUG / avec namespace ref -->
<!--		 	
	 		<referentielNS>
		 		<xsl:for-each select="$referentiel/ref:REFERENTIELS/ref:Referentiel">
		 			<xsl:sort select="ref:NomReferentiel"  order="ascending" />
		 			<element><xsl:value-of select="local-name()"/>:<xsl:value-of select="ref:CdReferentiel"/>-<xsl:value-of select="ref:NomReferentiel"/></element>
		 		</xsl:for-each>
		 	</referentielNS>
-->		 	

<!-- DEBUG / sans connaissance du namespace (l'ideal) -->					
<!--			
	 		<referentielExterne>
		 		<xsl:for-each select="$referentiel/*[local-name() = 'REFERENTIELS']/*[local-name() = 'Referentiel']">
		 			<xsl:sort select="*[local-name() ='NomReferentiel'][1]"  order="ascending" />
		 			<element><xsl:value-of select="local-name()"/>:<xsl:value-of select="./*[local-name() = 'CdReferentiel']"/>-<xsl:value-of select="./*[local-name() = 'NomReferentiel']"/></element>
		 		</xsl:for-each>
		 	</referentielExterne>
-->
			<!-- 
				RECHERCHE DES NOMENCLATURES UTILISEES DANS LE SCENARIO
			-->
			
<!--  DEBUG / pour afficher les referentiels trouves -->
<!--
			<Referentiels>
				<xsl:call-template name="parseListIDChildElement">
					<xsl:with-param name="level">1</xsl:with-param>
				</xsl:call-template>
			</Referentiels>	
-->			

			<!-- Recherche des nomenclatures utilisees dans le scenario -->
        <xsl:variable name="listReferentiels">
            <xsl:call-template name="parseListIDChildElement">
                <xsl:with-param name="level">1</xsl:with-param>
            </xsl:call-template>
        </xsl:variable>

			<!-- 
				TRAITEMENT DES NOMENCLATURES
			 -->

<!--  DEBUG / traitement de la liste des nomenclatures avec doublons -->
<!--			
			<nomenclaturesDoublons>
 				<xsl:for-each select="xalan:nodeset($listReferentiels)//Referentiel" >
	             	<xsl:sort select="@name"/>
                	<nomenclature>
                		<xsl:call-template name="processReferentiel">
							<xsl:with-param name="lookup" select="$referentiel" />
							<xsl:with-param name="ID" select="@code" />
						</xsl:call-template>
                	</nomenclature>
       			</xsl:for-each>
       		</nomenclaturesDoublons>
-->       		

			<!--  Traitement de la liste des nomenclatures sans doublons / triée par Nom -->
        <xsl:variable name="distinct-referentiels" select="xalan:nodeset($listReferentiels)//Referentiel[not( preceding-sibling::Referentiel/@code = @code )]"/>
        <xsl:for-each select="$distinct-referentiels">
            <xsl:sort select="@name"/>
            <xsl:call-template name="processReferentiel">
                <xsl:with-param name="lookup" select="$referentiel"/>
                <xsl:with-param name="ID" select="@code"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

	<!-- ////////////   RECHERCHE DES NOMENCLATURES UTILISEES DANS LE SCENARIO //////////  -->

	<!--
		TRAITEMENT DES ELEMENTS METIER (NIVEAU >= 1) SAUF ELEMENT SCENARIO
	-->
    <xsl:template name="parseListIDChildElement">
        <xsl:param name="level"/>
		<!-- Parcours des éléments du niveau donné -->
        <xsl:for-each select="//*[(local-name()='element') and (@name!='Scenario')][count(ancestor::*[local-name()='element']) = $level]">
			<!--  balise père des éléments parcourus -->
            <xsl:variable name="element" select="."/>					
					
			<!-- Traitement de l'élément -->
            <xsl:call-template name="parseElement">
                <xsl:with-param name="element" select="$element"/>
                <xsl:with-param name="first" select="true()"/>
                <xsl:with-param name="firstLevelChild" select="$level + 1"/>
                <xsl:with-param name="lastLevelChild" select="$level + 3"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

	<!-- 
		TRAITEMENT D'UN ELEMENT
	-->
    <xsl:template name="parseElement">
        <xsl:param name="element"/>
        <xsl:param name="first"/>
        <xsl:param name="isRoot"/>
        <xsl:param name="firstLevelChild"/>
        <xsl:param name="lastLevelChild"/>
        <xsl:param name="isSimple"/>
        <xsl:param name="isOneLevel"/>
        <xsl:param name="isTwoLevel"/>
        <xsl:param name="mode"/>		

		<!-- Détermination du type de l'élément <=> quel dico parcourir-->
		<!--  type entier  -->
        <xsl:variable name="type">
			<!-- type de namespace <=> référence le dico à parcourir -->
            <xsl:variable name="typeNs" select="substring-before($element/@type, ':')"/>
            <xsl:choose>
                <xsl:when test="$typeNs">
                    <xsl:value-of select="$typeNs"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:variable name="tmpTypeNs" select="substring-before($element/child::*[local-name()='complexType']/child::*[local-name()='simpleContent']/child::*[local-name() = 'restriction' or local-name() = 'extension']/@base, ':')"/>
                    <xsl:choose>
                        <xsl:when test="$tmpTypeNs">
                            <xsl:value-of select="$tmpTypeNs"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$defaultType"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
		
		<!-- Récupération de la définition de l'élément dans le dictionnaire des données -->
		<!-- pointe sur le BD Sandre... peut poser pb pour les tests -->
        <xsl:variable name="ns" select="//*[local-name()='schema']/namespace::*[local-name()=$type]"/>
	
		<!-- nom du fichier du dictionnaire à parser -->
        <xsl:variable name="relativeFileName" select="string(//*[local-name()='import'][@namespace=$ns]/@schemaLocation)"/>
        <xsl:variable name="fileName">
            <xsl:call-template name="getFileName">
                <xsl:with-param name="path" select="//*[local-name()='import'][@namespace=$ns]/@schemaLocation"/>
            </xsl:call-template>
        </xsl:variable>
		
<!-- DEBUG
<xsl:message>parseElement ns <xsl:value-of select="$ns" /> filename <xsl:value-of select="$fileName" /></xsl:message>
-->
		<!-- nom de l'élément rechercher dans le dico -->
        <xsl:variable name="elementDef" select="document(concat($schemaFilePath, $relativeFileName))//*[local-name()='complexType'][@name=$element/@name]"/>

<!-- <xsl:choose>
<xsl:when test="$fileName!=''">
		 <xsl:value-of select="document(concat($ns, '/', $fileName))//*[local-name()='complexType'][@name=$element/@name]"/> 
</xsl:when>
<xsl:otherwise>
<xsl:message>elementDef undefined</xsl:message>
<xsl:value-of select="''"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
	
<xsl:if test="$elementDef!=''" >
<xsl:message>Variable format</xsl:message>
 -->	
		<!-- Traitement de la colonne "Format" -->
        <xsl:variable name="format">
            <xsl:choose>
                <xsl:when test="$type != $defaultType">
                    <xsl:variable name="tmpFmt" select="substring-after($elementDef/child::*[local-name()='simpleContent' or local-name()='complexContent']/child::*[local-name()='restriction' or local-name()='extension']/@base, ':' )"/>
                    <xsl:choose>
                        <xsl:when test="string($tmpFmt) = '' ">
                            <xsl:value-of select="$defaultFormat"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$tmpFmt"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$defaultFormat"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
		
		<!-- Traitement Code + Nom du referentiel -->
        <xsl:if test="$format = 'CodeType' ">
<!-- 
<xsl:message>Variable code referentiel</xsl:message>
 -->
            <xsl:variable name="code" select="$elementDef/child::*[local-name()='simpleContent' or local-name()='complexContent']/child::*[local-name()='restriction']/child::*[local-name()='attribute'][@name='listID']/@fixed"/>
            <xsl:variable name="nameRef">
                <xsl:for-each select="$referentiel">
                    <xsl:value-of select="key('objetsReferentiels',$code)/*[local-name() = 'NomReferentiel']"/>
                </xsl:for-each>
            </xsl:variable>
            <Referentiel>
                <xsl:attribute name="code">
                    <xsl:value-of select="$code"/>
                </xsl:attribute>
                <xsl:attribute name="name">
                    <xsl:value-of select="$nameRef"/>
                </xsl:attribute>

<!-- DEBUG -->
                <xsl:call-template name="displayLog">
                    <xsl:with-param name="logContent">Elément du scénario avec CodeType : <xsl:value-of select="$element/@name"/>
                    </xsl:with-param>
                </xsl:call-template>
                <xsl:call-template name="displayLog">
                    <xsl:with-param name="logContent">Dictionnaire : <xsl:value-of select="$type"/> [<xsl:value-of select="$ns"/>/<xsl:value-of select="$fileName"/>]</xsl:with-param>
                </xsl:call-template>
                <xsl:call-template name="displayLog">
                    <xsl:with-param name="logContent">Referentiel NSA Code : <xsl:value-of select="$code"/> Nom : <xsl:value-of select="$nameRef"/>
                    </xsl:with-param>
                </xsl:call-template>					
<!-- FIN DEBUG -->
            </Referentiel>
        </xsl:if>
<!-- 
</xsl:if>	
 -->
        <xsl:choose>
            <xsl:when test="string($first)=string(true())">
					<!-- Traitement des sous-éléments -->
                <xsl:call-template name="parseSubElements">
                    <xsl:with-param name="parentElement" select="$element"/>
                    <xsl:with-param name="firstLevelChild" select="$firstLevelChild"/>
                    <xsl:with-param name="lastLevelChild" select="$lastLevelChild"/>
                </xsl:call-template>
				<!--/xsl:element -->
            </xsl:when>
            <xsl:otherwise>
			
				<!-- Traitement des sous-éléments -->
                <xsl:if test="string($isOneLevel)=string(true())">
                    <xsl:call-template name="parseSubElements">
                        <xsl:with-param name="parentElement" select="$element"/>
                        <xsl:with-param name="firstLevelChild" select="$firstLevelChild"/>
                        <xsl:with-param name="lastLevelChild" select="$lastLevelChild"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template name="parseSubElements">
        <xsl:param name="parentElement"/>
        <xsl:param name="firstLevelChild"/>
        <xsl:param name="lastLevelChild"/>
	
		<!-- Parcours des éléments fils -->
        <xsl:for-each select="$parentElement/descendant::*[local-name()='element'][count(ancestor::*[local-name()='element']) = $firstLevelChild]">
            <xsl:variable name="childElement" select="."/>
            <xsl:choose>
                <xsl:when test="not($childElement/descendant::*[local-name()='element'])">
                    <xsl:call-template name="parseSimpleElement">
                        <xsl:with-param name="element" select="$childElement"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:choose>
                        <xsl:when test="not($childElement/descendant::*[local-name()='element'][count(ancestor::*[local-name()='element']) = $lastLevelChild])">
                            <xsl:call-template name="parseOneLevelElement">
                                <xsl:with-param name="element" select="$childElement"/>
                                <xsl:with-param name="level" select="$firstLevelChild"/>
                            </xsl:call-template>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:call-template name="parseTwoLevelElement">
                                <xsl:with-param name="element" select="$childElement"/>
                            </xsl:call-template>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
	
	<!-- 
		elements de second niveau
	-->
    <xsl:template name="parseTwoLevelElement">
        <xsl:param name="element"/>
		<!--twoLevelElement-->
        <xsl:call-template name="parseElement">
            <xsl:with-param name="element" select="$element"/>
            <xsl:with-param name="isTwoLevel" select="true()"/>
        </xsl:call-template>			
		<!--/twoLevelElement-->
    </xsl:template>

	<!-- 
		elements de niveau 1 à 3
	-->
    <xsl:template name="parseOneLevelElement">
        <xsl:param name="element"/>
        <xsl:param name="level"/>		
		<!--oneLevelElement-->
        <xsl:call-template name="parseElement">
            <xsl:with-param name="element" select="$element"/>
            <xsl:with-param name="isOneLevel" select="true()"/>
            <xsl:with-param name="firstLevelChild" select="$level + 1"/>
            <xsl:with-param name="lastLevelChild" select="$level + 3"/>
        </xsl:call-template>
		<!--/oneLevelElement-->
    </xsl:template>

	<!-- 
		elements simples
	-->
    <xsl:template name="parseSimpleElement">
        <xsl:param name="element"/>
		<!--simpleElement-->
        <xsl:call-template name="parseElement">
            <xsl:with-param name="element" select="$element"/>
            <xsl:with-param name="isSimple" select="true()"/>
        </xsl:call-template>
		<!--/simpleElement-->
    </xsl:template>



	<!-- ////////////   AFFICHAGE D'UNE NOMENCLATURE //////////  -->
	<!-- 
		1. Recuperation du referentiel dont l'id est passé en parametre
	 -->
    <xsl:template name="processReferentiel">
        <xsl:param name="lookup"/> <!-- element root du document referentiel -->
        <xsl:param name="ID"/>
        <xsl:for-each select="$lookup">
		
			<!-- Test si le référentiel traité existe dans le référentiel du Sandre "NSA.xml" -->
            <xsl:choose>
                <xsl:when test="key('objetsReferentiels',$ID)">
                    <xsl:call-template name="displayLog">
                        <xsl:with-param name="logContent">Traitement de la nomenclature de code: <xsl:value-of select="$ID"/>
                        </xsl:with-param>
                    </xsl:call-template>
                    <xsl:call-template name="displayReferentiel">
                        <xsl:with-param name="referentiel" select="key('objetsReferentiels',$ID)"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="displayLogWarning">
                        <xsl:with-param name="logContent">La nomenclature de code : <xsl:value-of select="$ID"/>  n'est pas définie dans le référentiel <xsl:value-of select="$referentielURL"/>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template> 
	
	<!-- 
		2. Traitement de transformation du referentiel en bloc de balises odt
	 -->
    <xsl:template name="displayReferentiel">
        <xsl:param name="referentiel"/> <!-- element Referentiel -->
        <xsl:call-template name="displayNomenclatureTitle">
            <xsl:with-param name="NameRefToDisplay" select="$referentiel/*[local-name() = 'NomReferentiel']"/>
            <xsl:with-param name="CdRefToDisplay" select="$referentiel/*[local-name() = 'CdReferentiel']"/>
        </xsl:call-template>
        <xsl:if test="$referentiel/*[local-name() = 'Element']">
            <table:table table:style-name="Tableau26">
                <xsl:call-template name="displayNomHeaders"/>
                <xsl:for-each select="$referentiel/*[local-name() = 'Element']">
                    <xsl:call-template name="displayOneNomenclature">
                        <xsl:with-param name="nomCode" select="./*[local-name() = 'CdElement']"/>
                        <xsl:with-param name="nomMnemonique" select="./*[local-name() = 'MnElement']"/>
                        <xsl:with-param name="nomLibelle" select="./*[local-name() = 'LbElement']"/>
                        <xsl:with-param name="nomDefinition" select="./*[local-name() = 'DefElement']"/>
                        <xsl:with-param name="nomDateCreation" select="./*[local-name() = 'DateCreationElement']"/>
                        <xsl:with-param name="nomDateMaj" select="./*[local-name() = 'DateMajElement']"/>
                    </xsl:call-template>
                </xsl:for-each>
            </table:table>
        </xsl:if>
        <xsl:if test="not($referentiel/*[local-name() = 'Element'])">
            <xsl:call-template name="displayLogWarning">
                <xsl:with-param name="logContent">La nomenclature ne contient aucun élément.</xsl:with-param>
            </xsl:call-template>
            <text:p text:style-name="Standard">La nomenclature est définie sans élément dans le référentiel.</text:p>
        </xsl:if>
			
			<!-- saut de page entre chaque tableau de nomenclautre -->
        <text:p text:style-name="P73"/>
    </xsl:template>

	<!-- 
		AFFICHAGE DU TITRE DE CHAQUE NOMENCLATURE TRAITEE
	 -->
    <xsl:template name="displayNomenclatureTitle">
        <xsl:param name="NameRefToDisplay"/>
        <xsl:param name="CdRefToDisplay"/>
        <text:h text:style-name="P81" text:outline-level="2">
            <text:span text:style-name="P79">
                <xsl:value-of select="$NameRefToDisplay"/>
            </text:span>(code Sandre [<text:span text:style-name="P79">
                <xsl:value-of select="$CdRefToDisplay"/>
            </text:span>])			
		</text:h>
    </xsl:template>
	
	
	<!--
		AFFICHAGE DU HEADER DU TABLEAU DES NOMENCLATURES
	-->
    <xsl:template name="displayNomHeaders">
        <table:table-column table:style-name="Tableau26.A"/>
        <table:table-column table:style-name="Tableau26.B"/>
        <table:table-column table:style-name="Tableau26.C"/>
        <table:table-column table:style-name="Tableau26.D"/>
        <table:table-column table:style-name="Tableau26.E"/>
        <table:table-column table:style-name="Tableau26.F"/>
        <table:table-header-rows>
            <table:table-row>
                <table:table-cell table:style-name="Tableau26.A1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue1"/>
                    </text:p>
                </table:table-cell>
                <table:table-cell table:style-name="Tableau26.A1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue2"/>
                    </text:p>
                </table:table-cell>
                <table:table-cell table:style-name="Tableau26.A1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue3"/>
                    </text:p>
                </table:table-cell>
                <table:table-cell table:style-name="Tableau26.A1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue4"/>
                    </text:p>
                </table:table-cell>
                <table:table-cell table:style-name="Tableau26.A1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue5"/>
                    </text:p>
                </table:table-cell>
                <table:table-cell table:style-name="Tableau26.F1" office:value-type="string">
                    <text:p text:style-name="P55">
                        <xsl:value-of select="$nomHeaderValue6"/>
                    </text:p>
                </table:table-cell>
            </table:table-row>
        </table:table-header-rows>
    </xsl:template>


	<!-- 
		AFFICHAGE D'UNE NOMENCLATURE DANS LE TABLEAU 
	-->
    <xsl:template name="displayOneNomenclature">
        <xsl:param name="nomCode"/>
        <xsl:param name="nomMnemonique"/>
        <xsl:param name="nomLibelle"/>
        <xsl:param name="nomDefinition"/>
        <xsl:param name="nomDateCreation"/>
        <xsl:param name="nomDateMaj"/>
        <table:table-row>
            <table:table-cell table:style-name="Tableau26.A2" office:value-type="string">
                <text:p text:style-name="P89">
                    <xsl:value-of select="$nomCode"/>
                </text:p>
            </table:table-cell>
            <table:table-cell table:style-name="Tableau26.A2" office:value-type="string">
                <text:p text:style-name="Table_20_Contents">
                    <xsl:value-of select="$nomMnemonique"/>
                </text:p>
            </table:table-cell>
            <table:table-cell table:style-name="Tableau26.A2" office:value-type="string">
                <text:p text:style-name="Table_20_Contents">
                    <xsl:value-of select="$nomLibelle"/>
                </text:p>
            </table:table-cell>
            <table:table-cell table:style-name="Tableau26.A2" office:value-type="string">
                <text:p text:style-name="Table_20_Contents">
                    <xsl:value-of select="$nomDefinition"/>
                </text:p>
            </table:table-cell>
            <table:table-cell table:style-name="Tableau26.A2" office:value-type="string">
                <text:p text:style-name="Table_20_Contents">
                    <xsl:value-of select="$nomDateCreation"/>
                </text:p>
            </table:table-cell>
            <table:table-cell table:style-name="Tableau26.F2" office:value-type="string">
                <text:p text:style-name="Table_20_Contents">
                    <xsl:value-of select="$nomDateMaj"/>
                </text:p>
            </table:table-cell>
        </table:table-row>
    </xsl:template>
</xsl:stylesheet>