
function tmAJprocessReqTimeout(req)
{
    if (req.handled)
    {
        // no timeout b/c it was already handled.
        return;
    }

    req.handled = 1;  // mark handled.
    req.ht.abort();   // kill it off.

    if (req.userTimeoutHandler != null)
    {
        req.userTimeoutHandler(req.num);
    }
}

function tmAJprocessReqChange(req)
{
    var hreq = req.ht;
    if ((hreq.readyState == 4) && (hreq.status == 200))
    {
        if (req.handled)
        {
            // alert('ignoring late response to request #'+req.num);
            return;
        }

        req.handled = 1;  // mark handled.

        response = hreq.responseXML.documentElement;
        if (req.userHandler != null)
        {
            req.userHandler(req.num,response);
        }
    }
}

var NN=1;
function tmAJqueryBackend(url,handler,timeout,toHandler)
{
    var req = Object();  // one per request.
    req.handled = 0;
    req.num = NN++;
    req.userHandler = handler;
    req.userTimeoutHandler = toHandler;
    // output("query "+req.num+": '"+url+"' sent");

    var cb = function () {
        tmAJprocessReqChange(req);
    };
    if (window.XMLHttpRequest)
    {
        req.ht = new XMLHttpRequest();
        req.ht.onreadystatechange = cb;
        req.ht.open("GET", url, true);
        // for POST --
        // req.ht.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        // some suggest this will help w/ bad data servers --
        // req.ht.overrideMimeType('text/xml');
        req.ht.send(null);
    } 
    else if (window.ActiveXObject)
    {
        req.ht = new ActiveXObject("Microsoft.XMLHTTP");
        if (req)
        {
            req.ht.onreadystatechange = cb;
            req.ht.open("GET", url, true);
            // for POST --
            // req.ht.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            req.ht.send();
        }
    }

    if ( timeout > 0 ) {
        setTimeout( function() { tmAJprocessReqTimeout(req) },
                    timeout );
    }

    return req.num;
}

// {NS,IE} type = {text, hidden, checkbox, radio, select-one, select-multiple}
function tmAJformSubmit(formName,handler,timeout,toHandler)
{
    var form = document.forms[formName];
    var url = form.action;
    var elts = form.elements;
    
    var argn = 0;

    for(var i=0; i<elts.length; i++) {
        var elt = elts.item(i);
        if(elt.name) {

            // TODO: optimize select-one w/ selectedIndex
            if( elt.type == 'select-multiple' || elt.type == 'select-one' ) {

                for(var j=0; j<elt.options.length; j++) {

                    var opt = elt.options[j];
                    if( opt.selected ) {
                        var ovalue = opt.value;
                        if( ovalue==undefined || ovalue==null || ovalue=='' ) {
                            ovalue = opt.text;
                        }

                        if(argn || (url.indexOf('?') != -1)) {
                            url += '&';
                        } else {
                            url += '?';
                        }
                        argn++;
                        url += elt.name + '=' + encodeURIComponent(ovalue);
                    }
                }

            } else if( elt.type == 'checkbox' || elt.type == 'radio' ) {
                if( elt.checked ) {

                    if( argn || (url.indexOf('?') != -1)) {
                        url += '&';
                    } else {
                        url += '?';
                    }
                    argn++;
                    url += elt.name + '=' + encodeURIComponent(elt.value);
                }

            } else {  // text, hidden, ???

                var ovalue = elt.value;
                if( ovalue!=undefined && ovalue!=null && ovalue!='' ) {
                    if( argn || (url.indexOf('?') != -1)) {
                        url += '&';
                    } else {
                        url += '?';
                    }
                    argn++;
                    url += elt.name + '=' + encodeURIComponent(elt.value);
                }
            }
        }
    }
    return tmAJqueryBackend(url,handler,timeout,toHandler);
}

function tmAJformSnapshot(formName) {
    var form = document.forms[formName];
    var url = form.action;
    var elts = form.elements;

    var argn = 0;

    for(var i=0; i<elts.length; i++) {
        var elt = elts.item(i);
        if(elt.name && (elt.name.indexOf('_last_') != 0) ) {
            var emit = 1;
            var last = elts['_last_'+elt.name];
            if( last ) {
                last.value = elt.value;
            }
        }
    }

    return argn;
}

// only handles type = {text, hidden, select-one}
function tmAJformSubmitDeltas(formName,handler,timeout,toHandler) {
    var form = document.forms[formName];
    var url = form.action;
    var elts = form.elements;

    var argn = 0;

    for(var i=0; i<elts.length; i++) {
        var elt = elts.item(i);
        if(elt.name && (elt.name.indexOf('_last_') != 0) ) {
            var emit = 1;
            var last = elts['_last_'+elt.name];
            if( last ) {
                if(elt.value == last.value) {
                    emit = 0;
                } else {
                    last.value = elt.value;
                }
            } else {
                if( elt.value == '' || elt.value == null ) {
                    emit = 0;
                }
            }

            if( emit ) {
                if( argn || (url.indexOf('?') != -1)) {
                    url += '&';
                } else {
                    url += '?';
                }
                argn++;
                url += elt.name + '=' + encodeURIComponent(elt.value);
            }
        }
    }
    if( argn ) {
        return tmAJqueryBackend(url,handler,timeout,toHandler);
    } else {
        return 0;
    }
}

