aj = new Ajax();
var uc;
var __DEBUG = 0;
/* XML NODE TYPES, From: http://developer.mozilla.org/en/docs/DOM:element.nodeType
    * Node.ELEMENT_NODE == 1
    * Node.ATTRIBUTE_NODE == 2
    * Node.TEXT_NODE == 3
    * Node.CDATA_SECTION_NODE == 4
    * Node.ENTITY_REFERENCE_NODE == 5
    * Node.ENTITY_NODE == 6
    * Node.PROCESSING_INSTRUCTION_NODE == 7
    * Node.COMMENT_NODE == 8
    * Node.DOCUMENT_NODE == 9
    * Node.DOCUMENT_TYPE_NODE == 10
    * Node.DOCUMENT_FRAGMENT_NODE == 11
    * Node.NOTATION_NODE == 12 

*/
var nodeTypes = Array('UNDEFINED','ELEMENT','ATTRIBUTE','TEXT','CDATA','ENTITIY_REF','ENTITY','PI',
					  'COMMENT','DOCUMENT','DOCUMENT_TYPE','DOCUMENT_FRAG','NOTATION');

function arrayFromXMLList(xmlDoc) {
	var data = new Object();
	items = xmlDoc.getElementsByTagName('item');
	root = xmlDoc.documentElement;
	total = root.getAttribute('total');
	if (__DEBUG) {
		addDebugMessage(total + " items generated");
		addDebugMessage(items.length + " items returned via XML");
	}
	for(i = 0; i < items.length; i++) {
		valueAttrib = items[i].getAttribute('value');
		if (__DEBUG) 
			addDebugMessage('valueAttrib = ['+valueAttrib+']');
		valueAttribStr = (valueAttrib?valueAttrib:i);
		if (items[i].childNodes[0]) {
			data[valueAttribStr] = items[i].childNodes[0].nodeValue;
			if (__DEBUG) {
				addDebugMessage('Adding element #'+i+' index: ['+valueAttribStr + "], value: ["+items[i].childNodes[0].nodeValue+"], result: ["+data[valueAttribStr]+"]");
				addDebugMessage(data.length + ' new size');
			}
		}
	}	
	return data;
}
//////////////////////////////////////////////////////////////////////
// Submits a form via Ajax.
//////////////////////////////////////////////////////////////////////
// <response>
// 		<event id="" status="success">
// 			<message>Location Updated!</message>
//		</event>
// </response>
//////////////////////////////////////////////////////////////////////
function submitForm(url,formName,btn,submitOnSuccess,processFunction) {
	aj = new Ajax();
	aj.init();
	aj.setURL(url);
	aj.setForm(formName);
	aj.encodeForm();
	if (btn) {
		aj.setButton(btn);
		aj.disableButton();
	}
	aj.setSubmitOnSuccess(submitOnSuccess);
	aj.makeRequest(processFunction);
}
/// Send form is exactly like submitForm, but it does not wait for a response.
function sendForm(url,formName,btn,submitOnSuccess,processFunction) {
	aj = new Ajax();
	aj.init();
	aj.setURL(url);
	aj.setForm(formName);
	aj.encodeForm();
	if (btn) {
		aj.setButton(btn);
		aj.disableButton();
	}
	aj.setSubmitOnSuccess(submitOnSuccess);
	aj.sendRequest(processFunction);
}

function submitQuery(url,processFunction) {
	aj = new Ajax();
	aj.init();
	aj.makeQuery(url,processFunction);	
}

function valueChanged(url,formName,submitOnSuccess,updateList,dataId) {
	aj.init();
	aj.setURL(url);
	aj.setForm(formName);
	aj.setSubmitOnSuccess(submitOnSuccess);
	aj.makeRequest(updateList);
	uc = dataId
}


var updateCombo = function _updateCombo(hr) {
	if (__DEBUG)
		addDebugMessage(hr.responseText);

	doc = document.getElementById(uc);
	while(doc.childNodes[0])
		doc.removeChild(doc.childNodes[0]);
	doc.disabled = false;

	xmlData = arrayFromXMLList(hr.responseXML);
	if (__DEBUG)
		addDebugMessage(xmlData.length + " items processed");
	
	for(i in xmlData) {
		opt = document.createElement('option');
		opt.setAttribute('value',i);
		opt.appendChild(document.createTextNode(xmlData[i]));
		doc.appendChild(opt);
		if (__DEBUG)
			addDebugMessage('Adding html element #'+i+' index: '+i + ", value: "+xmlData[i]);

	}
}

///////////////////////////////////////////////////////

var fillHoverData = function _fullHoverData(hr) {
	hoverBox = document.getElementById('ajaxHoverDetails');
	while(hoverBox.childNodes[0])
		hoverBox.removeChild(hoverBox.childNodes[0]);
	xmlData = arrayFromXMLList(hr.responseXML);	
	hoverBox.style.display = 'block';
	hoverBox.style.top = mouseY+5+'px';
	hoverBox.style.left = mouseX+5+'px';
	for(i in xmlData) {
		hoverBox.appendChild(document.createElement('div').appendChild(document.createTextNode(xmlData[i])));
	}
}

function getHoverData(url) {
	aj.init();
	aj.setURL(url);
	aj.makeRequest(fillHoverData);
}

cacheurl = '';
function showHover(e,url) {
	if (url != cacheurl) {
		cacheurl = url;
		getHoverData(url);
	} else {
		document.getElementById('ajaxHoverDetails').style.display = 'block';	
	}
}

function hideHover() {
	document.getElementById('ajaxHoverDetails').style.display = 'none';
	
}

var processGenericEvent = function(http_request) {
	if(__DEBUG)
		addDebugMessage('<pre>'+http_request.responseText.entityify()+'</pre>');
	processEvents(http_request.responseXML);
}

//////////////////////////////////////////////////
// <event type="" id="" targetId="">Event Data</event>
// event types = replaceChildElement|replaceElement|toggleCheckbox|hideElement|appendCheckbox

function processEvents(xmlDoc) {
	var i, j;
	d = new Date();
	start = d.getTime();
	
	events = xmlDoc.getElementsByTagName('event');
	if(__DEBUG) {
		addDebugMessage("Root Element: "+xmlDoc.documentElement.tagName);
		addDebugMessage(events.length+" events returned.");
	}
	for(i = 0; i < events.length; i++) {
		eventType = events[i].getAttribute('type');
		eventTargetId = events[i].getAttribute('targetId');
		target = document.getElementById(eventTargetId);
		// Replace all of target's children with data
		if(__DEBUG)
			addDebugMessage("Found Event: "+eventType);
		if(eventType == 'replaceChildElement') {	
			if(__DEBUG)
				addDebugMessage("Removing "+target.childNodes.length+" child(ren) of element "+eventTargetId);	
			while(target.childNodes[0]) {
				target.removeChild(target.childNodes[0]);
			}
			for(j = 0 ; j < events[i].childNodes.length; j++) {
				newNode = importXMLToHTML(events[i].childNodes[j]);
				target.appendChild(newNode);	
			}					

		} else if(eventType == 'replaceElement') {
			if(__DEBUG)
				addDebugMessage("Replacing "+eventTargetId+" with "+events[i].childNodes.length+" elements.");
			// if there are multiple sibling, insert in the right order						
			if (target.nextSibling) {
				for(j = 0 ; j < events[i].childNodes.length; j++) {
					newNode = importXMLToHTML(events[i].childNodes[j]);
					target.parentNode.insertBefore(newNode,target.nextSibling);					
				}
			} else { //  if this is the only or last sibling, just append
				for(j = 0 ; j < events[i].childNodes.length; j++) {
					newNode = importXMLToHTML(events[i].childNodes[j]);
					target.parentNode.appendChild(newNode);	
				}				
			}
			target.parentNode.removeChild(target);
		} else if (eventType == 'toggleCheckbox') {
			state = events[i].getAttribute('state');
			if(__DEBUG)
				addDebugMessage("Toggling Checkbox "+eventTargetId+" state = "+state);
			if (state == 'on')
				target.checked = true;
			else if(state == 'off')
				target.checked = false;
			else if(state == 'switch')
				target.checked = !target.checked;
			else if(state == 'chkdisable')
				target.disabled = true;
			
		} else if (eventType == 'hideElement') {
			if(__DEBUG)
				addDebugMessage("Hiding Element "+eventTargetId);
			target.style.display = 'none';
		} else if (eventType == 'hidePopUp') {
			if(__DEBUG)
				addDebugMessage("Hiding PopUp "+eventTargetId);
			hidePopUp(eventTargetId);
		} else if (eventType == 'showPopUp') {
			if(__DEBUG)
				addDebugMessage("Showing PopUp "+eventTargetId);
			showPopUp(eventTargetId);
		} else if (eventType == 'appendSibling') {
			if(__DEBUG)
				addDebugMessage("Appending to  "+eventTargetId+" with "+events[i].childNodes.length+" elements.");
			// if there are multiple sibling, insert in the right order						
			if (target.nextSibling) {
				for(j = 0 ; j < events[i].childNodes.length; j++) {
					newNode = importXMLToHTML(events[i].childNodes[j]);
					target.parentNode.insertBefore(newNode,target.nextSibling);					
				}
			} else { //  if this is the only or last sibling, just append
				for(j = 0 ; j < events[i].childNodes.length; j++) {
					newNode = importXMLToHTML(events[i].childNodes[j]);
					target.parentNode.appendChild(newNode);	
				}				
			}
		} else if (eventType == 'appendCheckbox') {
			value = events[i].getAttribute('value');
			state = events[i].getAttribute('name');
			name = events[i].getAttribute('name');

			if(__DEBUG)
				addDebugMessage("Appending Checkbox to "+eventTargetId+" value = "+value);		
			checkbox = document.createElement('input');
			checkbox.setAttribute('type','checkbox');
			checkbox.setAttribute('name', name);
			checkbox.setAttribute('value',value);
			target.appendChild(checkbox);
			newNode = importXMLToHTML(events[i].childNodes[j]);
			target.appendChild(newNode);
			target.appendChild(document.createElement('br'));
		}
		else if (eventType == 'updateInputValue') {
			if (events[i].hasChildNodes())
				value = events[i].childNodes[0].nodeValue;
			else 
				value = '';
				
			if(__DEBUG)
				addDebugMessage("Updating Textbox("+eventTargetId+") value = "+value);		
			target.value = value;
		} else if(eventType == 'clearForm') {
			target.reset();
		} else if(eventType == 'alert') {
			value = events[i].getAttribute('value');
			alert(value);
		}else if(__DEBUG)
			addDebugMessage("<span class='err'>Unkown Event: "+eventType+"</span>");
	}
	end = d.getTime();
	if(__DEBUG)
		addDebugMessage('Import End :'+end );
}

////////////////////////////////////////////////////////////////
// There is no easy way to import elements from two different
// document types and have it work.  The 'document' object is 
// XHTML, where the AJAX response is XML.  
//
/////////////////////////////////////////////////////////////////
function importXMLToHTML(xmlNode) {

	var i,j,htmlNode,attr;
	//addDebugMessage('Found Node: '+nodeTypes[xmlNode.nodeType]);
	if (xmlNode.nodeType == 1) {
		//addDebugMessage('-> Importing Element "<span class="scs">'+xmlNode.tagName+'</span>" with '+xmlNode.childNodes.length+' child(ren)');
		htmlNode = document.createElement(xmlNode.tagName);
		for(j = 0; j < xmlNode.childNodes.length; j++) {

			htmlNode.appendChild(importXMLToHTML(xmlNode.childNodes[j]));
		}
		attr = xmlNode.attributes;
		for(i = 0; i < attr.length; i++) {
			//addDebugMessage('&lt;<span class="scs">'+xmlNode.tagName+'</span>&gt; Importing Attribute '+attr[i].name+' = '+attr[i].value);
			htmlNode.setAttribute(attr[i].name,attr[i].value);
			if (attr[i].name == 'class') {
				htmlNode.className = attr[i].value;
			}
			if (attr[i].name == 'style') 
				htmlNode.style.cssText = attr[i].value;
			if (attr[i].name == 'colspan')
				htmlNode.colSpan = attr[i].value;
			if (attr[i].name.toLowerCase() == 'onchange') {
				onchangeFunction = new Function("",attr[i].value);			
				htmlNode.onchange = onchangeFunction;	
			}
			if (attr[i].name.toLowerCase() == 'onclick') {
				onclickFunction = new Function("",attr[i].value);			
				htmlNode.onclick = onclickFunction;	
			}
		}
	} else if (xmlNode.nodeType == 3) {
		//addDebugMessage('-> Importing Text '+xmlNode.nodeValue);
		htmlNode = document.createTextNode(xmlNode.nodeValue);
	}

	return htmlNode;
}

