<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                              xmlns:wwsplits="urn:WebWorks-Engine-Splits-Schema"
                              xmlns:wwtoc="urn:WebWorks-Engine-TOC-Schema"
                              xmlns:wwlinks="urn:WebWorks-Engine-Links-Schema"
                              xmlns:wwmode="urn:WebWorks-Engine-Mode"
                              xmlns:wwfiles="urn:WebWorks-Engine-Files-Schema"
                              xmlns:wwdoc="urn:WebWorks-Document-Schema"
                              xmlns:wwbehaviors="urn:WebWorks-Behaviors-Schema"
                              xmlns:wwproject="urn:WebWorks-Publish-Project"
                              xmlns:wwpage="urn:WebWorks-Page-Template-Schema"
                              xmlns:wwlocale="urn:WebWorks-Locale-Schema"
                              xmlns:wwprogress="urn:WebWorks-XSLT-Extension-Progress"
                              xmlns:wwlog="urn:WebWorks-XSLT-Extension-Log"
                              xmlns:wwfilesystem="urn:WebWorks-XSLT-Extension-FileSystem"
                              xmlns:wwuri="urn:WebWorks-XSLT-Extension-URI"
                              xmlns:wwstring="urn:WebWorks-XSLT-Extension-StringUtilities"
                              xmlns:wwfilesext="urn:WebWorks-XSLT-Extension-Files"
                              xmlns:wwprojext="urn:WebWorks-XSLT-Extension-Project"
                              xmlns:wwexsldoc="urn:WebWorks-XSLT-Extension-Document"
                              exclude-result-prefixes="xsl msxsl wwsplits wwtoc wwlinks wwmode wwfiles wwdoc wwbehaviors wwproject wwpage wwlocale wwprogress wwlog wwfilesystem wwuri wwstring wwfilesext wwprojext wwexsldoc"
>

 <xsl:param name="GlobalInput" />
 <xsl:param name="GlobalPipelineName" />
 <xsl:param name="GlobalProject" />
 <xsl:param name="GlobalFiles" />
 <xsl:param name="ParameterDependsType" />
 <xsl:param name="ParameterSplitsType" />
 <xsl:param name="ParameterBehaviorsType" />
 <xsl:param name="ParameterTextType" />
 <xsl:param name="ParameterHeaderType" />
 <xsl:param name="ParameterWhatIsThisTextFileType" />
 <xsl:param name="ParameterWhatIsThisHeaderFileType" />

 <xsl:output method="xml" indent="yes" encoding="UTF-8" />
 <xsl:strip-space elements="*" />

 <xsl:key name="wwfiles-files-by-groupid-type" match="wwfiles:File" use="concat(@groupID, ':', @type)" />
 <xsl:key name="wwfiles-files-by-documentid" match="wwfiles:File" use="@documentID" />
 <xsl:key name="wwsplits-files-by-groupid-type" match="wwsplits:File" use="concat(@groupID, ':', @type)" />
 <xsl:key name="wwdoc-paragraphs-by-id" match="wwdoc:Paragraph" use="@id" />
 <xsl:key name="wwbehaviors-markers-by-behavior" match="wwbehaviors:Marker" use="@behavior" />
 <xsl:key name="wwbehaviors-paragraphs-by-id" match="wwbehaviors:Paragraph" use="@id" />

 <xsl:variable name="GlobalActionChecksum">
  <xsl:variable name="VarTransformChecksums">
   <xsl:value-of select="concat(wwuri:AsFilePath('wwtransform:self'), ':', wwfilesystem:GetChecksum(wwuri:AsFilePath('wwtransform:self')))" />
  </xsl:variable>
  <xsl:value-of select="wwstring:MD5Checksum($VarTransformChecksums)" />
 </xsl:variable>

 <xsl:template match="/">
  <wwfiles:Files version="1.0">

   <!-- Iterate groups -->
   <!--                -->
   <xsl:variable name="VarProjectGroups" select="$GlobalProject/wwproject:Project/wwproject:Groups/wwproject:Group" />
   <xsl:value-of select="wwprogress:Start(count($VarProjectGroups))" />
   <xsl:for-each select="$VarProjectGroups">
    <xsl:variable name="VarProjectGroup" select="." />
    <xsl:value-of select="wwprogress:Start(1)" />

    <!-- Iterate files -->
    <!--               -->
    <xsl:for-each select="$GlobalFiles[1]">
     <xsl:variable name="VarDependsNodes" select="key('wwfiles-files-by-groupid-type', concat($VarProjectGroup/@GroupID, ':', $ParameterDependsType))" />
     <xsl:variable name="VarFilesSplits" select="key('wwfiles-files-by-groupid-type', concat($VarProjectGroup/@GroupID, ':', $ParameterSplitsType))" />

     <xsl:variable name="VarSplits" select="wwexsldoc:LoadXMLWithoutResolver($VarFilesSplits/@path)" />
     <xsl:for-each select="$VarSplits[1]">

      <xsl:variable name="VarTextPath" select="key('wwsplits-files-by-groupid-type', concat($VarProjectGroup/@GroupID, ':', $ParameterWhatIsThisTextFileType))/@path" />
      <xsl:variable name="VarHeaderPath" select="key('wwsplits-files-by-groupid-type', concat($VarProjectGroup/@GroupID, ':', $ParameterWhatIsThisHeaderFileType))/@path" />

      <xsl:if test="(string-length($VarTextPath) &gt; 0) and (string-length($VarHeaderPath) &gt; 0)">
       <!-- Up-to-date? -->
       <!--             -->
       <xsl:variable name="VarTextUpToDate" select="wwfilesext:UpToDate($VarTextPath, concat($GlobalProject/wwproject:Project/@ChangeID, ':', count($VarDependsNodes)), $VarProjectGroup/@GroupID, '', $GlobalActionChecksum)" />
       <xsl:variable name="VarHeaderUpToDate" select="wwfilesext:UpToDate($VarHeaderPath, concat($GlobalProject/wwproject:Project/@ChangeID, ':', count($VarDependsNodes)), $VarProjectGroup/@GroupID, '', $GlobalActionChecksum)" />
       <xsl:if test="not($VarTextUpToDate) or not($VarHeaderUpToDate)">
        <!-- Get Entries -->
        <!--             -->
        <xsl:variable name="VarWhatIsThisAsXML">
         <xsl:for-each select="$VarDependsNodes">
          <xsl:variable name="VarFilesDocument" select="." />

          <xsl:call-template name="WhatIsThisText">
           <xsl:with-param name="ParamFilesDocument" select="$VarFilesDocument" />
          </xsl:call-template>
         </xsl:for-each>
        </xsl:variable>
        <xsl:variable name="VarWhatIsThisNodes" select="msxsl:node-set($VarWhatIsThisAsXML)" />

        <!-- Text file -->
        <!--           -->
        <xsl:if test="not($VarTextUpToDate)">
         <xsl:variable name="VarWhatIsThisTextAsXML">
          <xsl:call-template name="WriteWhatIsThisText">
           <xsl:with-param name="ParamNodes" select="$VarWhatIsThisNodes" />
          </xsl:call-template>
         </xsl:variable>
         <xsl:variable name="VarWhatIsThisText" select="msxsl:node-set($VarWhatIsThisTextAsXML)" />
         <xsl:variable name="VarWriteWhatIsThisText" select="wwexsldoc:Document($VarWhatIsThisText, $VarTextPath, wwprojext:GetFormatSetting('encoding', 'iso-8859-1'), 'text')" />
        </xsl:if>

        <!-- Header file -->
        <!--             -->
        <xsl:if test="not($VarHeaderUpToDate)">
         <xsl:variable name="VarWhatIsThisHeaderAsXML">
          <xsl:call-template name="WriteWhatIsThisHeader">
           <xsl:with-param name="ParamNodes" select="$VarWhatIsThisNodes" />
          </xsl:call-template>
         </xsl:variable>
         <xsl:variable name="VarWhatIsThisHeader" select="msxsl:node-set($VarWhatIsThisHeaderAsXML)" />
         <xsl:variable name="VarWriterWhatIsThisHeader" select="wwexsldoc:Document($VarWhatIsThisHeader, $VarHeaderPath, wwprojext:GetFormatSetting('encoding', 'iso-8859-1'), 'text')" />
        </xsl:if>
       </xsl:if>

       <!-- Record text file -->
       <!--                  -->
       <wwfiles:File path="{$VarTextPath}" type="{$ParameterTextType}" checksum="{wwfilesystem:GetChecksum($VarTextPath)}" projectchecksum="{concat($GlobalProject/wwproject:Project/@ChangeID, ':', count($VarDependsNodes))}" groupID="{$VarProjectGroup/@GroupID}" documentID="" actionchecksum="{$GlobalActionChecksum}">
        <xsl:for-each select="$VarDependsNodes">
         <wwfiles:Depends path="{@path}" checksum="{@checksum}" groupID="{@groupID}" documentID="{@documentID}" />
        </xsl:for-each>
       </wwfiles:File>

       <!-- Record header file -->
       <!--                    -->
       <wwfiles:File path="{$VarHeaderPath}" type="{$ParameterHeaderType}" checksum="{wwfilesystem:GetChecksum($VarHeaderPath)}" projectchecksum="{concat($GlobalProject/wwproject:Project/@ChangeID, ':', count($VarDependsNodes))}" groupID="{$VarProjectGroup/@GroupID}" documentID="" actionchecksum="{$GlobalActionChecksum}">
        <xsl:for-each select="$VarDependsNodes">
         <wwfiles:Depends path="{@path}" checksum="{@checksum}" groupID="{@groupID}" documentID="{@documentID}" />
        </xsl:for-each>
       </wwfiles:File>
      </xsl:if>
     </xsl:for-each>
    </xsl:for-each>
    <xsl:value-of select="wwprogress:End()" />
   </xsl:for-each>
   <xsl:value-of select="wwprogress:End()" />
  </wwfiles:Files>
 </xsl:template>

 <xsl:template name="WhatIsThisText">
  <xsl:param name="ParamFilesDocument" />

  <xsl:for-each select="$GlobalFiles[1]">
   <xsl:variable name="VarFilesBehaviors" select="key('wwfiles-files-by-documentid', $ParamFilesDocument/@documentID)[@type = $ParameterBehaviorsType]" />

   <!-- Load behaviors -->
   <!--                -->
   <xsl:variable name="VarBehaviors" select="wwexsldoc:LoadXMLWithoutResolver($VarFilesBehaviors/@path)" />

   <!-- Find paragraphs to process -->
   <!--                            -->
   <xsl:variable name="VarBehaviorsParagraphsAsXML">
    <xsl:for-each select="$VarBehaviors[1]">
     <xsl:variable name="VarWhatIsThisIDMarkers" select="key('wwbehaviors-markers-by-behavior', 'whatis-this-id')" />

     <xsl:for-each select="$VarWhatIsThisIDMarkers">
      <xsl:variable name="VarWhatIsThisIDMarker" select="." />

      <!-- Copy parent paragraph -->
      <!--                       -->
      <xsl:copy-of select="$VarWhatIsThisIDMarker/.." />
     </xsl:for-each>
    </xsl:for-each>
   </xsl:variable>
   <xsl:variable name="VarBehaviorsParagraphs" select="msxsl:node-set($VarBehaviorsParagraphsAsXML)/wwbehaviors:Paragraph" />

   <!-- Anything to process? -->
   <!--                      -->
   <xsl:for-each select="$VarBehaviorsParagraphs[1]">
    <!-- Determine unique paragraphs to process -->
    <!--                                        -->
    <xsl:variable name="VarUniqueBehaviorsParagraphsAsXML">
     <xsl:for-each select="$VarBehaviorsParagraphs">
      <xsl:variable name="VarParagraphToProcess" select="." />

      <xsl:variable name="VarBehaviorsParagraphsWithID" select="key('wwbehaviors-paragraphs-by-id', $VarParagraphToProcess/@id)" />
      <xsl:if test="count($VarParagraphToProcess | $VarBehaviorsParagraphsWithID[1]) = 1">
       <xsl:copy-of select="$VarParagraphToProcess" />
      </xsl:if>
     </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="VarUniqueBehaviorsParagraphs" select="msxsl:node-set($VarUniqueBehaviorsParagraphsAsXML)/wwbehaviors:Paragraph" />

    <!-- Load the document -->
    <!--                   -->
    <xsl:variable name="VarDocument" select="wwexsldoc:LoadXMLWithoutResolver($ParamFilesDocument/@path)" />

    <xsl:for-each select="$VarUniqueBehaviorsParagraphs">
     <xsl:variable name="VarBehaviorsParagraph" select="." />

     <xsl:for-each select="$VarDocument[1]">
      <xsl:variable name="VarParagraph" select="key('wwdoc-paragraphs-by-id', $VarBehaviorsParagraph/@id)" />

      <xsl:variable name="VarContextRule" select="wwprojext:GetContextRule('Paragraph', $VarParagraph/@stylename, $ParamFilesDocument/@documentID, $VarParagraph/@id)" />

      <xsl:variable name="VarWhatIsThisParagraph" select="$VarContextRule/wwproject:Options/wwproject:Option[@Name = 'whatis-this']/@Value" />

      <xsl:if test="contains($VarWhatIsThisParagraph, 'define')">
       <!-- Determine WhatIsThisID -->
       <!--                        -->
       <xsl:variable name="VarWhatIsThisID">
        <xsl:variable name="VarWhatIsThisIDMarkers" select="$VarBehaviorsParagraph/wwbehaviors:Marker[@behavior = 'whatis-this-id']" />

        <!-- Take the last marker -->
        <!--                      -->
        <xsl:if test="count($VarWhatIsThisIDMarkers[1]) = 1">
         <xsl:variable name="VarWhatIsThisIDMarker" select="$VarWhatIsThisIDMarkers[count($VarWhatIsThisIDMarkers)]" />

         <xsl:for-each select="$VarWhatIsThisIDMarker/wwdoc:Marker/wwdoc:TextRun/wwdoc:Text">
          <xsl:value-of select="@value" />
         </xsl:for-each>
        </xsl:if>
       </xsl:variable>

       <xsl:choose>
        <xsl:when test="string-length($VarWhatIsThisID) &gt; 0">
         <xsl:variable name="VarParagraphText">
          <xsl:for-each select="$VarParagraph/wwdoc:TextRun/wwdoc:Text">
           <xsl:value-of select="@value" />
          </xsl:for-each>
         </xsl:variable>

         <wwpage:Entry topic="{$VarWhatIsThisID}" text="{$VarParagraphText}" />
        </xsl:when>

        <xsl:otherwise>
         <xsl:value-of select="wwlog:Warning('Marker validation failure: Unable to validate WhatIsThisID marker.  Please verify this marker exists in the source paragraph.')" />
        </xsl:otherwise>
       </xsl:choose>
      </xsl:if>
     </xsl:for-each>
    </xsl:for-each>
   </xsl:for-each>
  </xsl:for-each>
 </xsl:template>


 <xsl:template name="WriteWhatIsThisText">
  <xsl:param name="ParamNodes" />

  <xsl:for-each select="$ParamNodes/wwpage:Entry">
   <xsl:variable name="VarEntry" select="." />

   <!-- Wrap in text element to prevent memory yo-yo -->
   <!--                                              -->
   <wwexsldoc:Text>
    <xsl:text>.topic </xsl:text>
    <xsl:value-of select="$VarEntry/@topic" />
    <xsl:text>
</xsl:text>
    <xsl:value-of select="$VarEntry/@text" />
    <xsl:text>
</xsl:text>
   </wwexsldoc:Text>
  </xsl:for-each>
 </xsl:template>


 <xsl:template name="WriteWhatIsThisHeader">
  <xsl:param name="ParamNodes" />

  <xsl:for-each select="$ParamNodes/wwpage:Entry">
   <xsl:variable name="VarEntry" select="." />
   <xsl:variable name="VarPosition" select="position()" />
   <xsl:variable name="VarMapNumber" select="$VarPosition * 10" />

   <!-- Wrap in text element to prevent memory yo-yo -->
   <!--                                              -->
   <wwexsldoc:Text>
    <xsl:text>#define </xsl:text>
    <xsl:value-of select="$VarEntry/@topic" />
    <xsl:text> </xsl:text>
    <xsl:value-of select="$VarMapNumber" />
    <xsl:text>
</xsl:text>
   </wwexsldoc:Text>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
