////Ajax Data Retrieval Utility Class
//(c) 2009 - Grant Galitz
//Modified for American Yoga
function TextNode(obj, textdata) {
	if (obj != null && textdata != null) {
		obj.appendChild(document.createTextNode(textdata));
	}
}
function RetrieveBasic() {
	this.sElement = arguments[0];
	this.sURL = arguments[1];
	this.classWrapper = (typeof arguments[2] == "string") ? arguments[2] : "announcements_wrapper";
	this.bAsynchronous = (typeof arguments[3] == "boolean") ? arguments[3] : true;
	this.fFail = (typeof arguments[4] == "function") ? arguments[4] : function () { };
	this.bCached = (typeof arguments[5] == "boolean") ? arguments[5] : false;
	this.sPost = (typeof arguments[6] != "undefined") ? arguments[6] : null;
	this.iCheckRate = (typeof arguments[7] == "number") ? arguments[7] : 100;	//Faster loading if lower, but may bog down some systems if so (recursive referencing).
	this.oHandle = null;
	this.childHandle = null;
	this.oDOM = null;
	this.elementHandle = null;
	this.bDone = false;
	this.errorObject = null;
	this.oTime = new Date();
	this.startTime = this.oTime.getTime();
	this.launch();
}
RetrieveBasic.prototype.StartQuery = function () {
	try {
		this.oHandle.open(((this.sPost != null) ? "POST" : "GET"), this.sURL + ((!this.bCached) ? "?t=" + this.startTime : ""), this.bAsynchronous);
		if (this.bAsynchronous) {
			this.checkWait(this);
		}
		if (this.sPost != null) {
			this.oHandle.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		}
		if (this.oHandle.readyState == 1) {
			this.oHandle.send((this.sPost != null) ? this.sPost : null);
		}
		else {
			throw(new Error("The send method was raised in an invalid environment."));
		}
	}
	catch (error) {
		throw (new Error("Could not establish a connection to " + this.sURL + " (\"" + error.message + "\")."));
	}
}
RetrieveBasic.prototype.checkXMLHttpRequest = function () {
	if (typeof window.XMLHttpRequest != "undefined") {
		this.oHandle = new window.XMLHttpRequest;
	}
	else {
		//Fallback, if IE7+ has native xmlhttprequest support turned off.
		try {
			this.oHandle = new ActiveXObject("Msxml2.XMLHTTP.6.0");
		}
		catch (error) {
			try {
				this.oHandle = new ActiveXObject("Msxml2.XMLHTTP.3.0");
			}
			catch (error) {
				try {
					this.oHandle = new ActiveXObject("Msxml2.XMLHTTP");
				}
				catch (error) {
					try {
						//Should never get to this, unless browser is something like IE5.
						this.oHandle = new ActiveXObject("Microsoft.XMLHTTP");
					}
					catch (error) {	//Should only fail for really old browsers (Some Pre-2006).
						throw(new Error("XmlHttpRequest isn\'t supported on your system (\"" + error.message + "\")."));
					}
				}
			}
		}
	}
	if (typeof this.oHandle == "undefined" || this.oHandle == null) {
		throw(new Error("The XmlHttpRequest handle returned by the browser is invalid."));
	}
}
RetrieveBasic.prototype.launch = function () {
	if (typeof document.getElementById(this.sElement) != "undefined") {
		try {
			this.checkXMLHttpRequest();
			this.StartQuery();
			if (!this.bAsynchronous) {
				this.start();
			}
		}
		catch (error) {
			this.errorObject = error;
			this.generateError();
		}
	}
	else {
		alert("The (x)html document is missing an id to match to.");
	}
}
RetrieveBasic.prototype.checkWait = function (thisObj) {
	try {
		if (thisObj.oHandle.readyState >= 3) {
			if (thisObj.oHandle.status < 200 || thisObj.oHandle.status >= 300) {
				thisObj.oHandle.abort();
				throw(new Error("Target file not found."));
			}
		}
		switch (thisObj.oHandle.readyState) {
			case 1:
			case 2:
			case 3:
				//Ignore case 1 - 3, since we want silent loading...
				break;
			case 4:
				thisObj.start();
				thisObj.bDone = true;
				return;
		}
		if (thisObj.oHandle.readyState < 4) {
			var thisObjRef = thisObj;	//Create a reference to this object, since the function timed runs as a global script.
			setTimeout(function () {thisObjRef.checkWait(thisObjRef); }, thisObjRef.iCheckRate);
		}
	}
	catch (error) {
		this.errorObject = error;
		this.errorObject.message = "A data retreival exception has occurred (\"" + this.errorObject.message + "\").";
		this.generateError();
	}
}
RetrieveBasic.prototype.start = function () {
	if (this.oHandle.responseXML != null) {
		this.oDOM = this.oHandle.responseXML;
		this.childHandle = this.oDOM.documentElement.firstChild;
		if (this.childHandle != null) {
			try {
				var toclean = document.getElementById("waitmessage_xml");
				if (toclean != null) {
					toclean.parentNode.removeChild(toclean);
					window.waited = false;
				}
				this.outputSection();
			}
			catch (error) {
				throw(new Error("Error \"" + error.message + "\" in handling the XML data."));
			}
		}
		else {
			throw(new Error("The XML document is empty."));
		}
	}
	else {
		throw(new Error("The server response was not XML."));
	}
}
RetrieveBasic.prototype.generateError = function () {
	this.errorObject.message = this.errorObject.message;
	if (this.fFail != null) {
		this.fFail(this);
	}
	else {
		var errorwrap = document.createElement("div");
		errorwrap.className = this.classWrapper;
		var texterror = document.createElement("span");
		texterror.className = "xml_dom_generated_error";
		TextNode(texterror, this.errorObject.message);
		errorwrap.appendChild(texterror);
		document.getElementById(this.sElement).appendChild(errorwrap);
	}
}
RetrieveBasic.prototype.outputSection = function () {
	this.elementHandle = document.createElement("div");
	this.elementHandle.className = this.classWrapper;
	this.parseTree(this.elementHandle, this.childHandle);
	document.getElementById(this.sElement).appendChild(this.elementHandle);
}
RetrieveBasic.prototype.parseTree = function (documentElement, domElement) {
	var treeBrowseException = (typeof arguments[2] == "number") ? arguments[2] : 0;
	while (domElement != null) {
		var description = null;
		if (domElement.nodeType == 1) {	//Weed out tab spacing...
			switch (domElement.nodeName) {
				case "text":
					description = document.createElement("span");
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					if (description.className == "") {
						description.className = "gray_announcement";
					}
					if (domElement.hasChildNodes()) {
						TextNode(description, domElement.firstChild.data);
					}
					documentElement.appendChild(description);
					break;
				case "highlight":
					description = document.createElement("span");
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					if (description.className == "") {
						switch (domElement.getAttribute("color")) {
							case "lightgray":
								description.className = "gray_announcement";
								break;
							case "gray":
								description.className = "black_announcement";
								break;
							case "orange":
								description.className = "orange_announcement";
								break;
							case "red":
								description.className = "red_announcement";
								break;
							case "blue":
								description.className = "blue_announcement";
						}
					}
					if (domElement.hasChildNodes()) {
						TextNode(description, domElement.firstChild.data);
					}
					documentElement.appendChild(description);
					break;
				case "hyperlink":
					description = document.createElement("a");
					description.setAttribute("href", domElement.getAttribute('address'));
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					if (domElement.getAttribute('open-as') != null) {
						switch (domElement.getAttribute('open-as')) {
							case "new window":
								description.setAttribute("target", "_blank");
								break;
							case "same window":
								description.setAttribute("target", "_self");
						}
					}
					if (domElement.hasChildNodes()) {
						this.parseTree(description, domElement.firstChild);
					}
					documentElement.appendChild(description);
					break;
				case "linebreak":
					var breakSpan = 1;
					if (domElement.getAttribute('span') != null) {
						breakSpan = domElement.getAttribute('span');
					}
					while (breakSpan > 0) {
						description = document.createElement("br");
						documentElement.appendChild(description);
						breakSpan--;
					}
					break;
				case "horizontal_bar":
					description = document.createElement("hr");
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					documentElement.appendChild(description);
					break;
				case "image":
					description = document.createElement("img");
					description.setAttribute("src", domElement.getAttribute('address'));
					description.setAttribute("alt", "picture ( \"" + domElement.getAttribute('address') + "\" )");
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					documentElement.appendChild(description);
					break;
				case "block":
					description = document.createElement("div");
					this.parseStyling(description, domElement);
					this.parseEvents(description, domElement);
					if (domElement.hasChildNodes()) {
						this.parseTree(description, domElement.firstChild);
					}
					documentElement.appendChild(description);
					break;
				case "list":
					this.parseList(documentElement, domElement);
					break;
				case "table":
					this.parseTable(documentElement, domElement);
					break;
				case "playback":
					this.parseObject(documentElement, domElement);
					break;
				case "parameter":
					if (treeBrowseException == 1) {
						this.parseObjectParameter(documentElement, domElement);
					}
			}
		}
		domElement = domElement.nextSibling;
	}
}
RetrieveBasic.prototype.parseStyling = function (documentElement, domElement) {
	if (domElement.getAttribute("style-id") != null) {
		documentElement.id = domElement.getAttribute("style-id");
	}
	if (domElement.getAttribute("style-class") != null) {
		documentElement.className = domElement.getAttribute("style-class");
	}
}
RetrieveBasic.prototype.parseEvents = function (documentElement, domElement) {
	if (domElement.getAttribute("hover-on") != null) {
		documentElement.setAttribute("onmouseover", domElement.getAttribute("hover-on"));
		if (typeof documentElement.onmouseover != "undefined") {
			documentElement.onmouseover = function () { eval(domElement.getAttribute("hover-on")); };
		}
	}
	if (domElement.getAttribute("hover-off") != null) {
		documentElement.setAttribute("onmouseout", domElement.getAttribute("hover-off"));
		if (typeof documentElement.onmouseout != "undefined") {
			documentElement.onmouseout = function () { eval(domElement.getAttribute("hover-off")); };
		}
	}
	if (domElement.getAttribute("single-click") != null) {
		documentElement.setAttribute("onclick", domElement.getAttribute("single-click"));
		if (typeof documentElement.onclick != "undefined") {
			documentElement.onclick = function () { eval(domElement.getAttribute("single-click")); };
		}
	}
	if (domElement.getAttribute("double-click") != null) {
		documentElement.setAttribute("ondblclick", domElement.getAttribute("double-click"));
		if (typeof documentElement.ondblclick != "undefined") {
			documentElement.ondblclick = function () { eval(domElement.getAttribute("double-click")); };
		}
	}
	if (domElement.getAttribute("click-press") != null) {
		documentElement.setAttribute("onmousedown", domElement.getAttribute("click-press"));
		if (typeof documentElement.onmousedown != "undefined") {
			documentElement.onmousedown = function () { eval(domElement.getAttribute("click-press")); };
		}
	}
	if (domElement.getAttribute("click-release") != null) {
		documentElement.setAttribute("onmouseup", domElement.getAttribute("click-release"));
		if (typeof documentElement.onmouseup != "undefined") {
			documentElement.onmouseup = function () { eval(domElement.getAttribute("click-release")); };
		}
	}
}
RetrieveBasic.prototype.parseList = function (documentElement, domElement) {
	var ordered = false;
	if (domElement.getAttribute("ordered") != null) {
		ordered = (domElement.getAttribute("ordered") == "true") ? true : false;
	}
	var listElement = document.createElement((ordered) ? "ol" : "ul");
	this.parseStyling(listElement, domElement);
	this.parseEvents(listElement, domElement);
	var listLine = domElement.firstChild;
	while (listLine != null) {
		if (listLine.nodeType == 1) {	//Weed out tab spacing...
			var listChunk = document.createElement("li");
			if (listLine.nodeName == "line") {
				if (listLine.hasChildNodes()) {
					this.parseTree(listChunk, listLine.firstChild);
				}
			}
			listElement.appendChild(listChunk);
		}
		listLine = listLine.nextSibling;
	}
	documentElement.appendChild(listElement);
}
RetrieveBasic.prototype.parseTable = function (documentElement, domElement) {
	var table = document.createElement("table");
	this.parseStyling(table, domElement);
	this.parseEvents(table, domElement);
	var tbody = document.createElement("tbody");
	var rows = domElement.getElementsByTagName("row");
	for (row = 0; row < rows.length; row++) {
		var rowElement = document.createElement("tr");
		this.parseEvents(rowElement, rows[row]);
		var cells = rows[row].getElementsByTagName("cell");
		for (var cell = 0; cell < cells.length; cell++) {
			var cellElement = document.createElement("td");
			this.parseEvents(cellElement, cells[cell]);
			if (cells[cell].hasChildNodes()) {
				this.parseTree(cellElement, cells[cell].firstChild);
			}
			rowElement.appendChild(cellElement);
		}
		tbody.appendChild(rowElement);
	}
	table.appendChild(tbody);
	documentElement.appendChild(table);
}
RetrieveBasic.prototype.parseObject = function (documentElement, domElement) {
	if (domElement.getAttribute("address") != null && domElement.getAttribute("type") != null) {
		var playBackObject = document.createElement("object");
		this.parseStyling(playBackObject, domElement);
		this.parseEvents(playBackObject, domElement);
		var address = domElement.getAttribute("address");
		var mimetype = domElement.getAttribute("type");
		playBackObject.setAttribute("data", address);
		playBackObject.setAttribute("type", mimetype);
		if (domElement.hasChildNodes()) {
			this.parseTree(playBackObject, domElement.firstChild, 1);
		}
		documentElement.appendChild(playBackObject);
	}
}
RetrieveBasic.prototype.parseObjectParameter = function (documentElement, domElement) {
	if (domElement.getAttribute("name") != null && domElement.getAttribute("value") != null) {
		var playBackObjectParameter = document.createElement("param");
		var paramName = domElement.getAttribute("name");
		var paramValue = domElement.getAttribute("value");
		playBackObjectParameter.setAttribute("name", paramName);
		playBackObjectParameter.setAttribute("value", paramValue);
		documentElement.appendChild(playBackObjectParameter);
	}
}