Bw.IO = {};

Bw.IO.Query =
{
	superclassName: null,
	selfclassName: "Bw.IO.Query",
	
	create: function ()
	{
		var obj = new Object();
		
		Bw.Core.bootstrap (obj, this);
		
		return obj;
	},
	
	initialize: function ()
	{
		this.asyncCallback = null;
		this.headers = {};
		this.impl = Bw.Xml.Helpers.createHttpRequest();
	},
	
	get: function (url, callback)
	{
		this.transmit ("GET", url, null, callback);
	},
	
	post: function (url, obj, callback)
	{
		if (obj && obj.selfclass && obj.selfclass == Bw.IO.Message) obj = obj.dom;
		this.transmit ("POST", url, obj, callback);
	},

	transmit: function (method, url, obj, callback)
	{
		var async = (typeof callback != "undefined");
		
		if (async) {
			this.asyncCallback = callback;
		}
	
		this.impl.open (method, this.buildUrl (url), async);
	
		for (h in this.headers) {
			this.impl.setRequestHeader (h, this.headers[h]);
		}
	
		if (async) {
			var self = this;
			this.impl.onreadystatechange = function () { self.readyStateChanged(); };
		}
		
		this.impl.send (obj);
		
		window.status = "";
	},

	readyStateChanged: function ()
	{
		if (this.impl.readyState == 4)
		{
			window.status = "";
			this.asyncCallback ();
		}
	},
	
	setNoCache: function()
	{
		this.headers["If-Modified-Since"] = "Sat, 1 Jan 2005 00:00:00 GMT";
	},

	setHeader: function (name, value)
	{
		this.headers[name] = value;
	},

	getText: function ()
	{
		return this.impl.responseText;
	},

	getMessage: function ()
	{
		return Bw.IO.Message.createFromXml (this.impl.responseXML);
	},

	getXml: function ()
	{
		return this.impl.responseXML;
	},

	getStatus: function ()
	{
		return this.impl.status;
	},

	getStatusText: function ()
	{
		return this.impl.statusText;
	},

	buildUrl: function (url)
	{
		var l = document.location;
		if (url.indexOf ("/") == 0)
		{
			var p = l.port;
			var h = l.host;
			var u = l.protocol + "//" + h;
			if (p != null && p != "" && h.indexOf (p) < 0) {
				u += (":" + p);
			}
			return (u + url);
		} 
		else 
		{
			var l = l.toString();
			var p = l.lastIndexOf ("/");
			var u = l.substr (0, p);
			return (u + "/" + url);
		}
	},
	
	PostData: function ()
	{
		this.properties = {};
		this.toString = function ()
		{
			var s = '';
			for (name in this.properties)
			{
				if (s != '') s += '&';
				var value = this.properties[name];
				
				value = '' + value ;
				
				if( typeof value != 'string' )
				{
					continue;
				}	
				
				value = value.replace(/%/g, "%25");
				value = value.replace(/&/g, "%26");
				
				s += (name + '=' + value);
			}
			
			return s;
		};
	}
};


Bw.IO.Message = 
{
	superclassName: null,
	selfclassName: "Bw.IO.Message",
	
	create: function (name)
	{
		var obj = new Object();
		obj.name = (name) ? name : "message";
		
		Bw.Core.bootstrap (obj, this);
	
		return obj;
	},

	createFromXml: function (xml)
	{
		var obj = new Object();
		obj.dom = xml;
		
		Bw.Core.bootstrap (obj, this);
	
		return obj;
	},

	initialize: function ()
	{
		if (!this.dom)
		{
			var d = Bw.Xml.Helpers.createDocument();
			d.appendChild (d.createElement (this.name));
			this.dom = d;
		}
		
		this.root = this.dom;
		
		if (!this.name) {
			this.name = this.root.nodeName;
		}
	},

	changeRoot: function (path)
	{
		var n = Bw.Xml.Path.navigate (path, this.root, false);
		this.root = (node == null) ? this.dom : node;
	},
	
	put: function (path, value, from)
	{
		var f = (from) ? from : this.root;
		var n = Bw.Xml.Path.navigate (path, f, true);
		if (n) Bw.Xml.Helpers.setNodeValue (n, value);
		return n;
	},
	
	get: function (path, from)
	{
		var f = (from) ? from : this.root;
		var n = Bw.Xml.Path.navigate (path, f, false);
		return (!n) ? null : Bw.Xml.Helpers.getNodeValue (n);
	},
	
	getNodes: function (path, from)
	{
		var f = (from) ? from : this.root;
		return Bw.Xml.Helpers.getNodes (f, path);
	},

	getNode: function (path, from)
	{
		var f = (from) ? from : this.root;
		return Bw.Xml.Helpers.getNode (f, path, false);
	},
	
	count: function (path)
	{
		var n = Bw.Xml.Path.navigate (path, this.root, false);
		return (!n) ? -1 : Bw.Xml.Helpers.countHomonymNodes (n);
	},

	remove: function (path)
	{
		var n = Bw.Xml.Path.navigate (path, this.root, false);
		return (!n) ? null : Bw.Xml.Path.removeNode (n);
	}
};

