<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
		xmlns:f="http://nwalsh.com/f"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
		exclude-result-prefixes="f xs"
		version="2.0">

<!-- Version 0.99 by Norman Walsh, ndw@nwalsh.com -->

<xsl:output method="xml" encoding="utf-8" indent="yes"
	    omit-xml-declaration="yes"/>

<xsl:param name="xsl-version" select="2.0"/>

<xsl:variable name="empty" as="xs:string">
  <xsl:choose>
    <xsl:when test="$xsl-version &gt;= 2">()</xsl:when>
    <xsl:otherwise>''</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:template match="flickr.api">
  <xsl:element name="xsl:stylesheet">
    <xsl:namespace name="xsl" select="'http://www.w3.org/1999/XSL/Transform'"/>
    <xsl:namespace name="f" select="'http://www.flickr.com/services/api/'"/>
    <xsl:namespace name="xs" select="'http://www.w3.org/2001/XMLSchema'"/>
    <xsl:namespace name="digest"
		   select="'http://nwalsh.com/xslt/ext/com.nwalsh.xslt.Digest'"/>
    <xsl:attribute name="version" select="$xsl-version"/>
    <xsl:attribute name="exclude-result-prefixes" select="'digest f xs'"/>

    <xsl:element name="xsl:param">
      <xsl:attribute name="name" select="'f:api_key'"/>
      <xsl:attribute name="select" select="$empty"/>
    </xsl:element>

    <xsl:element name="xsl:param">
      <xsl:attribute name="name" select="'f:shared_secret'"/>
      <xsl:attribute name="select" select="$empty"/>
    </xsl:element>

    <xsl:element name="xsl:param">
      <xsl:attribute name="name" select="'f:auth_token'"/>
      <xsl:attribute name="select" select="$empty"/>
    </xsl:element>

    <xsl:element name="xsl:param">
      <xsl:attribute name="name" select="'f:debug'"/>
      <xsl:attribute name="select" select="'false()'"/>
    </xsl:element>

    <xsl:element name="xsl:template">
      <xsl:attribute name="name" select="'f:flickr'"/>
      <xsl:if test="$xsl-version &gt;= 2">
	<xsl:attribute name="as" select="'element()'"/>
      </xsl:if>
      <xsl:element name="xsl:param">
	<xsl:attribute name="name" select="'method'"/>
	<xsl:if test="$xsl-version &gt;= 2">
	  <xsl:attribute name="as" select="'xs:string'"/>
	  <xsl:attribute name="required" select="'yes'"/>
	</xsl:if>
      </xsl:element>
      <xsl:element name="xsl:param">
	<xsl:attribute name="name" select="'uriparams'"/>
	<xsl:if test="$xsl-version &gt;= 2">
	  <xsl:attribute name="as" select="'xs:string'"/>
	  <xsl:attribute name="required" select="'yes'"/>
	</xsl:if>
      </xsl:element>

      <xsl:element name="xsl:if">
	<xsl:attribute name="test"
		       select="if ($xsl-version &gt;= 2)
			       then 'empty($f:api_key)'
			       else '$f:api_key = &apos;&apos;&apos;&apos;'"/>
	<xsl:element name="xsl:message">
	  <xsl:attribute name="terminate" select="'yes'"/>
	  <xsl:element name="xsl:text">
	    <xsl:text>Error: you must specify an api_key for Flickr.</xsl:text>
	  </xsl:element>
	</xsl:element>
      </xsl:element>

      <xsl:element name="xsl:variable">
	<xsl:attribute name="name" select="'uri'"/>
	<xsl:element name="xsl:text">
	  <xsl:text>http://www.flickr.com/services/rest/?method=</xsl:text>
	</xsl:element>
	<xsl:element name="xsl:value-of">
	  <xsl:attribute name="select" select="'$method'"/>
	</xsl:element>
	<xsl:element name="xsl:value-of">
	  <xsl:attribute name="select" select="'$uriparams'"/>
	</xsl:element>
      </xsl:element>

      <xsl:element name="xsl:if">
	<xsl:attribute name="test" select="'$f:debug'"/>
	<xsl:element name="xsl:message">
	  <xsl:element name="xsl:text">
	    <xsl:text>FLICKR: </xsl:text>
	  </xsl:element>
	  <xsl:element name="xsl:value-of">
	    <xsl:attribute name="select" select="'$uri'"/>
	  </xsl:element>
	</xsl:element>
      </xsl:element>

      <xsl:choose>
	<xsl:when test="$xsl-version &gt;= 2">
	  <xsl:element name="xsl:sequence">
	    <xsl:attribute name="select" select="'document($uri)/*'"/>
	  </xsl:element>
	</xsl:when>
	<xsl:otherwise>
	  <xsl:element name="xsl:copy-of">
	    <xsl:attribute name="select" select="'document($uri)/*'"/>
	  </xsl:element>
	</xsl:otherwise>
      </xsl:choose>
    </xsl:element>

    <xsl:element name="xsl:template">
      <xsl:attribute name="name" select="'f:flickr.auth'"/>
      <xsl:if test="$xsl-version &gt;= 2">
	<xsl:attribute name="as" select="'xs:string'"/>
      </xsl:if>

      <xsl:element name="xsl:param">
	<xsl:attribute name="name" select="'sig'"/>
      </xsl:element>

      <xsl:element name="xsl:if">
	<xsl:attribute name="test"
		       select="if ($xsl-version &gt;= 2)
			       then 'empty($f:auth_token)'
			       else '$f:auth_token = &apos;&apos;&apos;&apos;'"/>
	<xsl:element name="xsl:message">
	  <xsl:attribute name="terminate" select="'yes'"/>
	  <xsl:element name="xsl:text">
	    <xsl:text>Error: you must specify an api_key for Flickr.</xsl:text>
	  </xsl:element>
	</xsl:element>
      </xsl:element>

      <!--
      <xsl:element name="xsl:if">
	<xsl:attribute name="test" select="'$f:debug'"/>
	<xsl:element name="xsl:message">
	  <xsl:element name="xsl:text">
	    <xsl:text>DIGEST OF: </xsl:text>
	  </xsl:element>
	  <xsl:element name="xsl:value-of">
	    <xsl:attribute name="select" select="'concat($f:shared_secret,$sig)'"/>
	  </xsl:element>
	</xsl:element>
      </xsl:element>
      -->

      <xsl:element name="xsl:value-of">
	<xsl:attribute name="select"
		       select="'digest:md5(concat($f:shared_secret,$sig))'"/>
      </xsl:element>
    </xsl:element>

    <xsl:apply-templates select="method"/>
  </xsl:element>
</xsl:template>

<xsl:template match="method">
  <xsl:variable name="methodName" select="@name"/>

  <xsl:element name="xsl:template">
    <xsl:attribute name="name">
      <xsl:text>f:</xsl:text>
      <xsl:value-of select="substring-after(@name, 'flickr.')"/>
    </xsl:attribute>

    <xsl:if test="$xsl-version &gt;= 2">
      <xsl:attribute name="as" select="'element()'"/>
    </xsl:if>

    <xsl:element name="xsl:param">
      <xsl:attribute name="name" select="'api_key'"/>
      <xsl:if test="$xsl-version &gt;= 2">
	<xsl:attribute name="as" select="'xs:string?'"/>
      </xsl:if>
      <xsl:attribute name="select" select="'$f:api_key'"/>
    </xsl:element>

    <xsl:for-each select="param[@name != 'api_key']">
      <xsl:element name="xsl:param">
	<xsl:attribute name="name" select="@name"/>

	<xsl:if test="$xsl-version &gt;= 2">
	  <xsl:attribute name="as">
	    <xsl:value-of select="if (@type) then @type else 'xs:string'"/>
	    <xsl:text>?</xsl:text>
	  </xsl:attribute>
	</xsl:if>

	<xsl:choose>
	  <xsl:when test="@use = 'required' and $xsl-version &gt;= 2">
	    <xsl:attribute name="required" select="'yes'"/>
	  </xsl:when>
	  <xsl:otherwise>
	    <xsl:attribute name="select">
	      <xsl:value-of select="$empty"/>
	    </xsl:attribute>
	  </xsl:otherwise>
	</xsl:choose>
      </xsl:element>
    </xsl:for-each>

    <xsl:element name="xsl:variable">
      <xsl:attribute name="name" select="'uriparams'"/>

      <xsl:for-each select="param">
	<xsl:choose>
	  <xsl:when test="$xsl-version &gt;= 2">
	    <xsl:element name="xsl:value-of">
	      <xsl:attribute name="select">
		<xsl:text>if (exists($</xsl:text>
		<xsl:value-of select="@name"/>
		<xsl:text>)) then concat('&amp;</xsl:text>
		<xsl:value-of select="@name"/>
		<xsl:text>=', $</xsl:text>
		<xsl:value-of select="@name"/>
		<xsl:text>) else ''</xsl:text>
	      </xsl:attribute>
	    </xsl:element>
	  </xsl:when>
	  <xsl:otherwise>
	    <xsl:element name="xsl:if">
	      <xsl:attribute name="test">
		<xsl:text>$</xsl:text>
		<xsl:value-of select="@name"/>
		<xsl:text> != ''</xsl:text>
	      </xsl:attribute>
	      <xsl:element name="xsl:text">
		<xsl:text>&amp;</xsl:text>
		<xsl:value-of select="@name"/>
		<xsl:text>=</xsl:text>
	      </xsl:element>
	      <xsl:element name="xsl:value-of">
		<xsl:attribute name="select">
		  <xsl:value-of select="concat('$',@name)"/>
		</xsl:attribute>
	      </xsl:element>
	    </xsl:element>
	  </xsl:otherwise>
	</xsl:choose>
      </xsl:for-each>

      <xsl:element name="xsl:if">
	<xsl:attribute name="test">
	  <xsl:if test="@auth">true() or </xsl:if>
	  <xsl:choose>
	    <xsl:when test="$xsl-version &gt;= 2">
	      <xsl:attribute name="test">exists($f:auth_token)</xsl:attribute>
	    </xsl:when>
	    <xsl:otherwise>
	      <xsl:attribute name="test">$f:auth_token != ''</xsl:attribute>
	    </xsl:otherwise>
	  </xsl:choose>
	</xsl:attribute>

	<xsl:element name="xsl:text">
	  <xsl:text>&amp;auth_token=</xsl:text>
	</xsl:element>
	<xsl:element name="xsl:value-of">
	  <xsl:attribute name="select" select="'$f:auth_token'"/>
	</xsl:element>

	<xsl:element name="xsl:text">
	  <xsl:text>&amp;api_sig=</xsl:text>
	</xsl:element>

	<xsl:variable name="augparam" as="element()+">
	  <param name="method"/>
	  <param name="auth_token"/>
	  <xsl:copy-of select="param"/>
	</xsl:variable>

	<xsl:element name="xsl:call-template">
	  <xsl:attribute name="name" select="'f:flickr.auth'"/>
	  <xsl:element name="xsl:with-param">
	    <xsl:attribute name="name" select="'sig'"/>

	    <xsl:for-each select="$augparam">
	      <xsl:sort data-type="text" order="ascending" select="@name"/>

	      <xsl:choose>
		<xsl:when test="@name = 'method'">
		  <xsl:element name="xsl:text">
		    <xsl:text>method</xsl:text>
		    <xsl:value-of select="$methodName"/>
		  </xsl:element>
		</xsl:when>
		<xsl:when test="@name = 'auth_token'">
		  <xsl:element name="xsl:text">
		    <xsl:value-of select="@name"/>
		  </xsl:element>
		  <xsl:element name="xsl:value-of">
		    <xsl:attribute name="select" select="'$f:auth_token'"/>
		  </xsl:element>
		</xsl:when>
		<xsl:when test="$xsl-version &gt;= 2">
		  <xsl:element name="xsl:value-of">
		    <xsl:attribute name="select">
		      <xsl:text>if (exists($</xsl:text>
		      <xsl:value-of select="@name"/>
		      <xsl:text>)) then concat('</xsl:text>
		      <xsl:value-of select="@name"/>
		      <xsl:text>', $</xsl:text>
		      <xsl:value-of select="@name"/>
		      <xsl:text>) else ''</xsl:text>
		    </xsl:attribute>
		  </xsl:element>
		</xsl:when>
		<xsl:otherwise>
		  <xsl:element name="xsl:if">
		    <xsl:attribute name="test">
		      <xsl:text>$</xsl:text>
		      <xsl:value-of select="@name"/>
		      <xsl:text> != ''</xsl:text>
		    </xsl:attribute>
		    <xsl:element name="xsl:text">
		      <xsl:value-of select="@name"/>
		    </xsl:element>
		    <xsl:element name="xsl:value-of">
		      <xsl:attribute name="select">
			<xsl:value-of select="concat('$',@name)"/>
		      </xsl:attribute>
		    </xsl:element>
		  </xsl:element>
		</xsl:otherwise>
	      </xsl:choose>
	    </xsl:for-each>
	  </xsl:element>
	</xsl:element>
      </xsl:element>
    </xsl:element>

    <xsl:element name="xsl:call-template">
      <xsl:attribute name="name" select="'f:flickr'"/>
      <xsl:element name="xsl:with-param">
	<xsl:attribute name="name" select="'method'"/>
	<xsl:attribute name="select" select='concat("&apos;",@name,"&apos;")'/>
      </xsl:element>
      <xsl:element name="xsl:with-param">
	<xsl:attribute name="name" select="'uriparams'"/>
	<xsl:attribute name="select" select="'$uriparams'"/>
      </xsl:element>
    </xsl:element>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>
