/*
This Class handles the inner-workings of XMLHttpRequest handling

Single object contains all parameters using JSON-style
User calls this function:
new ajax.request({
    'url': 'ajaxdata.aspx',
    'urlParams': [
        'type=something',
        'month=january',
        'year=2007'
    ],
    'formParams': [
        'text1=login',
        'text2=password'
    ],
    'httpMethod': 'POST',
    'completeMethod': complete,
    'loadingMethod'OPTIONAL: loading,
    'errorMethod'OPTIONAL: error,
    'cache'OPTIONAL: doCache,
    'reference'OPTIONAL: referenceObject
})

VERSION 1.1 - 2008.2.11
*/

ajax = new Object() //"ajax" namespace

//constructor
ajax.request = function(params){
    //constants
    this.STATE_UNITIALIZED = 0
    this.STATE_OPEN = 1
    this.STATE_SENT = 2
    this.STATE_RECEIVING = 3
    this.STATE_LOADED = 4
   
    this.params = params
   
    //optional params
    if(!this.params.loadingMethod){
        this.params.loadingMethod = null
    }
    if(!this.params.errorMethod){
        this.params.errorMethod = this.defaultError
    }
   
    this.xhr = null
    this.load()
}
ajax.request.prototype.load = function(){
    //get xhr object
    if (window.XMLHttpRequest) {
        this.xhr = new XMLHttpRequest()
    }
    else if( window.ActiveXObject) {
        this.xhr = new ActiveXObject("Microsoft.XMLHTTP")
    }
   
    if(this.xhr){
        //load xhr
        var strURL = this.params.url
        var sendParams = null
        var urlParams = ''

        var ajaxObject = this //so that onreadystatechange can reference original object
        this.xhr.onreadystatechange = function(){
            ajaxObject.onStateChange.call(ajaxObject)
        }
   
        //encode URL parameters
        if(this.params.urlParams && this.params.urlParams.length > 0){
            for(var i = 0; i < this.params.urlParams.length; i++){
                urlParams += '&' + this.params.urlParams[i]       
            }
            if(this.params.cache == false){
                urlParams += '&' + this.getRandomParameter()
            }
            urlParams = urlParams.substring(1)
            strURL += '?' + urlParams       
        }
        //encode form parameters if POSTing
        if(this.params.httpMethod == 'POST'){
            sendParams = ''
            if(this.params.formParams && this.params.formParams.length > 0){
                for(var i = 0; i < this.params.formParams.length; i++){
                    sendParams += '&' + this.params.formParams[i]       
                }
                sendParams = sendParams.substring(1)               
            }
        }

       
        //open & send request
        this.xhr.open(this.params.httpMethod, strURL, true)
        if(this.params.httpMethod == 'POST'){
            //indicate to server this is a form
            this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            this.xhr.send(sendParams)
        }
        else{
            this.xhr.send(null)
        }
    }
    else{
        //alert user of incompatibility
        alert('Your browser does not support this page')
    }
}

ajax.request.prototype.onStateChange = function(){
    //handle ready-state changes
    if(this.xhr.readyState == this.STATE_LOADED ){
        var httpStatus = this.xhr.status
        if(httpStatus == 200 || httpStatus == 0){
            this.params.completeMethod.call(this)
            this.params.reference = null
        }
        else{
            this.params.errorMethod.call(this)
        }
    }
    else{
        //if onLoading was passed into constructor
        if(this.params.loadingMethod){
            this.params.loadingMethod.call(this)   
        }
    }
}

ajax.request.prototype.defaultError = function(){
    //default error handler
    alert(this.xhr.statusText)
}