//=================================================================================================
var
	ntElement   = 1, 
	ntAttribute = 2, 
	ntText      = 3, 
	ntCData     = 4, 
	ntComment   = 8, 
	ntDocument  = 9;
//=================================================================================================
var
	specialChar = [
			"¡", "&iexcl;",  "¢", "&cent;",   "£", "&pound;",  "¤", "&curren;", "¥", "&yen;", 
			"¦", "&brvbar;", "§", "&sect;",   "¨", "&uml;",    "©", "&copy;",   "ª", "&ordf;", 
			"«", "&laquo;",  "¬", "&not;",    "­", "&shy;",    "®", "&reg;",    "¯", "&macr;", 
			"°", "&deg;",    "±", "&plusmn;", "²", "&sup2;",   "³", "&sup3;",   "´", "&acute;", 
			"µ", "&micro;",  "¶", "&para;",   "·", "&middot;", "¸", "&cedil;",  "¹", "&sup1;", 
			"º", "&ordm;",   "»", "&raquo;",  "¼", "&frac14;", "½", "&frac12;", "¾", "&frac34;", 
			"¿", "&iquest;", "€", "&euro;",   "ß", "&szlig;",  "à", "&agrave;", "á", "&aacute;", 
			"â", "&acirc;",  "ã", "&atilde;", "ä", "&auml;",   "å", "&aring;",  "æ", "&aelig;", 
			"ç", "&ccedil;", "è", "&egrave;", "é", "&eacute;", "ê", "&ecirc;",  "ë", "&euml;", 
			"ì", "&igrave;", "í", "&iacute;", "î", "&icirc;",  "ï", "&iuml;",   "ð", "&eth;", 
			"ñ", "&ntilde;", "ò", "&ograve;", "ó", "&oacute;", "ô", "&ocirc;",  "õ", "&otilde;", 
			"ö", "&ouml;",   "ø", "&oslash;", "ù", "&ugrave;", "ú", "&uacute;", "û", "&ucirc;", 
			"ü", "&uuml;",   "ý", "&yacute;", "ÿ", "&yuml;",   "À", "&Agrave;", "Á", "&Aacute;", 
			"Â", "&Acirc;",  "Ã", "&Atilde;", "Ä", "&Auml;",   "Å", "&Aring;",  "Æ", "&AElig;", 
			"Ç", "&Ccedil;", "È", "&Egrave;", "É", "&Eacute;", "Ê", "&Ecirc;",  "Ë", "&Euml;", 
			"Ì", "&Igrave;", "Í", "&Iacute;", "Î", "&Icirc;",  "Ï", "&Iuml;",   "Ð", "&ETH;", 
			"Ñ", "&Ntilde;", "Ò", "&Ograve;", "Ó", "&Oacute;", "Ô", "&Ocirc;",  "Õ", "&Otilde;", 
			"Ö", "&Ouml;",   "Ø", "&Oslash;", "Ù", "&Ugrave;", "Ú", "&Uacute;", "Û", "&Ucirc;", 
			"Ü", "&Uuml;",   "Ý", "&Yacute;", " ", "&nbsp;",   "’", "&rsquo;",  "”", "&rdquo;", 
			"‘", "&lsquo;",  "“", "&ldquo;",  "Þ", "&THORN;",  "÷", "&divide;", "ƒ", "&fnof;", 
			"×", "&times;",  "ˆ", "&circ;",   "˜", "&tilde;",  "–", "&ndash;",  "—", "&mdash;", 
			"‚", "&sbquo;",  "„", "&bdquo;",  "†", "&dagger;", "‡", "&Dagger;", "•", "&bull;", 
			"…", "&hellip;", "‰", "&permil;", "‹", "&lsaquo;", "›", "&rsaquo;", "™", "&trade;", 
			"Ø", "&Oslash;", "÷", "&divide;", "ø", "&oslash;", "þ", "&thorn;",  "Œ", "&OElig;", 
			"œ", "&oelig;",  "Š", "&Scaron;", "š", "&scaron;", "Ÿ", "&Yuml;",   "¢", "&cent;"];
//-------------------------------------------------------------------------------------------------
function toXml( value, type )
{
	if ( typeof( type ) != "undefined")
	{
		switch ( type )
		{
			case dtBoolean:
				if ( value )
					return "1";
				else
					return "0";
				
				break;
			case dtDateTime:
				return value.formatString("s");
				break;
			case dtDouble:
			case dtMoney:
			case dtPercentage:
				return value.formatString("0.0#########").replace(",", ".");
				break;
			case dtInteger:
			case dtLong:
				break;
			case dtString:
			case dtGuid:
				value = value.replace( /\&/gi, "&amp;");
				value = value.replace( /\"/gi, "&quot;");
				value = value.replace( /\</gi, "&lt;");
				value = value.replace( /\>/gi, "&gt;");
				
				break;
			default:
				throw new Error("Illegal assignment to parameter \"type\" (" + type + ").");
		}
	}
	else
	{
		// TODO: bep welk type...
	}
	
	return value;
}
//=================================================================================================
function fromXml( value, type )
{
	if ( typeof( value ) != "undefined" && typeof( value.firstChild ) != "undefined")
		value = value.firstChild ? value.firstChild.data : null;
	
	if ( value == null || String( value ) == "")
		return null;
	
	switch ( type )
	{
		case dtBoolean:
			if ( String( value ) == "0" || String( value ).toLowerCase() == "false" || String( value ).toLowerCase() == "no")
				return false;
			else
				return true;
			
			break;
		case dtDateTime:
			value = parseXmlDate( value );
			
			if ( isNaN( value ) )
				return null;
			else
				return value;
			
			break;
		case dtDouble:
		case dtMoney:
		case dtPercentage:
			value = parseFloat( value );
			
			if ( isNaN( value ) )
				return null;
			else
				return value;
			
			break;
		case dtInteger:
		case dtLong:
			value = parseInt( value );
			
			if ( isNaN( value ) )
				return null;
			else
				return value;
			
			break;
		case dtString:
		case dtGuid:
			value = value.replace( /&amp;/gi,  "&");
			value = value.replace( /&quot;/gi, "\"");
			value = value.replace( /&lt;/gi,   "<");
			value = value.replace( /&gt;/gi,   ">");
			
			return value;
			break;
		default:
			throw new Error("Illegal assignment to parameter \"type\" (" + type + ").");
	}
}
//=================================================================================================
function parseXmlDate( value )
{
	var
		regex = /^(\d{4}-\d{2}-\d{2})(T\d{2}:\d{2}:\d{2}(\.\d{1,7})?)?$/i;
	
	if ( regex.test( value ) )
	{
		var
			date = value.split( /[-T:\.]/g );
		
		for ( var i = 0; i < date.length; i++ )
			while ( date[i].startsWith("0") && String( date[i] ).length > 1 )
				date[i] = date[i].substr( 1 );
			
		var
			year   = parseInt( date[0] );
			month  = parseInt( date[1] );
			day    = parseInt( date[2] );
			hour   = parseInt( date[3] );
			minute = parseInt( date[4] );
			second = parseInt( date[5] );
		
		if ( isNaN( hour ) ) 
			hour = 0;
		
		if ( isNaN( minute ) ) 
			minute = 0;
		
		if ( isNaN( second ) ) 
			second = 0;
		
		return new Date( year, month - 1, day, hour, minute, second );
	}
	else
		return parseInt("knaag");
}
//=================================================================================================
function htmlEncode( HTML )
{
	var
		retVal;
	
	try
	{
		retVal = new String( HTML );
		
		retVal = retVal.replace( /&/g, "&amp;");
		
		for ( var i = 0; i < specialChar.length; i += 2 )
			if ( !["<", ">", "\""].contains( specialChar[i] ) )
				retVal = retVal.replace( new RegExp( specialChar[i], "gi"), "&amp;" + specialChar[i + 1].substr( 1 ) );
		
		retVal = retVal.replace( /</g, "&lt;");
		retVal = retVal.replace( />/g, "&gt;");
		retVal = retVal.replace( /"/g, "&quot;");	//"
	}
	catch ( error )
	{
		try
		{
			retVal = HTML.join(", ");
		}
		catch ( error )
		{
			retVal = HTML;
		}
	}
	
	return retVal;
}
//=================================================================================================
function showXml( node, name )
{
	if ( typeof( name ) == "undefined" || name == null )
		name = "";
	
	if ( typeof( node ) != "object" || typeof( node.childNodes ) == "undefined")
		throw new Error("Illegal argument. First argument is not an XmlNode.");
	
	if ( typeof( node.documentElement ) != "undefined")
		node = node.documentElement;
	
	var
		bytes = String("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n").length, 
		win   = window.open("", "frmXML" + name, "toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=1,resizable=1,width=788,height=570");
	
	if ( typeof( Xml ) != "undefined" && typeof( Xml.toString ) == "function")
		bytes += Xml.toString( node ).length;
	
	if ( win )
	{
		win.document.open();
		win.document.writeln("<html><head><title>Xml " + name + "</title></head><body style=\"font-family: Lucida Console, Courier New; font-size:11px; color:navy; margin:5px; background-color:white;\">&lt;?xml version=\"1.0\" encoding=\"Windows-1252\"?&gt;");
		win.document.writeln( buildXml( node ) );
		
		if ( typeof( Xml ) != "undefined" && typeof( Xml.toString ) == "function")
		{
			if ( bytes < 2048 ) 
				win.document.writeln("<div style=\"clear:both; margin-top:10px; font-family:Verdana; color:black;\"><b>XML size:</b> " + bytes + " bytes</div></html>");
			else if ( bytes / 1024 < 2048 ) 
				win.document.writeln("<div style=\"clear:both; margin-top:10px; font-family:Verdana; color:black;\"><b>XML size:</b> " + (Math.round(bytes / 1024 * 100) / 100) + " kB</div></html>");
			else if ( bytes / 1024 / 1024 < 2048 ) 
				win.document.writeln("<div style=\"clear:both; margin-top:10px; font-family:Verdana; color:black;\"><b>XML size:</b> " + (Math.round(bytes / 1024 / 1024 * 100) / 100) + " MB</div></html>");
		}
		
		win.document.writeln("</body></html>");
		win.document.close();
		
		win.focus();
	}
}
//=================================================================================================
function nodeName( node )
{
	var
		retVal = node.nodeName;
	
	if ( node.attributes )
	{
		for ( var i = 0; i < node.attributes.length; i++ )
		{
			var
				attr = node.attributes.item( i );
			
			if ( attr.nodeName != "xmlns:sql" && attr.value != "null" && attr.value != "" && attr.value != null )
				retVal += " " + attr.nodeName + "=<font color=\"blue\">\"" + attr.value.replace(/\"/g, "&amp;quot;") + "\"</font>";
		}
	}
		
	return retVal;
}
//=================================================================================================
function buildXml( node, tabs )
{
	var
		retVal = "";
	
	if ( tabs == undefined )
		tabs = "";
	
	if ( node.childNodes.length ) 
	{
		retVal += "<br/>" + tabs + "&lt;" + nodeName( node ) + "&gt;";
		
		for ( var i = 0; i < node.childNodes.length; i++ )
			retVal += buildXml( node.childNodes[i], tabs + "&nbsp;&nbsp;&nbsp;");
		
		var
			length = node.childNodes.length;
		
		for ( var i = 0; i < node.childNodes.length; i++ )
			if ( node.childNodes[i].nodeType == ntText || node.childNodes[i].nodeType == ntCData )
				length--;
		
		if ( length > 0 )
			retVal += "<br/>" + tabs;
		
		retVal += "&lt;/" + node.nodeName + "&gt;";
	}
	else if ( node.nodeType == ntText )
	{
		var
			text = null;
		
		if ( typeof( node.value ) != "undefined")
			text = node.value;
		else if ( typeof( node.text ) != "undefined")
			text = node.text;
		else if ( typeof( node.nodeValue ) != "undefined")
			text = node.nodeValue;
		
		if ( typeof( text ) != "undefined" && text != "" && text != null )
			retVal += "<font color=\"black\"><b>" + toXml( text, dtString ).htmlEncode().replace(/[\r\n]/gi, "<br/>") + "</b></font>";
	}
	else if ( node.nodeType == ntCData )
	{
		var
			text = null;
		
		if ( typeof( node.value ) != "undefined")
			text = node.value;
		else if ( typeof( node.text ) != "undefined")
			text = node.text;
		else if ( typeof( node.nodeValue ) != "undefined")
			text = node.nodeValue;
		
		retVal += "<font color=\"red\">&lt;![CDATA[<br/><div style=\"margin-left:" + (tabs.length / 6) * 7 + "px; padding-left:3px; border-left:1px solid #C00000;\"><font color=\"black\">";
		retVal += toXml( text, dtString ).replace(/[\r\n]/gi, "<br/>").replace(/[\t]/gi, "&nbsp;&nbsp;&nbsp;");
		retVal += "</font><br/></div>" + tabs + "]]&gt;</font>";
	}
	else if ( node.nodeType == ntElement )
		retVal += "<br/>" + tabs + "&lt;" + nodeName( node ) + "/&gt;";
	
	return retVal;
}
//=================================================================================================
