<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.1"
xmlns:aaa="http://www.w3.org/1999/XSL/TransformAlias"
xmlns:graph="http://zvon.org/graphotron"
> 

<xsl:namespace-alias stylesheet-prefix="aaa" result-prefix="xsl"/>
<xsl:output method="xml" indent="yes"/>

<xsl:variable name="lower">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="upper">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:variable name="generate-position-separator">-</xsl:variable>

<xsl:template match="*" mode="xslt">
  <xsl:param name="mode"/>
  <xsl:copy>
    <xsl:copy-of select="@*[name()!='mode']"/>
    <xsl:attribute name="mode">
      <xsl:value-of select="concat($mode,@mode)"/>
    </xsl:attribute>
    <xsl:apply-templates mode="xslt">
      <xsl:with-param name="mode" select="$mode"/>
    </xsl:apply-templates>
  </xsl:copy>
</xsl:template>

<xsl:template match="graph:script[@type='xslt']">
  <xsl:param name="mode"/>

  <xsl:for-each select="xsl:template">
    <aaa:template>
      <xsl:copy-of select="@*[name()!='mode']"/>
      <xsl:attribute name="mode">
	<xsl:value-of select="concat($mode,@mode)"/>
      </xsl:attribute>
      <xsl:apply-templates mode="xslt">
	<xsl:with-param name="mode" select="$mode"/>
      </xsl:apply-templates>
    </aaa:template>
  </xsl:for-each>
</xsl:template>


<xsl:template match="/">
  <aaa:stylesheet version="1.1" >
    <xsl:for-each select="*/namespace::*">
      <xsl:variable name="xxx">
	<xsl:if test="string-length(name())&gt;0">
	  <xsl:text>:</xsl:text>
	</xsl:if>
      </xsl:variable>
      <xsl:if test=". != 'http://www.w3.org/XML/1998/namespace'">
	<xsl:attribute name="{name()}{$xxx}foo" namespace="{.}"/>
      </xsl:if>
    </xsl:for-each>

    <aaa:output method="text"/>

    <xsl:for-each select="/*/graph:key">
      <aaa:key>
	<xsl:copy-of select="@*"/>
      </aaa:key>
    </xsl:for-each>

    <xsl:for-each select="/*/graph:variable | /*/graph:param">
      <xsl:element name="aaa:{local-name()}" namespace="http://www.w3.org/1999/XSL/Transform">
	<xsl:copy-of select="@name"/>

	<xsl:choose>
	  <xsl:when test="graph:script[@type='xslt']">
	    <aaa:apply-templates select="/" mode="__{@name}__"/>
	  </xsl:when>
	  <xsl:otherwise>
	    <xsl:value-of select="text()"/>
	  </xsl:otherwise>
	</xsl:choose>
      </xsl:element>

      <xsl:apply-templates select="graph:script[@type='xslt']">
	<xsl:with-param name="mode">
	  <xsl:text>__</xsl:text>
	  <xsl:value-of select="@name"/>
	  <xsl:text>__</xsl:text>
	</xsl:with-param>
      </xsl:apply-templates>
    </xsl:for-each>

    <aaa:template name="process_value_of">
      <aaa:param name="select"/>
      <aaa:param name="select-from-target"/>
      <aaa:param name="value-of"/>
      <aaa:variable name="quotes">"'</aaa:variable>

      <aaa:choose>
	<xsl:for-each select="/*/graph:edge">
	  <xsl:for-each select="*[@value-of and namespace-uri() != 'http://zvon.org/graphotron']">
	    <xsl:variable name="__rrr">
	      <xsl:variable name="quotes">"'</xsl:variable>
	      <xsl:value-of select='translate(@value-of,$quotes,"%%")'/>
	    </xsl:variable>
	    <aaa:when test="translate($value-of,$quotes,'%%')='{$__rrr}'">
	      <aaa:value-of select="{@value-of}"/>
	    </aaa:when>
	  </xsl:for-each>
	</xsl:for-each>
	<aaa:when test="true()"/>
      </aaa:choose>
    </aaa:template>


  <aaa:template match="/">
    <aaa:variable name="xxx">
      <aaa:apply-templates select="//node() | //*/@*" mode="createVertex"/>
    </aaa:variable>

    <xsl:call-template name="header">
      <xsl:with-param name="params">
	<xsl:for-each select="/*/graph:global-settings/*">
	  <xsl:copy>
	    <xsl:if test="@select">
	      <selection>
		<aaa:value-of select="{@select}"/>
	      </selection>
	    </xsl:if>
	    <default>
	      <xsl:value-of select="."/>
	    </default>
	  </xsl:copy>
	</xsl:for-each>
      </xsl:with-param>
    </xsl:call-template>

    <aaa:apply-templates select="$xxx/v" mode="printText"/>
    
    <xsl:call-template name="call-print-edges"/>
    <xsl:call-template name="footer"/>
  </aaa:template>

    <aaa:template name="printParamValue">
      <aaa:param name="xslt-target-id"/>
      <aaa:param name="value"/>

      <aaa:variable name="__xyz">
	<aaa:choose>
	  <aaa:when test="$value/selection/startEdge">
	    <aaa:call-template name="process_value_of">
	      <aaa:with-param name="select" select="$value/selection/startEdge"/>
	      <aaa:with-param name="select-from-target" select="substring-before(substring-after($value,concat('@#1#$',$xslt-target-id,'@#2#$')),'@#3#$')"/>
	      <aaa:with-param name="value-of" select="$value/selection/value-of"/>
	    </aaa:call-template>
	  </aaa:when>
	  <aaa:when test="starts-with($value/selection,'@#1#$')">
	    <aaa:value-of select="substring-before(substring-after($value,concat('@#1#$',$xslt-target-id,'@#2#$')),'@#3#$')"/>
	  </aaa:when>
	  <aaa:otherwise>
	    <aaa:value-of select="$value/selection"/>
	  </aaa:otherwise>
	</aaa:choose>
      </aaa:variable>

      <aaa:choose>
	<aaa:when test="normalize-space($__xyz) = '' ">
	  <aaa:value-of select="$value/default"/>
	</aaa:when>
	<aaa:otherwise>
	  <aaa:value-of select="$__xyz"/>
	</aaa:otherwise>
      </aaa:choose>
    </aaa:template>

    <aaa:template match="node()|@*" mode="createEdgeTarget"/>

    <aaa:template match="node()|@*" mode="edgeTarget">
      <aaa:param name="edge-id"/>
      <aaa:param name="origin"/>
      <aaa:param name="params" select="/parent::*"/>

      <aaa:variable name="xxx">
	<aaa:apply-templates select="." mode="createEdgeTarget"/>
      </aaa:variable>

      <aaa:if test="string-length($xxx) &gt; 0">
	<aaa:call-template name="createEdge">
	  <aaa:with-param name="edge-id" select="$edge-id"/>
	  <aaa:with-param name="origin" select="$origin"/>
	  <aaa:with-param name="target" select="$xxx"/>
	  <aaa:with-param name="params" select="$params"/>
	  <aaa:with-param name="xslt-target-id" select="generate-id()"/>
	</aaa:call-template>
      </aaa:if>
    </aaa:template>

    <aaa:template match="*" mode="create-generate-position">
      <aaa:apply-templates select="parent::*" mode="create-generate-position"/>
      <aaa:value-of select="count(preceding-sibling::*)+1"/>
      <aaa:text><xsl:value-of select="$generate-position-separator"/></aaa:text>
    </aaa:template>

    <aaa:template name="create-generate-position">
      <aaa:variable name="xxx">
	<aaa:variable name="yyy">
	  <aaa:apply-templates select="." mode="create-generate-position"/>	
	</aaa:variable>
	<aaa:value-of select="substring($yyy,1,string-length($yyy)-{string-length($generate-position-separator)})"/> 
      </aaa:variable>
      <aaa:value-of select="$xxx"/> 
    </aaa:template>

    <xsl:call-template name="printParam"/>

    <aaa:template name="createVertex">
      <aaa:param name="name"/>
      <aaa:param name="generate-position"/>
      <aaa:param name="params" select='/parent::*'/>

      <xsl:call-template name='printNode'/>
      
      <xsl:for-each select="/*/graph:edge"> 
	<aaa:apply-templates select="." mode="createEdge{position()}">
	  <aaa:with-param name="origin">
	    <xsl:call-template name="vertex-id"/>
	  </aaa:with-param>
	</aaa:apply-templates>
      </xsl:for-each>
    </aaa:template>

    <aaa:template name="createEdge">
      <aaa:param name="edge-id"/>
      <aaa:param name="origin"/>
      <aaa:param name="target"/>
      <aaa:param name="xslt-target-id"/>
      <aaa:param name="params" select="/parent::*"/>

      <e>
	<xsl:call-template name='printEdge'/>
      </e>
    </aaa:template>

    <aaa:template match="node()|@*" mode="createVertex"/>
    <xsl:for-each select="/*/graph:edge"> 
      <aaa:template match="node()|@*" mode="createEdge{position()}"/>
    </xsl:for-each>

    <xsl:apply-templates select="/*/graph:vertex" mode="createVertex"/>
    <xsl:apply-templates select="/*/graph:edge[1]" mode="createEdge"/>

  </aaa:stylesheet>

</xsl:template>


<xsl:template match="graph:edge" mode="createEdge">
  <xsl:param name="id" select="1"/>
  <xsl:variable name="match" select="@match"/>
  <xsl:variable name="select" select="@select"/>

  <xsl:for-each select="*[@select and namespace-uri() != 'http://zvon.org/graphotron']">
    <aaa:template match="node()|@*" mode="selectEdge{generate-id()}">
      <aaa:value-of select="{@select}"/>
    </aaa:template>
  </xsl:for-each>

  <xsl:for-each select="*[@select-from-target and namespace-uri() != 'http://zvon.org/graphotron']">
    <aaa:template match="node()|@*" mode="select_from_targetEdge{generate-id()}">
      <aaa:apply-templates select="{parent::*/@select}" mode="select_from_targetEdge2{generate-id()}"/>
    </aaa:template>
    <aaa:template match="node()|@*" mode="select_from_targetEdge2{generate-id()}">
      <aaa:text>@#1#$</aaa:text>
      <aaa:value-of select="generate-id()"/>
      <aaa:text>@#2#$</aaa:text>
      <aaa:value-of select="{@select-from-target}"/>
      <aaa:text>@#3#$</aaa:text>
    </aaa:template>
  </xsl:for-each>


  <aaa:template match="{$match}" mode="createEdgeSelect{$id}" priority="10">
    <aaa:value-of select="{@select}"/>
  </aaa:template>

  <aaa:template match="{$match}" mode="createEdge{$id}" priority="10">
    <aaa:param name="origin"/>

    <aaa:apply-templates select="{@select}" mode="edgeTarget">
      <aaa:with-param name="origin" select="$origin"/>
      <aaa:with-param name="edge-id" select="'{generate-id()}'"/>

      <xsl:if test="*[namespace-uri() != 'http://zvon.org/graphotron']">
	<aaa:with-param name="params">
	  <xsl:for-each select="*[namespace-uri() != 'http://zvon.org/graphotron']">
	    <xsl:copy>
	      <aaa:variable name="__xyz">
		<xsl:choose>
		  <xsl:when test="@value-of">
		    <startEdge>
		      <aaa:apply-templates select="." mode="selectEdge{generate-id()}"/>
		    </startEdge>
		    <targetEdge>
		      <aaa:apply-templates select="." mode="select_from_targetEdge{generate-id()}"/>
		    </targetEdge>
		    <value-of>
		      <xsl:value-of select="@value-of"/>
		    </value-of>
		  </xsl:when>

		  <xsl:when test="@select">
		      <aaa:apply-templates select="." mode="selectEdge{generate-id()}"/>
		  </xsl:when>

		  <xsl:when test="@select-from-target">
		    <aaa:apply-templates select="." mode="select_from_targetEdge{generate-id()}"/>
		  </xsl:when>
		</xsl:choose>
	      </aaa:variable>
	      
	      <selection>
		<aaa:copy-of select="$__xyz"/>
	      </selection>
	      <default>
		<xsl:value-of select="."/>
	      </default>
	    </xsl:copy>
	  </xsl:for-each>
	</aaa:with-param>
      </xsl:if>
    </aaa:apply-templates>
  </aaa:template>

  <xsl:apply-templates select="following-sibling::graph:edge[1]" mode="createEdge"> 
    <xsl:with-param name="id" select="$id+1"/>
  </xsl:apply-templates>
</xsl:template>


<xsl:template match="graph:vertex" mode="createVertex">
  <aaa:template match="{@match}" priority="{position()+10}" mode="createVertex">
    <xsl:variable name="rrr">
      <xsl:variable name="sss">
	<aaa:variable name="__xyz">
	  <xsl:if test="graph:name/@select">
	    <aaa:value-of select="{graph:name/@select}"/>
	  </xsl:if>
	</aaa:variable>

	<aaa:choose>
	  <aaa:when test="normalize-space($__xyz)=''">
	    <xsl:value-of select="graph:name"/>
	  </aaa:when>
	  <aaa:otherwise>
	    <aaa:value-of select="$__xyz"/>
	  </aaa:otherwise>
	</aaa:choose>
      </xsl:variable>

      <aaa:call-template name="createVertex">
	<aaa:with-param name="name">
	  <xsl:copy-of select="$sss"/>
	</aaa:with-param>
	<aaa:with-param name="generate-position" select="'{graph:name/@generate-position}'"/>
	
	<xsl:if test="*[namespace-uri() != 'http://zvon.org/graphotron']">
	  <aaa:with-param name="params">
	    <xsl:for-each select="*[namespace-uri() != 'http://zvon.org/graphotron']">
	      <xsl:copy>
		<xsl:if test="@select">
		  <selection>
		    <aaa:value-of select="{@select}"/>
		  </selection>
		</xsl:if>
		<default>
		  <xsl:value-of select="."/>
		</default>
	      </xsl:copy>
	    </xsl:for-each>
	  </aaa:with-param>
	</xsl:if>
      </aaa:call-template>
    </xsl:variable>
    
    <xsl:choose>
      <xsl:when test='graph:condition'>
	<aaa:if test='{graph:condition/@test}'>
	  <xsl:copy-of select="$rrr"/>
	</aaa:if>
      </xsl:when>
      <xsl:otherwise><xsl:copy-of select="$rrr"/></xsl:otherwise>
    </xsl:choose>

  </aaa:template>

  <aaa:template match="{@match}" priority="{position()+10}" mode="createEdgeTarget">
    <xsl:call-template name="vertex-id"/>
  </aaa:template>
</xsl:template>

</xsl:stylesheet>
