/*
 * Rich JavaScript XmlData.js, version 1.0
 * Copyright (c) 2006-2008 Lee Won-Gyoon <mail.kido@gmail.com>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * For details, see the RichScript web site: http://www.richScript.net/
 * 
*******************************************************************************/

function XmlData() {
	this.xmlDoc;
}
XmlData.prototype.load = function(_path) {
	if (window.ActiveXObject) {
		this.xmlDoc = new ActiveXObject("MSXML.DOMDocument");
	} else {
		if (browser.isSF||browser.isCR) {
			XMLDocument.prototype.load = function(_xmlPath) {
				var _tempRequest = new XMLHttpRequest();
				_tempRequest.open("GET", _xmlPath, false);
				_tempRequest.setRequestHeader("Content-Type","text/xml");
				_tempRequest.send(null);
				this.appendChild(this.importNode(_tempRequest.responseXML.documentElement,true));
			}
		}
		this.xmlDoc = document.implementation.createDocument("","",null);
	}
	this.xmlDoc.async = false;
	this.xmlDoc.load(_path);
};
XmlData.prototype.loadXML = function(_s) {
	if (window.ActiveXObject) {
		this.xmlDoc = new ActiveXObject("MSXML.DOMDocument");
		this.xmlDoc.async = false;
		this.xmlDoc.loadXML(_s);
	} else {
		this.xmlDoc = (new DOMParser()).parseFromString(_s,"text/xml");
	}
};
XmlData.prototype.toObject = function(_node) {
	if (_node==undefined) {
		_node = this.xmlDoc.documentElement;
	}
	
	var data = new NodeData(_node);
	data.setAttributes(_node.attributes);
	
	if (_node.childNodes&&_node.childNodes.length>0) {
		for (var i=0; i<_node.childNodes.length; i++) {
			if (_node.childNodes[i].tagName!=undefined) {
				var tagName = _node.childNodes[i].tagName.toUpperCase();
				var nodeValue = "";
				try {
					nodeValue = _node.childNodes[i].firstChild.nodeValue;
				} catch(e) { }
				if (data[tagName]==undefined) {
					data[tagName] = this.toObject(_node.childNodes[i]);
					data.hasChildNodes = true;
				} else {
					// µ¿ÀÏ ÀÌ¸§ ³ëµåÀÏ °æ¿ì Array·Î º¯È¯
					if (data[tagName].length==undefined) {
						data[tagName] = [data[tagName]];
					}
					
					// Array¿¡ ½Å±Ô ³ëµå push
					data[tagName].push(this.toObject(_node.childNodes[i]));
				}
			}
		}
	}
	
	return data;
};
XmlData.prototype.toXmlString = function() {
	return this.toObject().toXmlString();
};



function NodeData(_node) {
	this.realName = (_node!=undefined&&_node.tagName!=null) ? _node.tagName : undefined;
	this.value = (_node!=undefined&&_node.firstChild!=undefined&&_node.firstChild.nodeValue!=null) ? _node.firstChild.nodeValue : "";
	this.hasChildNodes = false;
	this.attributes = [];
}
NodeData.prototype.getAttribute = function(_name) {
	var value;
	for (var i=0; i<this.attributes.length; i++) {
		if (this.attributes[i].name==_name) {
			value = this.attributes[i].value;
			break;
		}
	}
	return value;
};
NodeData.prototype.setAttribute = function(_name, _value) {
	var isNewAttribute = true;
	for (var i=0; i<this.attributes.length; i++) {
		if (this.attributes[i].name==_name) {
			this.attributes[i].value = _value;
			isNewAttribute = false;
			break;
		}
	}
	if (isNewAttribute) {
		this.attributes.push({
			name : _name,
			value : _value
		});
	}
};
NodeData.prototype.setAttributes = function(_attributes) {
	if (_attributes!=undefined) {
		if (_attributes.length>0) {
			for (var i=0; i<_attributes.length; i++) {
				this.attributes.push({
					name : _attributes[i].name,
					value : _attributes[i].value
				});
			}
		}
	}
};

NodeData.prototype.toXmlString = function(_depth) {
	if (_depth==undefined) _depth = 0;
	var tab = '';
	for (var i=0; i<_depth; i++) {
		tab += '\t';
	}
	var s = '';
	s += tab + '<'+this.realName;
	for (var i=0; i<this.attributes.length; i++) {
		s += ' '+this.attributes[i].name+'="'+this.attributes[i].value.escapeXml()+'"';
	}
	s += '>';
	
	if (this.hasChildNodes) {
		s += '\n';
		for (prop in this) {
			var propString = ''+prop;
			if (propString==propString.toUpperCase()) {
				if (this[propString].length>0) {
					for (var i=0; i<this[propString].length; i++) {
						s += this[propString][i].toXmlString(_depth+1);
					}
				} else {
					s += this[propString].toXmlString(_depth+1);
				}
			}
		}
		s += tab;
	} else {
		s += '<![CDATA[';
		s += this.value;
		s += ']]>';
	}
	s += '</'+this.realName+'>' + '\n';
	return s;
};