function AjaxRequest(myaction,myhandler)
{
    var action = myaction;
    var handler = myhandler;
    var params = new Array();
    var req = null;
    var props = new Array();
    var remote = false;
    var ie8=false;

    this.getHandler=getHandler;
    this.getAction=getAction;
    this.setParameter=setParameter;
    this.getParameter=getParameter;
    this.getParameters=getParameters;
    this.addForm=addForm;
    this.send=SendRequest;
    this.setProperty=setProperty;

    function setParameter(key,val)  {params[params.length]=new KeyVal(key,val);}
    function getHandler()           {return handler;}
    function getParameters()        {return params;}
    function getProperties()        {return props;}
    function setProperty(key,val)   {props[props.length]=new KeyVal(key,val);}
    this.setParameters=function(q)
    {
        if (arguments.length==1)
        {
            if (typeof(q)=="string")
            {
                var query=q;
                if (q.indexOf("?")==0)
                {
                    query = query.substring(1);
                }
                var ar = query.split("&");
                for (var i=0;i<ar.length;i++)
                {
                    var s = ar[i].split("=");
                    params[params.length]=new KeyVal(s[0],s[1]);
                }
            }
            else if (typeof(q)=="object")
            {
                addForm(q);
            }
        }
    }

    function getAction()
    {
        return action;
    }

    function addForm(f)
    {
        var elements = f.elements;
        var rads = new Array();
        for (var i=0;i<elements.length;i++)
        {
            if (!f.elements[i].disabled)
            {
                if (f.elements[i].type && f.elements[i].type=="radio")
                {
                    if (f.elements[i].checked)
                    {
                        params[params.length]=new KeyVal(elements[i].name,elements[i].value)
                    }
                    else
                    {
                        push(rads,f.elements[i].name);
                    }
                }
                else if (f.elements[i].type && f.elements[i].type=="checkbox")
                {
                    if (f.elements[i].checked)
                    {
                        params[params.length]=new KeyVal(elements[i].name,elements[i].value)
                        params[params.length]=new KeyVal("cp-checkbox-"+elements[i].name,"cp-on")
                    }
                    else
                    {
                        params[params.length]=new KeyVal("cp-checkbox-"+elements[i].name,"cp-off")
                    }
                }
                else if(f.elements[i].type && f.elements[i].type == "select-multiple")
                {
                    var mselect = f.elements[i];
                    for(var j=0; j<mselect.length; j++)
                    {
                        if(mselect.options[j].selected)
                        {
                            params[params.length]=new KeyVal(mselect.name,mselect.options[j].value)
                        }
                    }
                }
                else
                {
                    params[params.length]=new KeyVal(elements[i].name,elements[i].value)
                }
            }
        }
        for (var i=0;i<rads.length;i++)
        {
            params[params.length]=new KeyVal("cp-radio-"+rads[i],"");
        }

    }

    function push(map,value)
    {
        if (value==null || value=="")
        {
            return;
        }
        for (var i=0;i<map.length;i++)
        {
            if (map[i]==value)
            {
                return;
            }
        }
        map[map.length]=value;
    }


    function getParameter(key)
    {
        for (var i=0;i<params.length;i++)
        {
            if (params[i].key==key) {return params[i].val;}
        }
        return null;
    }

    function KeyVal(key,val)
    {
        this.key=key;
        this.val=val;
    }

    function SendRequest(_remote)
    {
        if (req!=null)
        {
            req.abort();
        }

        remote = (arguments.length==1 && _remote);

        req = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
        if (remote && window.XDomainRequest)
        {
            req = new XDomainRequest();
            ie8=true;
        }

        var url = getAction();
        if (remote && ie8)
        {
            req.onreadystatechange=ReceiveRequest;
            req.onerror = ReceiveFail;
            req.ontimeout = ReceiveFail;
            req.onload = ReceiveRequest;
            req.timeout=10000;
            req.open("get", url);
        }
        else
        {
            req.open("POST", url, true);
            req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            req.onreadystatechange=ReceiveRequest;
        }

        var ar = getParameters();
        var str="";
        if (remote)
        {
            var amp="";
            for (var i=0;i<ar.length;i++)
            {
                str+=amp+encodeURIComponent(ar[i].key)+"="+encodeURIComponent(ar[i].val);
                amp="&";
            }
        }
        else
        {
            req.setRequestHeader("nxAjax","true");
            str="cp-transport=true";
            for (var i=0;i<ar.length;i++)
            {
                str+="&"+ar[i].key+"="+encodeURIComponent(ar[i].val);
            }
        }
        req.send(str);
    }

    function ReceiveFail()
    {
        var func = getHandler()
        var response = new AjaxResponse(false,null,null,req.contentType,0);
        var ar = getProperties();
        for (var i=0;i<ar.length;i++)
        {
            response.setProperty(ar[i].key,ar[i].val);
        }
        eval("window."+func+"(response)")
    }

    function ReceiveRequest()
    {
        if (ie8 || req.readyState == 4)
        {
            var func = getHandler()
            var response = null;

            var ct = ie8?req.contentType:req.getResponseHeader("content-type");
            if (ie8)
            {
                response = new AjaxResponse(true,req.responseText,req.responseText,ct,200);
            }
            else if (req.status == 200)
            {
                response = new AjaxResponse(true,req.responseXML,req.responseText,ct,req.status);
            }
            else if (req.status == 0)
            {
                response = new AjaxResponse(false,null,null,ct,req.status);
            }
            else
            {
                var text = (req.statusText?req.statusText:"");
                response = new AjaxResponse(false,text,null,ct,req.status);
            }

            if (!ie8 && req.getAllResponseHeaders())
            {
                var str = req.getAllResponseHeaders();
                if (str!=null)
                {
                    var ar = str.split("\n");
                    for (var i=0;i<ar.length;i++)
                    {
                        var ar2=ar[i].split(":", 2);
                        if (ar2.length==2)
                        {
                            response.setHeader(ar2[0],(new String(ar2[1])).trim());
                        }
                    }
                }
            }

            var ar = getProperties();
            for (var i=0;i<ar.length;i++)
            {
                response.setProperty(ar[i].key,ar[i].val);
            }

            if (!ie8 && response.isSessionTimeout())
            {
                alert("Due to inactivity and to protect your data, your session has expired.\n\nYou will now be redirected to the login screen.\n\nLogging in will refresh your session.");
                window.location = response.getExit();
                return;
            }
            eval("window."+func+"(response)")
        }
    }
}

function AjaxResponse(mysuccess,mydoc,mytext,ct,cd)
{
    var success=mysuccess;
    var xdoc=mydoc;
    var text=mytext;
    var contentType = ct;
    var statusCode = cd;
    var target=null;
    var request=null;
    var props = new Array();
    var headers = new Array();

    this.ok=ok;
    this.getXmlDocument=getXmlDocument;
    this.getText=getText;
    this.getProperty=getProperty;
    this.setProperty=setProperty;
    this.getJSON=getJSON;
    this.isSessionTimeout=isSessionTimeout;
    this.getExit=getExit;
    this.setHeader=setHeader;
    this.getHeader=getHeader;
    this.getContentType=getContentType;
    this.getStatusCode=getStatusCode;

    function ok()               {return success;}
    function getXmlDocument()   {return xdoc;}
    function getText()          {return text;}
    function getProperty(n)     {return props[n];}
    function setProperty(k,v)   {props[k]=v;}
    function getJSON()          {try{return eval('(' + getText() + ')');} catch(ex){return null}}
    function setHeader(k,v)     {headers[k]=v;}
    function getHeader(k)
    {
        var value = headers[k];
        if (value || !k)
        {
            return value;
        }
        else
        {
            for (var h in headers)
            {
                if (h && k.toUpperCase() == h.toUpperCase())
                {
                    value = headers[h];
                    break;
                }
            }
            return value;
        }
    }
    function isSessionTimeout() {return headers["NxExpired"]!=null;}
    function getExit()          {return headers["NxExit"];}
    function getContentType()   {return ct;}
    function getStatusCode()    {return cd;}

}



String.prototype.trim = function()
{
    if (this.indexOf(" ")==0 && this.length>1)
    {
        var s = this.substring(1);
        var n = s.indexOf("\r");
        if (n>0)
        {
            s = s.substr(0,n)
        }
        return s;
    }
    return this;
}




