/*
	LiveUpdater, copyright @copy; 2005 Drew Butler
	http://www.digitalanxiety.org
	nodrew@hotmail.com
	
	This class functionality is open source and freely available
	under the Creative Commons License. While it is not necessary,
	input, feedback and changes are appreciated.
*/

var debugMode = false;

function LiveUpdater( uri, data, handlerFunc, postFunc, target )
{
	var toolkit 		= new nodeHelper();
	var uri 			= uri;
	var data 			= data;
	var handlerFunc 	= handlerFunc;
	var postFunc		= postFunc;
	var xmlBaseTag 		= "lu";
	
	if ( !target ) {
		var target = document;
	} else {
		var target = target;
	}
	
	function getRequester() 
	{	
		if ( window.XMLHttpRequest ) {
			return new XMLHttpRequest();
	
		} else if ( window.ActiveXObject ) {
			try {
				return new ActiveXObject( "Msxml2.XMLHTTP" );
	
			} catch ( error ) {
				try {
					return new ActiveXObject( "Microsoft.XMLHTTP" );
	
				} catch ( error2 ) {
					return false;
				}
			}
		}
	}
	
	
	function getReadyStateHandler( requester, xmlHandler ) 
	{
		return function () 
		{
			if ( requester.readyState == 4 ) {     
				if ( requester.status == 200 ) {
					try {
						var xml = requester.responseXML;        
						
					} catch( e ) {
						if ( debugMode ) {
							alert (requester.responseText);  		
						}   
						
						return false;
					}						
					//alert (requester.responseText);
					xmlHandler( xml );
	
				} else {
					if ( debugMode == true ) {
						alert( "An error occurred: "+requester.status );
					}
				}
			}
		}
	}
	

	function makeXMLRequest() 
	{
		var requester = getRequester();
		
			
		var handlerFunction = getReadyStateHandler( requester, handleXML );
		
		requester.onreadystatechange = handlerFunction;
		
		requester.open( "POST", uri, true );
		requester.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );		
		requester.send( "junk=1"+data );
	}
	
	
	function handleXML( xml )
	{		
		var body = xml.getElementsByTagName( xmlBaseTag ); 
		    
		if ( body.length > 0 ) {
			var nodes = body[0].childNodes;			
			for ( var i=0; i < nodes.length; i++ ) {
				
				if ( nodes[i].nodeType == 1 && nodes[i].getAttribute("id") != null ) {
					var id = nodes[i].getAttribute("id");
	          		
					if ( handlerFunc ) {
						handlerFunc( nodes[i], id );
							
					} else if ( nodes[i].nodeName == "select" ) {
						toolkit.handleSelect( nodes[i], id );
						
					} else if ( nodes[i].nodeName == "optionSelect" ) {
						toolkit.optionSelect( id, nodes[i].nodeType );
						
					} else if ( document.all && nodes[i].nodeName == 'tr' ) {
						toolkit.handleTr( id, nodes[i] );
						
					} else {						
						document.getElementById( id ).innerHTML = toolkit.urldecode( toolkit.flattenChildren( nodes[i].childNodes ) );
					}
					
				} else if ( nodes[i].nodeName == "script" ) {
					toolkit.handleScripts( nodes[i] );
				}	
			}
		}

		if ( postFunc ) {	
			postFunc();	
		}
	}
	
	makeXMLRequest();
}


function nodeHelper()
{	
	this.flatten = function( node )
	{
		var returnStr = "";
		
		if ( node.nodeType == 1 ) {
			switch ( node.nodeName ) {
				case "br":
					returnStr += "<br />";	
					break;
					
				case "img":
					returnStr += '<' + node.nodeName + this.flattenAttributes( node ) + ' />';
					break;
					
				default:			
					returnStr += '<' + node.nodeName + this.flattenAttributes( node ) + '>';					
					returnStr += this.flattenChildren( node.childNodes );					
					returnStr += '</' + node.nodeName + '>';
					break;
			}
			
		} else if ( node.nodeType == 3 ) {
			returnStr += node.nodeValue;
		}
		
		return returnStr;
	}
	
	this.flattenChildren = function( nodes )
	{
		var buffer = '';
		
		if ( nodes.length > 0 ) {
			for ( var i=0; i < nodes.length; i++ ) {				
				buffer += this.flatten(nodes[i]);
			}
		}
		
		return buffer;
	}	
	
	this.flattenAttributes = function( node )
	{
		var buffer = "";
	  
		for ( var i=0; i < node.attributes.length; i++ ) {
			var attribute = node.attributes[i];
			buffer += ' '+attribute.name+'="'+attribute.value+'"'
		}
		
		return buffer;
	}
	
	this.copyAttributes = function( source, destination )
	{
		for ( var i=0; i < source.attributes.length; i++ ) {
			var attribute = source.attributes[i];
			destination.setAttribute( attribute.name, attribute.value );
		}
		
		destination.className = source.getAttribute('class');
	}
	
	this.handleTr = function( id, subtree )
	{
		var parentElement = document.getElementById( id );
		
		for ( var i=parentElement.childNodes.length-1; i >= 0; i-- ) {
			parentElement.removeChild( parentElement.childNodes[i] );
		}
	
		for ( var i=0; i < subtree.childNodes.length; i++ ) {
			var cell = document.createElement( subtree.childNodes[i].nodeName );
			
			copyAttributes( subtree.childNodes[i], cell );
			cell.innerHTML = urldecode( flattenChildren( subtree.childNodes[i].childNodes ) );
			parentElement.appendChild(cell);
		}
	}
	
	this.handleSelect = function( node, id )
	{
		optNodes = node.getElementsByTagName( 'option' );
		targetBox = document.getElementById( id );
		targetBox.length = 0;
		
		if ( optNodes.length == 0 ) {
			var newOption = document.createElement( 'option' );

			targetBox.appendChild( newOption );
			newOption.value = "";
			newOption.text = "None found...";              		
			targetBox.disabled=true;
			
		} else {
			for ( var x=0; x < optNodes.length; x++ ) {
				var loadingOption = document.createElement( 'option' );

				targetBox.appendChild( loadingOption );
				loadingOption.value = urldecode( optNodes[x].getAttribute( "value" ) );
				loadingOption.text = urldecode( optNodes[x].firstChild.nodeValue );   
	
				targetBox.disabled=false;	 
			}
		}		
	}	
	
	this.handleScripts = function( node )
	{		
		if ( node.firstChild != null ) {
			var script = node.firstChild.nodeValue;
					
			if ( script != null ) {
				scriptArr = script.split( ";" );
				for ( var i=0; i < scriptArr.length - 1; i++ ) {
					eval( this.urldecode( scriptArr[i]+";" ) );
				}
			}
		}

	}

	this.urlencode = function( str ) 
	{
		return escape( str ).replace( /[+]/g, '%2B' );
	}

 	this.urldecode = function( str ) 
 	{
		return unescape( str ).replace( /[+]/g, ' ' );
	}
	
	this.optionSelect = function( id, value )
	{
		var box = document.getElementById( id );
		var boxSize = box.options.length;
		
		for ( var i=0; i < boxSize; i++ ) {
			if (  box.options[i].value == value ) {
				box.options[i].selected = true;
			}
		}
	}
	

	this.compressData = function( field, value ) 
	{
		return "&"+field+"="+this.urlencode( value );
	}
}

nh = new nodeHelper();
