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);
    }
};
