<?xml version="1.0"?>
<!--
	
  $Id:$
  File:         sddf.xsl
  Description:  XML stylesheet which outputs an SDDF/XML file to a web
		browser in the form of an SDDF ASCII record of the SDDF data.
  Author:                William C. Wendling
  Contributing Author:

  PABLOCOPYRIGHT

	-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

<!-- Simulate built-in templates in the XSL Working Draft -->
<xsl:template match="*"><xsl:apply-templates/></xsl:template>
<xsl:template match="text()"><xsl:value-of select="."/></xsl:template>


<!-- Match the root node of the XML document -->
<xsl:template match="/">
<HTML>
<HEAD>
<BASE HREF="http://www.ncsa.uiuc.edu/~wendling/xml/sddf.xml"/>
</HEAD>
	<BODY>
<pre>
SDDFA
</pre>
<xsl:apply-templates/>
	</BODY>
</HTML>
</xsl:template>


<!--
Match the command packet tag. Output in the format:

	%17: ;;
	-->
<xsl:template match="cmd">
	<pre><xsl:eval>emitCommandPacket(this)</xsl:eval></pre>
</xsl:template>


<!--
Match the stream packet tag. Output in the format:

	/*
	 *	"key" "value"
	 */ ;;
	-->
<xsl:template match="stream">
	<pre><xsl:eval>emitStreamPacket(this)</xsl:eval></pre>
</xsl:template>


<!--
Match the descriptor packet tag. Output in the format:

	#tag_number:
	// "key" "value"
	"descr_name" {
			// "key" "value"
			int	fieldName;
			char fieldName[][];
	} ;;
	-->
<xsl:template match="descr">
	<tt>
	<xsl:element name="a">
		<xsl:attribute name="name">
			<xsl:value-of select="@tag"/>
		</xsl:attribute>
		#<xsl:value-of select="@tag"/>:
	</xsl:element>
	</tt>
	<pre><xsl:eval>emitDescriptorPacket(this)</xsl:eval></pre>
</xsl:template>


<!--
Match the data packet tag. Output in the format:
	-->
<xsl:template match="data">
	<tt>
	<xsl:element name="a">
		<xsl:attribute name="href">
			#<xsl:value-of select="@tag"/>
		</xsl:attribute>
		"<xsl:value-of select="@name"/>"
	</xsl:element>
	</tt>
	<pre><xsl:eval>emitDataPacket(this)</xsl:eval></pre>
</xsl:template>


<!-- Javascripts used in generating the dimension brackets. -->
<xsl:script><![CDATA[

/////////////////////////////////////////////////////////////////
//	SDDF Packet Scripts
//

//	emitCommandPacket
//
//	Emit the command packet in SDDF/ASCII format.
//
function emitCommandPacket(e) {
	return "%" + e.getAttribute("tag") + " ;;\n";
}

//	emitStreamPacket
//
//	Emit the stream packet in SDDF/ASCII format.
//
function emitStreamPacket(e) {
	// get a list of the attribute nodes
	a = e.selectNodes("attr");
	res = "/*\n";

	for (attr = a.nextNode(); attr != null; attr = a.nextNode()) {
		// loop through these nodes printing them out in the correct format
		res += " * \"" + attr.getAttribute("key") + "\" \"";
		res += attr.getAttribute("value") + "\"\n";
	}

	res +=" */ ;;\n";
	return res;
}

//	emitDescriptorPacket
//
//	Emit the descriptor packet in SDDF/ASCII format. Prints the tag
//	number, the attributes of the descriptor, the fields for the descriptor
//	packet and the attributes associated with them.
//
function emitDescriptorPacket(e) {
	res = "";

	a = e.selectNodes("attr");

	for (attr = a.nextNode(); attr != null; attr = a.nextNode()) {
		res += formatAttribute(attr);
	}

	res += "\"" + e.getAttribute("name") + "\" {\n";

	f = e.selectNodes("field");

	for (field = f.nextNode(); field != null; field = f.nextNode()) {
		a = field.selectNodes("attr");

		for (attr = a.nextNode(); attr != null; attr = a.nextNode()) {
			res += "\t" + formatAttribute(attr);
		}

		res += "\t" + field.getAttribute("type");
		res += "\t\"" + field.getAttribute("name");
		res += "\"" + generateDimBrackets(field) + ";\n";
	}

	res += "};;\n";
	return res;
}

//	emitDataPacket
//
//	Emit the data packet in SDDF/ASCII format. This handles dimension
//	(dim), string (str), and value (v) tags or ordinary text which can be
//	children of the field tag.
//
function emitDataPacket(e) {
	res = " { ";

	f = e.selectNodes("field");

	for (field = f.nextNode(); field != null; field = f.nextNode()) {
		s = field.selectNodes("str");
		d = field.selectNodes("dim");

		if (d.length == 0 && s.length == 0) {
			// there are no dimension or string tags, so emit the text field
			res += field.text;
		} else if (d.length > 0) {
			// we have dimension tags
			res += "\n\t";
			done = 0;

			while (done == 0) {
				dim = d.nextNode();

				if (dim != null) {
					res += "[" + dim.getAttribute("size") + "]";
					d = dim.selectNodes("dim");

					if (d.length == 0) {
						done = 1;
					}
				} else {
					done = 1;
				}
			}

			// select all value (v) nodes which are decendants of this node
			v = field.selectNodes("*//v");
			len = v.length;

			if (len > 0) {
				// we have value (v) nodes to emit
				res += " {\n\t";

				for (value = v.nextNode(); value != null; value = v.nextNode()) {
					res += value.text;
					
					if (len-- > 1) {
						// we don't want a comma after the last value
						res += ",\n\t";
					}
				}
			} else {
				// we have strings to emit. select all the string (str) nodes
				// which are decendants to this node.
				s = field.selectNodes("*//str");
				len = s.length;
				str = s.nextNode();

				// emit the (max) size of the strings
				res += "[" + str.getAttribute("size") + "] {\n\t";

				for (; str != null; str = s.nextNode()) {
					// loop through and emit the strings themselves
					res += "\"" + str.text + "\"";
					
					if (len-- > 1) {
						// we don't want a comma after the last value
						res += ",\n\t";
					}
				}
			}

			res += "\n\t}";
		} else if (s.length > 0) {
			// we only have string (str) tags
			len = s.length;
			str = s.nextNode();

			// emit the (max) size of the strings
			res += "\n\t[" + str.getAttribute("size") + "] {\n\t";

			for (; str != null; str = s.nextNode()) {
				// loop through and emit the strings themselves
				res += "\"" + str.text + "\"";
				
				if (len-- > 1) {
					// we don't want a comma after the last value
					res += ",\n\t";
				}
			}

			res += "\n\t}";
		}

		if (field != e.lastChild) {
			// only emit a comma if we aren't in the last field
			res += ", ";
		}
	}

	res += " };;\n";
	return res;
}

/////////////////////////////////////////////////////////////////
//	Generic Scripts
//

//	generateDimBrackets
//
//	A script for generating the correct number of dimension brackets
//
function generateDimBrackets(e) {
	dim = e.getAttribute("dims");
	res = "";

	for (; dim > 0; dim--) {
		res += "[]";
	}

	return res;
}

//	formatAttribute
//
//	Take an attribute and format it in a nice way.
//
//	I.e.:
//
//		// "key" "value"
//
function formatAttribute(a) {
	return "// \""+a.getAttribute("key")+"\" \""+a.getAttribute("value")+"\"\n";
}

]]></xsl:script>

</xsl:stylesheet>

