// JavaScript Document

function XSLTransform(xml, xsl, cacheXml, cacheXsl, onComplete)
{
	this.xmlPath	= (typeof(xml) == 'string')? xml : null;
	this.xslPath	= (typeof(xsl) == 'string')? xsl : null;

	this.cacheXml	= (cacheXml != false);
	this.cacheXsl	= (cacheXsl != false);

	this.xml		= (typeof(xml) == 'object')? xml : null;
	this.xsl		= (typeof(xsl) == 'object')? xsl : null;

	this.xmlProxy	= null;
	this.xslProxy	= null;

	this.onComplete	= onComplete;

	this.transform = function(xml, xsl, xslVars, element)
	{
		var result = '';
		var serializer;
		var xsltProcessor;
		var xslMSObject;
		var xslDoc;
		
		// code for IE
		if (window.ActiveXObject)
		{
			xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
			xslDoc.loadXML(xsl.xml);

			xslMSObject = new ActiveXObject("Msxml2.XSLTemplate");
			xslMSObject.stylesheet = xslDoc;
			
			xsltProcessor = xslMSObject.createProcessor();
			xsltProcessor.input = xml;
			
			if(xslVars)
			{
				for(var i in xslVars)
				{
					if(xslVars[i] != null && typeof(xslVars[i]) != 'undefined')
					{
						xsltProcessor.addParameter(i, xslVars[i]);
					}
				}
			}
			xsltProcessor.transform();
			result = xsltProcessor.output;

			if(element)
			{
				element.innerHTML = result;
			}
		}
		// code for Mozilla, Firefox, Opera, etc.
		else if (document.implementation && document.implementation.createDocument)
		{
			xsltProcessor	= new XSLTProcessor();
			xsltProcessor.importStylesheet(xsl);
			if(xslVars)
			{
				for(var i in xslVars)
				{
					if(xslVars[i] != null && typeof(xslVars[i]) != 'undefined')
					{
						xsltProcessor.setParameter('',i,xslVars[i]);
					}
				}
			}
			
			result = xsltProcessor.transformToFragment(xml,document);

			serializer = new XMLSerializer();
		    result = serializer.serializeToString(result);	
			if(element)
			{
				element.innerHTML = result;
			}
		}
		
		if(typeof(this.onComplete) == 'function')
		{
			this.onComplete(result);
		}
		
		if(!this.cacheXml)
		{
			this.xml = null;
		}
		if(!this.cacheXsl)
		{
			this.xsl = null;
		}
		
		return result;
	}
	
	this.update	= function(xml, xslVars, onComplete)
	{
		var self		= this;
		
		if(typeof(xml) == 'string')
		{
			this.xmlPath = xml;
			this.xml = null;
		}
		else if(typeof(xml) == 'object')
		{
			this.xml = xml;
		}
		
		this.xslVars	= (typeof(xslVars) == 'object')? xslVars : this.xslVars;
		this.onComplete	= (typeof(onComplete) == 'function')? onComplete : this.onComplete;
		
		if(this.xml != null && this.xsl != null)
		{
			this.transform(this.xml, this.xsl, this.xslVars);
		}
		else
		{
			if(!this.cacheXml || this.xml == null)
			{
				this.xml = null;
				this.xmlProxy	= new XMLProxy(this.cacheXml);
				this.xmlProxy.load(this.xmlPath, function(xml) {self.onXmlLoadedHandler(xml);});
			}
			
			if(!this.cacheXsl || this.xsl == null)
			{
				this.xsl = null;
				this.xslProxy	= new XMLProxy(this.cacheXsl);
				this.xslProxy.load(this.xslPath, function(xml) {self.onXslLoadedHandler(xml);});
			}
		}
	}
	
	this.clear = function()
	{
		if(this.xml == null && this.xmlProxy != null)
		{
			this.xmlProxy.onReadyStateHandler = function() {};
			this.xmlProxy = null;
		}

		if(this.xsl == null && this.xslProxy != null)
		{
			this.xslProxy.onReadyStateHandler = function() {};
			this.xslProxy = null;
		}
	}
	
	this.onXmlLoadedHandler = function(xml)
	{
		this.xml		= xml;
		this.xmlProxy	= null;

		if(this.xml && this.xsl)
		{
			this.transform(this.xml, this.xsl, this.xslVars);
		}
	}
	
	this.onXslLoadedHandler = function(xsl)
	{
		this.xsl		= xsl;
		this.xslProxy	= null;
		
		if(this.xml && this.xsl)
		{
			this.transform(this.xml, this.xsl, this.xslVars);
		}
	}
}

function XMLProxy(cache)
{
	this.request	= null;
	this.cache		= (cache == true);
	
	this.load = function(url, onComplete, postData)
	{
		var self		= this;
		var method;
		
		if(!this.cache)
		{
			url = appendUrlVar(url, 'r', Math.ceil(Math.random() * 1000000));
		}
		this.onComplete	= onComplete;
		this.request	= null;
		
		method = (postData)? 'POST' : 'GET';
		
		if (window.XMLHttpRequest) { // Mozilla, Safari,...
			this.request = new XMLHttpRequest();
		
			if(typeof(firebug) == 'object' && firebug.env.init)
			{
				firebug.watchXHR(this.request);
			}
		}
		else if (window.ActiveXObject) { // IE
			try {
				this.request = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (e) {
				try {
					this.request = new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch (e) {}
			}
		}
		if (!this.request) {
			return false;
		}

		this.request.url = url;
		this.request.onreadystatechange = function() { self.onReadyStateHandler(); };
		this.request.open(method, url, true);
		if(method == 'POST')
		{
			this.request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		}
		this.request.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
		this.request.send(postData);
	}
	
	this.onReadyStateHandler = function()
	{
		var xml, e;
		
//		try
//		{
			switch(this.request.readyState)
			{
				case 0:	//uninitialized
					break;
				case 1:	//loading
					break;
				case 2:	//loaded
					break;
				case 3:	//interactive
					break;
				case 4:	//complete
					if(this.request.status == 200)
					{
						if(typeof(this.onComplete) == 'function')
						{
							if (window.ActiveXObject) {
								xml = new ActiveXObject("Microsoft.XMLDOM");
								xml.loadXML(this.request.responseText);
							}
							else
							{
								xml = this.request.responseXML;
							}
							
							this.onComplete(xml);
							this.request = null;
						}
					}
					else
					{
						if(typeof(console) != 'undefined')
						{
							console.debug(this.request.responseText);
						}
					}
					break;
				default: break;
			}
//		}
/*		catch(e)
		{
			if(typeof(console) != 'undefined')
			{
				console.error(e.message, e);
			}
		}
*/
	}
}

function toQueryParams(object)
{
	var i, j, value, str = '';
	
	for(i in object)
	{
		if(object[i] != null && typeof(object[i]) == 'object')
		{
			if(typeof(object[i].tagName) == 'undefined' && typeof(object[i].length) != 'undefined')
			{
				for(j = 0; j < object[i].length; j++)
				{
					value = getValue(object[i][j]);
					if(value != null)
					{
						if(str.length > 0)
						{
							str += '&';
						}
						str += i + '=' + encodeURIComponent(value);
					}
				}
			}
			else
			{
				value = getValue(object[i]);
				if(value != null)
				{
					if(str.length > 0)
					{
						str += '&';
					}
					str += i + '=' + encodeURIComponent(value);
				}
			}
		}
		else if(object[i] != null)
		{
			if(typeof(object[i]) != 'undefined')
			{
				if(str.length > 0)
				{
					str += '&';
				}
				str += i + '=' + encodeURIComponent(object[i]);
			}
		}
	}
	return str;
}

function appendUrlVar(url, name, value)
{
	var delimiter;
	
	if(url.indexOf('?') == -1)
	{
		delimiter	= '?';
	}
	else
	{
		delimiter	= '&';
	}
	
	return url + delimiter + name + '=' + escape(value);
}