// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//  © Copyright 2000, Calypso Systems, Inc.
//  All Rights Reserved.
//
//  Description:	XML - xNode - Library
//
//  Who                     When         What
//  ------------------------------------------------
//  lGoodman@calsys.com     01/17/00     Created
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// var MODULE_NAME = "csxNode.asp"
function xNode()
{
	this._items = new Array();
	this._itemCount = 0;
	this._attributes = new Array();
	this.value = "";
	this.tagName = "XML";
}
xNode.prototype.typeName = "xNode";
	
xNode.prototype.memberKey = function ()
{
	return this.getProperty("XKEY");
}
	
xNode.prototype._loadTag = function (sFullTag)
{
	var iTagNameEnd = sFullTag.indexOf(" ");
	if (iTagNameEnd==-1)
		{	
	
		this.tagName = sFullTag;
}
	else
{
	
		this.tagName = sFullTag.substr(0,iTagNameEnd);
		var sParms = sFullTag.substr(iTagNameEnd+1,sFullTag.length-iTagNameEnd);
		this._loadTagProps(sParms);
}
}

xNode.prototype._loadTagProps = function(sProps)
	
{
	//debugPrint("loadTagProps",sProps);
	var aProps = sProps.split('"')
	var sKey;
	var sValue;
	var lLen = aProps.length;
	var lMax = (lLen-1) / 2;
	
	
	for (var i=0;i<lMax;i++)
	{
		sKey = aProps[i*2];
		if(i==0)
		{
			sKey=sKey.substr(0,sKey.length-1);
	}
		else
		{
			sKey=sKey.substr(1,sKey.length-2);
}

		sValue = aProps[(i*2)+1];
		this.setProperty(sKey,jsHTMLDecode(sValue));
		//this.setProperty(sKey,sValue);
	}
}

xNode.prototype.loadInnerXML = function (sInnerXML)
{
	//debugPrint("loadInnerXML",sInnerXML);
	var iChildStart = sInnerXML.indexOf("<");
	var sChildXML = "";
	if (iChildStart==-1)
	{	
		// No Children
		this.value = jsHTMLDecode(sInnerXML);
		//this.value = sInnerXML;
}
	else
	{
		if (iChildStart!=0)
{
			// Strip of the value
			this.value = sInnerXML.substr(0,iChildStart);
			sChildXML = sInnerXML.substr(iChildStart,sInnerXML.length-iChildStart);
		}
		else
	{
			sChildXML = sInnerXML;
	}

		this._loadChildXML(sChildXML)
	}
}

xNode.prototype._loadChildXML = function (sChildXML)
{
	var iBreak = 0;
	//debugPrint("Break:" , iBreak);
	var iMaxPos = sChildXML.length;
	var iCount = 0;
	var iPos = 0;
	var iPosOpen = 0;
	var iPosClose = 0;
	var iOpen = 0;
	var iClose = 0;
	var sChild = "";
	var sTag = "";
	
	while (iPos < iMaxPos)
	{
		iBreak++;
		iCount++;
		iPosOpen = sChildXML.indexOf("<",iPos);
		iPosClose = sChildXML.indexOf(">",iPos);
		sTag = sChildXML.substr(iPosOpen,iPosClose-iPosOpen+1)

		// Test for single tag
		sTest = sChildXML.substr(iPosClose-1,1);
		if (sTest=="/")
{
			iCount--;
}
		else
		{
			sTest = sChildXML.substr(iPosOpen+1,1);

			if (sTest=="/")
{
				iCount--;
				iCount--;
			}	
}

		iPos = iPosClose +1;
		if (iCount==0)
		{
			sChild = sChildXML.substr(iOpen,iPosClose-iOpen+1)
			if (sChild!="")
{
			var oNode = this.addNode("Loading")
			oNode.loadXML(sChild);
}


			iOpen = iPos;
}
		if (iBreak>10000)
	{
			alert("XML Parser Max Size");
			break;
		}
	}
}


xNode.prototype.exists = function (sTag,sMember)
{
	var bHave = false;
	var oNode;
	if (sMember)
	{
		for (var iNode=0;iNode<this._itemCount;iNode++)
		{
			oNode = this._items[iNode];
			if(oNode.tagName==sTag)
				{
				if(oNode.memberKey()==sMember)
					{
					bHave=true;
					break;
					}
				}
			
		}
	}
	else
	{
		if (isNaN(sTag))
		// Get the string keyed node
		{
			for (var iNode=0;iNode<this._itemCount;iNode++)
			{
				oNode = this._items[iNode];
				if(oNode.tagName==sTag)
				{
					bHave=true;
					break;
				}
			}
		}
		else
		// Get the ordinal node
		{
			oNode = this._items[sTag];
		    bHave=true;
		}
	}
	return bHave;
}


	xNode.prototype.addExistingNode = function(cNode,sTag)
{
	if(sTag)
	{
	cNode.tagName = sTag;
	}
	this._itemCount++;
	cNode.parentNode = this;
	this._items[this._itemCount-1] = cNode;
	return cNode;
}


	xNode.prototype.getQueryString = function()
{
	// Fixes the netscape issue with espace and the plus sign
	var sString = escape(this.getXML());
	//var sString = escape(this.getEncodedXML());
	sString = sString.replace(/\+/g,"%2B");
	return sString;
}

	xNode.prototype.count = function ()
{
return this._itemCount;
}

	xNode.prototype.getDebugXML = function (iIndent)
{
	var iNode = 0;
	var sRet = "";
	var sKey = "";
	//sRet = "<DIV STYLE='position:relative;left:" + iIndent + "px'>";
	//sRet = "<DIV CLASS='indent" + iIndent + "'>";
	if (!iIndent)
	{
		iIndent = 0;
		sRet = "<DIV CLASS='indent0'>";
	}
	else
	{
		sRet = "<DIV CLASS='indent2'>";
	}
	
	for (var i=0;i<iIndent;i++)
	{	
		//sRet = sRet + "&nbsp;";
	}
	
	
	sRet = sRet + spanWrapText("&lt;" + this.tagName,"NodeTag");
	for (sKey in this._attributes)
	{
		sRet = sRet + " " + spanWrapText(sKey,"ParmTag") + spanWrapText(  "=" + addQuotes(jsHTMLEncode(jsHTMLEncode(this._attributes[sKey].value))),"ParmValueTag");
	}
	sRet = sRet + spanWrapText("&gt;" ,"NodeTag");;
	sRet = sRet + spanWrapText(jsHTMLEncode(jsHTMLEncode(this.value)),"ValueTag");

	for (var iNode=0;iNode<this._itemCount;iNode++)
	{
		oNode = this._items[iNode];
		sRet = sRet + oNode.getDebugXML(iIndent+1) 		
	}
	sRet = sRet + spanWrapText("&lt;/" + this.tagName + "&gt;","NodeTag");
	sRet = sRet + "</DIV>";
	return sRet;
}

	xNode.prototype.loadXML = function (sXMLIn)
{
	sXML = String(sXMLIn);
	
	var iLen = sXML.length;
	if (sXML != "")
	{
		if (sXML.substr(iLen-1,1)=="\\")
		{
			var iTagEnd = sXML.indexOf("\>");
			var sFullTag = sXML.substr(1,iTagEnd-1);
			this._loadTag(sFullTag);
		}
		else
		{
			var iTagEnd = sXML.indexOf("\>");
			var sFullTag = sXML.substr(1,iTagEnd-1);
			this._loadTag(sFullTag);
			
			var iTagLen = this.tagName.length;
			var sInnerXML = sXML.substr(iTagEnd+1,iLen-iTagEnd-iTagLen-4);
			this.loadInnerXML(sInnerXML);
		}
	}
}
	
xNode.prototype.getXML = function()
{
	var iNode = 0;
	var sRet = "";
	var sKey = "";
	sRet = "<" + this.tagName;
	for (sKey in this._attributes)
	{
		sRet = sRet + " " + sKey + "=" + addQuotes(jsHTMLEncode(this._attributes[sKey].value));
	}
	sRet = sRet + ">";
	sRet = sRet + jsHTMLEncode(this.value);
	
	for (var iNode=0;iNode<this._itemCount;iNode++)
	{
		oNode = this._items[iNode];
		sRet = sRet + oNode.getXML() 		
	}

	sRet = sRet + "</" + this.tagName + ">";
	return sRet;
}

xNode.prototype.clearAll = function ()
{
	this.clearInner();
	this._attributes = new Array();
}

xNode.prototype.clearInner = function ()
{
	this.value = "";
	this._items = new Array();
	this._itemCount = 0;
}

xNode.prototype.addNode = function (sTag)
{
	var oRet = new xNode()
	oRet.tagName = sTag
	this._itemCount++;
	oRet.parentNode = this;
	this._items[this._itemCount-1] = oRet
	return oRet;
}

xNode.prototype.propertyExists = function (sName)
{
	if(this._attributes[sName])
	{
		return true;
	}
}
xNode.prototype.setProperty = function (sName,sValue)
{
	this.property(sName).value = sValue;
}

xNode.prototype.clearProperty = function (sName)
{
	var oRet= this._attributes[sName];
	if (oRet)
	{
		delete this._attributes[sName];
	}

}

xNode.prototype.getProperty = function (sName)
{
	if (this._attributes[sName])
	{
	return this.property(sName).value;
	}
	
}

xNode.prototype.property = function(sName)
{
	var bHave = false;
	var oRet= this._attributes[sName];
	if (!oRet)
	{
		oRet = new xNode_attribute(sName)
		this._attributes[sName] = oRet
	}
	return oRet;
}

xNode.prototype.nodes = function (sTag,sMember)
{
	var bHave = false;
	var oNode;
	if (sMember)
	{
		for (var iNode=0;iNode<this._itemCount;iNode++)
		{
			oNode = this._items[iNode];
			if(oNode.tagName==sTag)
				{
				if(oNode.memberKey()==sMember)
					{
					bHave=true;
					break;
					}
				}
		}
		if (bHave==false)
		{
			oNode=this.addNode(sTag);
			oNode.setProperty("XKEY",sMember);
		}
	}
	else
	{
		if (isNaN(sTag))
		// Get the string keyed node
		{
			for (var iNode=0;iNode<this._itemCount;iNode++)
			{
				oNode = this._items[iNode];
				if(oNode.tagName==sTag)
				{
					bHave=true;
					break;
				}
			}
			if (bHave==false)
			{
				oNode=this.addNode(sTag);
			}
		}
		else
		// Get the ordinal node
		{
			oNode = this._items[sTag];
		    bHave=true;

		}
	}
	return oNode;
}


function xNode_attribute(sName,sValue)
{
	this.name = sName;
	this.value = "";

}

	
function spanWrapText(sText,sStyle)
	{
	var sRet = "<SPAN";
	sRet = sRet + " CLASS='" + sStyle + "'>"
	sRet = sRet + sText;
	sRet = sRet + "</SPAN>";
	return sRet;
}

function addQuotes(sItem)
{
	return '"' + sItem + '"'
}

// -----------------------------------------
// debugXML
// -----------------------------------------
function debugXML(sXML, sCaption, sTarget)
{
	var oXML = new xNode();
	oXML.loadXML(sXML);
	debugxNode(oXML, sCaption, sTarget)
}

// -----------------------------------------
// debugXML
// -----------------------------------------
function debugxNode(oXML, sCaption, sTarget)
{	
	var oWin = window.open("",sTarget,"menubar=yes,scrollbars=yes,resizable=yes");
	var oDoc = oWin.document;
		
	var sOut = "";
	sOut += "<HTML>";
	sOut += ("<HEAD><TITLE>" + sCaption + "</TITLE></HEAD>");
	sOut += ("<LINK rel='stylesheet' type='text/css' href='./css/xNode.css'>");
	sOut += ("<BODY>");
	sOut += (oXML.getDebugXML());
	sOut += ("</BODY>");
	sOut += ("</HTML>");

	oDoc.write(sOut);
	oDoc.close();
		
		}
// -----------------------------------------
// debugText
// -----------------------------------------
function debugText(sText, sCaption, sTarget)
			{
	var oWin = window.open("",sTarget,"scrollbars=yes,resizable=yes");
	var oDoc = oWin.document;
				
	var sOut = "";
	sOut += "<HTML>";
	sOut += ("<HEAD><TITLE>" + sCaption + "</TITLE></HEAD>");
	sOut += ("<LINK rel='stylesheet' type='text/css' href='./css/xNode.css'>");
	sOut += ("<BODY>");
	sOut += jsHTMLEncode(sText);
	sOut += ("</BODY>");
	sOut += ("</HTML>");
			
	oDoc.write(sOut);
	oDoc.close();
			
}

