var ajax_objects = new Array();
var object_idx = 5;

// constructor
function AJAX() {
    // internal properties
    this.html_id       = null;
    this.response_func = null;
    this.error_func    = null;
    this.state         = 'idle';
    this.params        = null;
    this.loading_id    = null;
    
    // set up some semi-fixed variables
    this.method               = 'POST';
    this.request_header       = "application/x-www-form-urlencoded; charset=UTF-8";
    this.animated_loading_pic = "animated_loading.gif";
    this.loading_message = "";
    
    if(navigator.appName == "Microsoft Internet Explorer") {
        this.http = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else {
        this.http = new XMLHttpRequest();
    }
    
    // public methods
    this.handle_response = _handle_response;
    this.poll            = _poll;
    this.on_start        = _on_start;
    this.on_stop         = _on_stop;
    this.response        = _response;
    this.sync_request    = _sync_request;
    this.async_request   = _async_request;
    this.get_form_values = _get_form_values;
    this.destroy         = _destroy;
    
    this.object_idx      = get_index();
    
    ajax_objects[this.object_idx] = this;
}

function get_index () {
    return object_idx++;
}

// internal functions
function _handle_response(idx) {

    var self = ajax_objects[idx];

    switch(self.http.readyState) {
        case 0:
        case 1:
        case 2:
        case 3:
            break;
        case 4:
            self.state = 'completed';

            self.response_content = self.http.responseText;
            self.on_stop();
    
            if (self.http.status == 200) {
                if (self.response_func) 
                    self.response_func();
            }
            else {
                if (self.error_func) 
                    self.error_func();
            }
            return 1;
            break;
    
        default:
            break;

    }
    return 0;
}

function _response() {
    if (this.state == 'completed') {
        return this.response_content;
    }
}

function _poll() {
    switch (this.state) {
        case 'idle':
        case 'running':
            return null;

        case 'completed':
        case 'error':
            return 1;
    }
}

function _async_request() {
    if (this.state == 'running')
            return; // search in progress already
    this.state == 'running';

    this.on_start();

    this.http.open(this.method, this.action, true);
    this.http.setRequestHeader("Content-Type",this.request_header);

    var idx = this.object_idx;
    
    this.http.onreadystatechange = function () {
        _handle_response(idx);
    };

    this.http.send(this.params);
}

function _sync_request() {
    this.state == 'running';

    this.on_start();

    this.http.open(this.method, this.action, false);
    this.http.setRequestHeader("Content-Type",this.request_header); 

    this.http.send(this.params);

    do { ; } while (!this.handle_response(this.object_idx));

    return this.response();
}

function _on_start() {
    // start animated loading icon
    if (this.loading_id)
        document.getElementById(this.loading_id).innerHTML = this.loading_message +" <img src='" + this.animated_loading_pic  + "'/>";
}

function _on_stop() {
    // stop animated loading icon
    if (this.loading_id)
        document.getElementById(this.loading_id).innerHTML = "";
}

function _get_form_values(form) {

    var str = ""; 

    for(var i = 0; i < form.elements.length;i++) {
        switch(form.elements[i].type) { 
            case "text": 
                str += form.elements[i].name + 
                "=" + encodeURI(form.elements[i].value) + ";"; 
                break; 
            case "select-one": 
                str += form.elements[i].name +
                "=" + form.elements[i].options[form.elements[i].selectedIndex].value + ";"; 
                break;
            case "select-multiple": 
                for(var j = 0; j < form.elements[i].length; j++) {
                    if(form.elements[i].options[j].selected == true)
                    {
                        str += form.elements[i].name +
                        "=" + form.elements[i].options[j].value + ";";
                    }
                } 
                break;
            case "checkbox":
                if (form.elements[i].checked)
                    str += form.elements[i].name +
                    "=" + form.elements[i].value + ";"; 
                 break; 
            case "radio":
                if (form.elements[i].checked)
                    str += form.elements[i].name +
                    "=" + form.elements[i].value + ";"; 
                 break; 
            default:
                 str += form.elements[i].name + 
                 "=" + form.elements[i].value + ";"; 
                 break; 
                 
        } 
    } 
    str = str.substr(0,(str.length - 1)); 
    return str; 
}

function _destroy() {
    ajax_objects[this.object_idx] = null;
}

