<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:fm="http://www.pnp-software.com/XFeature/fmm">
    <xsl:output method="xml"/>

    <!-- <xd:doc>
      <xd:short>Decides whether file contains macro extension and calls <code>ProcessExtenssions</code> if needed.</xd:short>
    </xd:doc> -->		
    <xsl:template match="/">
        <!-- <xsl:apply-templates/> -->
        <xsl:choose>
          <xsl:when test="//fm:MacroExtensionAppendGroupNode | //fm:MacroExtensionAppendFeatureNode">
            <xsl:variable name="extensions" select="//fm:MacroExtensionAppendGroupNode | //fm:MacroExtensionAppendFeatureNode"/>
            <!--<xsl:message>extensions: <xsl:value-of select="$extensions/@fm:value"/></xsl:message>-->
            <xsl:call-template name="ProcessExtensions">
              <xsl:with-param name="file" select="."/>
            </xsl:call-template>
            <!-- <xsl:message>Extension processing</xsl:message> -->
          </xsl:when>
          <xsl:otherwise>
            <!-- <xsl:message>NO extension processing</xsl:message> -->
            <xsl:copy-of select="."/>
          </xsl:otherwise>
        </xsl:choose>        
    </xsl:template>
    
    <!-- <xd:doc>
      <xd:short>Processes file if it contains macro extension.</xd:short>
      <xd:detail>
      This template can be called recursively by itself. It processes the extensions 
      in the argument <code>$file</code>, as long as there are macro extension elements left in it. 
      If no more extensions are
      found, the <code>$file</code> is sent to the output (using <code>xsl:copy-of</code>).</xd:detail>
      <xd:param name="file" type="node-set">whole file, the file still contains at least one macro extension</xd:param>
    </xd:doc> -->
    <xsl:template name="ProcessExtensions">
      <xsl:param name="file"/>
      <xsl:variable name="extensions" select="$file//fm:MacroExtensionAppendGroupNode | $file//fm:MacroExtensionAppendFeatureNode"/>
      <xsl:choose>
        <xsl:when test="$extensions">
          
          <!-- What follows at next seven lines is the debuging code -->
          <xsl:variable name="saveTempWovenFiles" select="'false'"/>
          <xsl:if test="$saveTempWovenFiles = 'true'">
            <xsl:variable name="tmpFile" select="concat('tmp.xml', '_',count($extensions), '.xml')"/>
            <xsl:result-document href="{$tmpFile}">
              <xsl:copy-of select="$file"/>
            </xsl:result-document>
          </xsl:if>
          
          <xsl:call-template name="ProcessExtensions">
            <xsl:with-param name="file">
              <xsl:apply-templates select="$file" mode="appending"/>
            </xsl:with-param>
          </xsl:call-template>
        </xsl:when>
        
        <xsl:otherwise>
          <xsl:copy-of select="$file"/> <!-- This is end of recursion -->
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>  
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*" mode="appending">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates mode="appending"/>  
        </xsl:copy>
    </xsl:template>
    
    <!-- ######################################## Ct 1538 ########################################### -->
    <!-- Orginial match="Extension[...]" is replaces by two templates -->
    
    
    <!-- May 12, 2005 <xd:doc>
      <xd:short>Process MacroExtensionAppendGroupNode</xd:short>
      <xd:detail>
          This template process MacroExtensionAppendGroupNode 
      </xd:detail>
    </xd:doc> -->    
    <xsl:template match="//fm:MacroExtensionAppendGroupNode[fm:AppendGroupPropertySet/fm:ExtendedMacroNameProperty/@fm:value=//fm:MacroFeatureNode[fm:FeatureNode]/@fm:value]" mode="appending">
        <xsl:variable name="enteredExtensionName" select="@fm:value"/>
        <xsl:variable name="targetMacroName" select="fm:AppendGroupPropertySet/fm:ExtendedMacroNameProperty/@fm:value"/>
        <xsl:variable name="targetMacro" select="/fm:FeatureModel/fm:MacroFeatureNode[@fm:value=$targetMacroName]"/>
        <xsl:variable name="targetAppendedFeatureName" select="fm:AppendGroupPropertySet/fm:TargetFeatureNameProperty/@fm:value"/>
        <xsl:variable name="targetAppendedFeature" select="$targetMacro//fm:FeatureNode[@fm:value=$targetAppendedFeatureName]"/>
        <xsl:variable name="macroWithExtension" select="@fm:value"/>

        <!-- This copies everything and one of the (sub)features extends with a group -->
        <xsl:element name="fm:MacroFeatureNode">
            <xsl:attribute name="fm:value" select="@fm:value"/>
                <xsl:element name="fm:SingletonCardinality">
                    <xsl:attribute name="fm:cardMin" select="1"/>
                    <xsl:attribute name="fm:cardMax" select="1"/>
                </xsl:element>
                <xsl:apply-templates select="$targetMacro/fm:FeatureNode" mode="ext">
                    <xsl:with-param name="macroWithExtensionThatIsBeingProcessed" select="$macroWithExtension" tunnel="yes"/>
                </xsl:apply-templates>
        </xsl:element>
    </xsl:template>
    <!-- May 12, 2005 <xd:doc>
      <xd:short>Process MacroExtensionAppendFeatureNode</xd:short>
      <xd:detail>
          This template process MacroExtensionAppendFeatureNode 
      </xd:detail>
    </xd:doc> -->
    <xsl:template match="//fm:MacroExtensionAppendFeatureNode[fm:AppendFeaturePropertySet/fm:ExtendedMacroNameProperty/@fm:value=//fm:MacroFeatureNode[fm:FeatureNode]/@fm:value]" mode="appending">
        <xsl:variable name="enteredExtensionName" select="@fm:value"/>
        <xsl:variable name="targetMacroName" select="fm:AppendFeaturePropertySet/fm:ExtendedMacroNameProperty/@fm:value"/>
        <xsl:variable name="targetMacro" select="/fm:FeatureModel/fm:MacroFeatureNode[@fm:value=$targetMacroName]"/>
        <xsl:variable name="targetAppendedGroupName" select="fm:AppendFeaturePropertySet/fm:TargetGroupNameProperty/@fm:value"/>
        <xsl:variable name="targetAppendedGroup" select="$targetMacro//fm:GroupNode[@fm:value=$targetAppendedGroupName]"/>
        <xsl:variable name="macroWithExtension" select="@fm:value"/>
        
        <!-- This copies everything and one of the (sub)features extends with a group -->
        <xsl:element name="fm:MacroFeatureNode">
            <xsl:attribute name="fm:value" select="@fm:value"/>
                <xsl:element name="fm:SingletonCardinality">
                    <xsl:attribute name="fm:cardMin" select="1"/>
                    <xsl:attribute name="fm:cardMax" select="1"/>
                </xsl:element>
                <xsl:apply-templates select="$targetMacro/fm:FeatureNode" mode="ext">
                    <xsl:with-param name="macroWithExtensionThatIsBeingProcessed" select="$macroWithExtension" tunnel="yes"/>
                </xsl:apply-templates>
        </xsl:element>
    </xsl:template>

    <!-- MODE 'EXT' GUARANTEES THAT WE ARE WITHIN Macro/Extension/Feature -->
    
    <xsl:template match="*" mode="ext">
        <xsl:param name="macroWithExtensionThatIsBeingProcessed" tunnel="yes"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates mode="ext"/>
        </xsl:copy>
    </xsl:template>
<!--    
   <xsl:template match="fm:MacroFeatureNode" mode="ext">
        <xsl:param name="macroWithExtensionThatIsBeingProcessed" tunnel="yes"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates mode="ext"/>
            <xsl:variable name="macroName" select="@fm:value"/>
            <xsl:variable name="groupContentIfAny" select="(//fm:MacroExtensionAppendGroupNode[fm:AppendGroupPropertySet/fm:TargetFeatureNameProperty/@fm:value=current()/@fm:value and @fm:value=$macroWithExtensionThatIsBeingProcessed]/fm:GroupNode)"/>
            <xsl:copy-of select="$groupContentIfAny"/>
        </xsl:copy>
    </xsl:template>
-->
    <xsl:template match="fm:FeatureNode" mode="ext">
        <xsl:param name="macroWithExtensionThatIsBeingProcessed" tunnel="yes"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates mode="ext"/>
            <xsl:variable name="macroName" select="ancestor::fm:MacroFeatureNode/@fm:value"/>
            <xsl:variable name="groupContentIfAny" select="(//fm:MacroExtensionAppendGroupNode[fm:AppendGroupPropertySet/fm:TargetFeatureNameProperty/@fm:value=current()/@fm:value and @fm:value=$macroWithExtensionThatIsBeingProcessed]/fm:GroupNode)"/>
            <xsl:copy-of select="$groupContentIfAny"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="fm:GroupNode" mode="ext">
        <xsl:param name="macroWithExtensionThatIsBeingProcessed" tunnel="yes"/>
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:variable name="macroName" select="ancestor::fm:MacroFeatureNode/@fm:value"/>
            <xsl:variable name="featureContentIfAny" select="(//fm:MacroExtensionAppendFeatureNode[fm:AppendFeaturePropertySet/fm:TargetGroupNameProperty/@fm:value=current()/@fm:value and @fm:value=$macroWithExtensionThatIsBeingProcessed]/fm:FeatureNode)"/>

            <xsl:choose>
              <xsl:when test="$featureContentIfAny">
                  <xsl:apply-templates mode="ext">
                     <xsl:with-param name="cardPropSet" select="//fm:MacroExtensionAppendFeatureNode[fm:AppendFeaturePropertySet/fm:TargetGroupNameProperty/@fm:value=current()/@fm:value and @fm:value=$macroWithExtensionThatIsBeingProcessed]/fm:AppendFeaturePropertySet"/>
                  </xsl:apply-templates>             
              </xsl:when>
              <xsl:otherwise>
                  <!-- Just apply templates (nothing added) -->
                  <xsl:apply-templates mode="ext"/>
              </xsl:otherwise>
            </xsl:choose>

            <xsl:copy-of select="$featureContentIfAny"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="fm:GroupCardinality" mode="ext">
        <xsl:param name="macroWithExtensionThatIsBeingProcessed" tunnel="yes"/>
        <xsl:param name="cardPropSet"/>
        <xsl:choose>
            <xsl:when test="$cardPropSet">
                <xsl:copy>
                    <xsl:attribute name="fm:cardMin" select="$cardPropSet/fm:NewMinCardinalityProperty/@fm:value"/>
                    <xsl:attribute name="fm:cardMax" select="$cardPropSet/fm:NewMaxCardinalityProperty/@fm:value"/>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
</xsl:stylesheet>
