// ================================================================
//  jkl-parsexml.js ---- JavaScript Kantan Library for Parsing XML
//  Copyright 2005-2007 Kawasaki Yusuke <u-suke@kawa.net>
//  http://www.kawa.net/works/js/jkl/parsexml.html
// ================================================================
//  xml.js ---- Source change # 2007/01/26 14:05 #
//   ylists.htmlzymap.htmlzSummons
//   ylists.jsz  ymap.jsz  I use it in both scripts
// ================================================================
if ( typeof(XML) == 'undefined' ) XML = function() {};
XML.ParseXML = function ( url, query, method ) {
	this.http = new XML.ParseXML.HTTP( url, query, method, false );
	return this;
};
XML.ParseXML.VERSION = "0.22";
XML.ParseXML.MIME_TYPE_XML  = "text/xml";
XML.ParseXML.MAP_NODETYPE = ["","ELEMENT_NODE","ATTRIBUTE_NODE","TEXT_NODE","CDATA_SECTION_NODE","ENTITY_REFERENCE_NODE","ENTITY_NODE","PROCESSING_INSTRUCTION_NODE","COMMENT_NODE","DOCUMENT_NODE","DOCUMENT_TYPE_NODE","DOCUMENT_FRAGMENT_NODE","NOTATION_NODE"];
XML.ParseXML.prototype.async = function ( func, args ) {
	this.callback_func = func;
	this.callback_arg  = args;
};
XML.ParseXML.prototype.onerror = function ( func, args ) {
	this.onerror_func = func;
};
XML.ParseXML.prototype.parse = function () {
	if ( ! this.http ) return;
	if ( this.onerror_func ) {this.http.onerror( this.onerror_func );}
	if ( this.callback_func ) {
		var copy = this;
		var proc = function() {
			if ( ! copy.http ) return;
			var data = copy.parseResponse();
			copy.callback_func( data, copy.callback_arg );
		};
		this.http.async( proc );
	}
	this.http.load();
	if ( ! this.callback_func ) {
		var data = this.parseResponse();
		return data;
	}
};
XML.ParseXML.prototype.setOutputArray = function ( mode ) {
	if ( typeof(mode) == "string" ) {
		mode = [ mode ];
	}
	if ( mode && typeof(mode) == "object" ) {
		if ( mode.length < 0 ) {
			mode = false;
		} else {
			var hash = {};
			for( var i=0; i<mode.length; i++ ) {
				hash[mode[i]] = true;
			}
			mode = hash;
			if ( mode["*"] ) {
				mode = true;
			}
		} 
	} 
	this.usearray = mode;
}
XML.ParseXML.prototype.parseResponse = function () {
	var root = this.http.documentElement();
	var data = this.parseDocument( root );
	return data;
}
XML.ParseXML.prototype.parseDocument = function ( root ) {
	if ( ! root ) return;
	var ret = this.parseElement( root );
	if ( this.usearray == true ) {
		ret = [ ret ];
	} else if ( this.usearray == false ) {
	} else if ( this.usearray == null ) {
	} else if ( this.usearray[root.nodeName] ) {
		ret = [ ret ];
	}
	var json = {};
	json[root.nodeName] = ret;
	return json;
};
XML.ParseXML.prototype.parseElement = function ( elem ) {
	if ( elem.nodeType == 7 ) {
		return;
	}
	if ( elem.nodeType == 3 || elem.nodeType == 4 ) {
		var bool = elem.nodeValue.match( /[^\x00-\x20]/ );
		if ( bool == null ) return;
		return elem.nodeValue;
	}
	var retval;
	var cnt = {};
	if ( elem.attributes && elem.attributes.length ) {
		retval = {};
		for ( var i=0; i<elem.attributes.length; i++ ) {
			var key = elem.attributes[i].nodeName;
			if ( typeof(key) != "string" ) continue;
			var val = elem.attributes[i].nodeValue;
			if ( ! val ) continue;
			if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
			cnt[key] ++;
			this.addNode( retval, key, cnt[key], val );
		}
	}
	if ( elem.childNodes && elem.childNodes.length ) {
		var textonly = true;
		if ( retval ) textonly = false;
		for ( var i=0; i<elem.childNodes.length && textonly; i++ ) {
			var ntype = elem.childNodes[i].nodeType;
			if ( ntype == 3 || ntype == 4 ) continue;
			textonly = false;
		}
		if ( textonly ) {
			if ( ! retval ) retval = "";
			for ( var i=0; i<elem.childNodes.length; i++ ) {
				retval += elem.childNodes[i].nodeValue;
			}
		} else {
			if ( ! retval ) retval = {};
			for ( var i=0; i<elem.childNodes.length; i++ ) {
				var key = elem.childNodes[i].nodeName;
				if ( typeof(key) != "string" ) continue;
				var val = this.parseElement( elem.childNodes[i] );
				if ( ! val ) continue;
				if ( typeof(cnt[key]) == "undefined" ) cnt[key] = 0;
				cnt[key] ++;
				this.addNode( retval, key, cnt[key], val );
			}
		}
	}
	return retval;
};
XML.ParseXML.prototype.addNode = function ( hash, key, cnts, val ) {
	if ( this.usearray == true ) {
		if ( cnts == 1 ) hash[key] = [];
		hash[key][hash[key].length] = val;
	} else if ( this.usearray == false ) {
		if ( cnts == 1 ) hash[key] = val;
	} else if ( this.usearray == null ) {
		if ( cnts == 1 ) {
			hash[key] = val;
		} else if ( cnts == 2 ) {
			hash[key] = [ hash[key], val ];
		} else {
			hash[key][hash[key].length] = val;
		}
	} else if ( this.usearray[key] ) {
		if ( cnts == 1 ) hash[key] = [];
		hash[key][hash[key].length] = val;
	} else {
		if ( cnts == 1 ) hash[key] = val;
	}
};
XML.ParseXML.Text = function ( url, query, method ) {
	this.http = new XML.ParseXML.HTTP( url, query, method, true );
	return this;
};
XML.ParseXML.Text.prototype.parse = XML.ParseXML.prototype.parse;
XML.ParseXML.Text.prototype.async = XML.ParseXML.prototype.async;
XML.ParseXML.Text.prototype.onerror = XML.ParseXML.prototype.onerror;
XML.ParseXML.Text.prototype.parseResponse = function () {
	var data = this.http.responseText();
	return data;
}
XML.ParseXML.JSON = function ( url, query, method ) {
	this.http = new XML.ParseXML.HTTP( url, query, method, true );
	return this;
};
XML.ParseXML.JSON.prototype.parse = XML.ParseXML.prototype.parse;
XML.ParseXML.JSON.prototype.async = XML.ParseXML.prototype.async;
XML.ParseXML.JSON.prototype.onerror = XML.ParseXML.prototype.onerror;
XML.ParseXML.JSON.prototype.parseResponse = function () {
	var text = this.http.responseText();
	if ( typeof(text) == 'undefined' ) return;
	if ( ! text.length ) return;
	var data = eval( "("+text+")" );
	return data;
}
XML.ParseXML.DOM = function ( url, query, method ) {
	this.http = new XML.ParseXML.HTTP( url, query, method, false );
	return this;
};
XML.ParseXML.DOM.prototype.parse = XML.ParseXML.prototype.parse;
XML.ParseXML.DOM.prototype.async = XML.ParseXML.prototype.async;
XML.ParseXML.DOM.prototype.onerror = XML.ParseXML.prototype.onerror;
XML.ParseXML.DOM.prototype.parseResponse = function () {
	var data = this.http.documentElement();
	return data;
}
XML.ParseXML.LoadVars = function ( url, query, method ) {
	this.http = new XML.ParseXML.HTTP( url, query, method, true );
	return this;
};
XML.ParseXML.HTTP = function( url, query, method, textmode ) {
	this.url = url;
	if ( typeof(query) == "string" ) {
		this.query = query;
	} else {
		this.query = "";
	}
	if ( method ) {
		this.method = method;
	} else if ( typeof(query) == "string" ) {
		this.method = "POST";
	} else {
		this.method = "GET";
	}
	this.textmode = textmode ? true : false;
	this.req = null;
	this.xmldom_flag = false;
	this.onerror_func  = null;
	this.callback_func = null;
	this.already_done = null;
	return this;
};
XML.ParseXML.HTTP.REQUEST_TYPE  = "application/x-www-form-urlencoded";
XML.ParseXML.HTTP.ACTIVEX_XMLDOM  = "Microsoft.XMLDOM";
XML.ParseXML.HTTP.ACTIVEX_XMLHTTP = "Microsoft.XMLHTTP";
XML.ParseXML.HTTP.EPOCH_TIMESTAMP = "Thu, 01 Jun 1970 00:00:00 GMT"
XML.ParseXML.HTTP.prototype.onerror = XML.ParseXML.prototype.onerror;
XML.ParseXML.HTTP.prototype.async = function( func ) {
	this.async_func = func;
}
XML.ParseXML.HTTP.prototype.load = function() {
	if ( window.ActiveXObject ) {
		var activex = XML.ParseXML.HTTP.ACTIVEX_XMLHTTP;
		if ( this.method == "GET" && ! this.textmode ) {
			activex = XML.ParseXML.HTTP.ACTIVEX_XMLDOM;
		}
		this.req = new ActiveXObject( activex );
	} else if ( window.XMLHttpRequest ) {
		this.req = new XMLHttpRequest();
	}
	var async_flag = this.async_func ? true : false;
	if ( typeof(this.req.send) != "undefined" ) {
	    this.req.open( this.method, this.url, async_flag );
	}
	if ( typeof(this.req.setRequestHeader) != "undefined" ) {
	    this.req.setRequestHeader( "Content-Type", XML.ParseXML.HTTP.REQUEST_TYPE );
	}
	if ( typeof(this.req.overrideMimeType) != "undefined" && ! this.textmode ) {
	    this.req.overrideMimeType( XML.ParseXML.MIME_TYPE_XML );
	}
	if ( async_flag ) {
		var copy = this;
		copy.already_done = false;
		var check_func = function () {
			if ( copy.req.readyState != 4 ) return;
			var succeed = copy.checkResponse();
			if ( ! succeed ) return;
			if ( copy.already_done ) return;
			copy.already_done = true;
			copy.async_func();
		};
		this.req.onreadystatechange = check_func;
	}
	if ( typeof(this.req.send) != "undefined" ) {
		this.req.send( this.query );
	} else if ( typeof(this.req.load) != "undefined" ) {
		this.req.async = async_flag;
		this.req.load( this.url );
	}
	if ( async_flag ) return;
	var succeed = this.checkResponse();
}
XML.ParseXML.HTTP.prototype.checkResponse = function() {
	if ( this.req.parseError && this.req.parseError.errorCode != 0 ) {
		if ( this.onerror_func ) this.onerror_func( this.req.parseError.reason );
		return false;
	}
	if ( this.req.status-0 > 0 && this.req.status != 200 && this.req.status != 206 && this.req.status != 304 ) {
		if ( this.onerror_func ) this.onerror_func( this.req.status );
		return false;
	}
	return true;
}
XML.ParseXML.HTTP.prototype.documentElement = function() {
	if ( ! this.req ) return;
	if ( this.req.responseXML ) {
		return this.req.responseXML.documentElement;
	} else {
		return this.req.documentElement;
	}
}

