if (typeof IGS === "undefined") {
    var IGS = {};
};

/**
 *  @constructor - Ajax
 *  @param1 - url[string]: required, the server side file to which the request is
 *            being sent;
 *  @param2 - method[string]: required, the method which will be used to sent the
 *            request. Ex: POST, GET, HEAD;
 *  @param3 - options[object]: optional, other parameters for the request, such as a
 *            string with values that will be POST-ed.
 *            The complete list of optional params:
 *              - params;
 *              - username;
 *              - password;
 *              - displayErrors; or better not, any IGS.Ajax object will throw
 *                Exceptions when encountering problems, so use try/catch
 *              - responseType; XML or TEXT or JSON;
 */
IGS.Ajax = function(url, options) {

    this.username      =  null;
    this.password      =  null;
    this.onComplete    =  null;
    this.method        =  "POST";
    this.url           =  url;
    this.async         =  true;
    this.responseType  =  "XML";
    this.params        =  null;
    this.data          =  null;

    for (var o in options)
    {
        if ( this.hasOwnProperty(o) )
        {
            this[o] = options[o];
        }
        else
        {
            throw "Unsupported option: " + o;
        }
    }
};

IGS.Ajax.prototype.ActiveXOptions = ["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.6.0","MSXML2.XMLHTTP"];

IGS.Ajax.prototype.request = function() {
    this.setParams();
    this.startTransfer( this.getXHRObject() );
}

IGS.Ajax.prototype.setParams = function() {
    if ( this.method.toUpperCase() === "POST" )
    {
        this.data = this.serialize(this.params);
    }
    else if ( this.method.toUpperCase() === "GET" )
    {
        if ( this.url.indexOf("?") === -1 )
        {
            this.url += "?";
        }
        this.url += this.serialize(this.params);
    }
};

IGS.Ajax.prototype.getXHRObject = function() {
    if (window.XMLHttpRequest)
    {
        var XHRObject = new XMLHttpRequest;
        if (this.responseType.toUpperCase() === "XML")
        {
            XHRObject.overrideMimeType("text/xml");
        }
        return XHRObject;
    }
    else if (window.ActiveXObject)
    {
        for (var i=0; i<this.ActiveXOptions.length; i++)
        {
            try {
                return new ActiveXObject(this.ActiveXOptions[i]);
            } catch (e) {
                // do nothing;
            }
        }
    }
    return false;
};

IGS.Ajax.prototype.startTransfer = function(XHRObject) {
    XHRObject.open(this.method, this.url, this.async, this.username, this.password);
    XHRObject.onreadystatechange = this.handleStateChange(XHRObject);
    XHRObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset:UTF-8");
    XHRObject.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 1980 00:00:00 GMT");
    XHRObject.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    XHRObject.send(this.data);
};

IGS.Ajax.prototype.handleStateChange = function(XHRObject) {
    var that = this;
    var x = function() {
        if (XHRObject.readyState === 4)
        {
            if (XHRObject.status === 200)
            {
                that.onComplete(XHRObject.responseText);
            }
        }
    }
    return x;
};

IGS.Ajax.prototype.buildQueryString = function(object) {
    var queryString = [];
    for ( var o in object ) {
        if (typeof object[o] === "object")
        {
            for (var i=0; i<object[o].length; i++)
            {
                queryString.push(encodeURIComponent(o + "[" + i + "]") + "=" + encodeURIComponent(object[o][i]));
            }
        }
        else
        {
            queryString.push(encodeURIComponent(o) + "=" + encodeURIComponent(object[o]));
        }
    }
    return queryString.join("&");
}

IGS.Ajax.prototype.serialize = function(object) {
    var f = null;
    if ( typeof object === "string" )
    {
        f = document.getElementById(object);
    }
    else if ( typeof object === "object")
    {
        if ( object.nodeName && object.nodeName.toUpperCase() === "FORM" )
        {
            f = object;
        }
        else
        {
            return this.buildQueryString(object);
        }
    }

    var formObject = {};
    var inputs = f.getElementsByTagName("input");
    for ( var i=0; i<inputs.length; i++ )
    {
        switch ( inputs[i].type.toUpperCase() )
        {
            case "TEXT":
            case "IMAGE":
            case "BUTTON":
            case "SUBMIT":
            case "PASSWORD":
                if ( inputs[i].name )
                {
                    formObject[inputs[i].name] = inputs[i].value;
                }
                break;
            case "RADIO":
                if ( inputs[i].checked === true )
                {
                    formObject[inputs[i].name] = inputs[i].value;
                }
                break;
            case "CHECKBOX":
                if ( inputs[i].checked === true )
                {
                    var iname = inputs[i].name;
                    if ( iname.indexOf("[]") === iname.length - 2 )
                    {
                        var currInput = iname.substring(0, iname.length - 2);
                        if ( !formObject.hasOwnProperty(currInput) )
                        {
                            formObject[currInput] = [];
                            formObject[currInput].push([inputs[i].value]);
                        }
                        else
                        {
                            formObject[currInput].push([inputs[i].value]);
                        }
                    }
                    else
                    {
                        formObject[iname] = inputs[i].value;
                    }
                }
                break;
        }
    }
    return this.buildQueryString(formObject);
}
