// Example invocation
// dAjaxSubmitForm(theForm,'../../dAjax/server.php',job_saved);   
 
function dAjaxSubmitForm(f,serverUrl,zcallBack){
    dAjaxLoading(true);
    
    //set if not set
    if(serverUrl==null) var serverUrl=f.action;
    
    if(window.XMLHttpRequest){
        var xmlReq = new XMLHttpRequest();
    } else if(window.ActiveXObject) {
        var xmlReq = new ActiveXObject('Microsoft.XMLHTTP');
    }
    var formData = '', elem = '',inpValue;
    for(var s=0; s<f.elements.length; s++){
        //reset value
        inpValue=null;
        
        //get element
        elem = f.elements[s];
        
          inpType = elem.getAttribute('type');
          //check type
					if(inpType=='submit') continue;
					
          if(inpType == 'checkbox' || inpType == 'radio') {
            if(elem.checked==true){
                // unchecked radios/checkboxes don't get submitted
                inpValue=elem.value;
            }
          }else{
                inpValue=elem.value;
          }     
        
        if(inpValue!=null){  
            //alert(elem.value);
            if(formData != ''){
                formData += '&';
            }
            formData += elem.name+"="+escape(inpValue);
        }
    }
		
		//alert(formData);

    xmlReq.onreadystatechange = function(){
        if(xmlReq.readyState == 4){
            //document.getElementById('insert').innerHTML = xmlReq.responseText;
            
            //turn off loading...
            dAjaxLoading(false);
            
            var textSerial=xmlReq.responseText;
						
						//alert(textSerial);
            
            //alert(textSerial);
            //unserialize data
            
            /*var ser = new HTML_AJAX_Serialize_PHP();
            var data = ser.unserialize(textSerial);
            
            if(data==null){
                alert('error in dAjaxSubmitForm: '+textSerial);
            }*/
            
            zcallBack(textSerial);
        }
    }
		
    xmlReq.open('POST', serverUrl, true);
    xmlReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlReq.send(formData);
    
    return false;
}

function dAjaxDoResponse(theText){

    alert(theText);
    
}

function dAjaxLoading(view){
    //change focus make sure all onchange events are triggered!
    document.body.blur();
    
    var loading = document.getElementById('HTML_AJAX_LOADING');

    if(view==true){
        if (!loading) {
            loading = document.createElement('div');
            loading.id = 'HTML_AJAX_LOADING';
            loading.innerHTML = 'Loading...';

            loading.style.color           = '#fff';
            loading.style.position        = 'fixed';
            loading.style.top             = 0;
            loading.style.right           = 0;
            loading.style.backgroundColor = '#f00';
            loading.style.border          = '1px solid #f99';
            loading.style.width           = '80px';
            loading.style.padding         = '4px';
            loading.style.fontFamily      = 'Arial, Helvetica, sans';
            loading.count = 0;
        
           document.body.insertBefore(loading,document.body.firstChild);

        }else{
            loading.style.display = '';
        }
    }else{
        loading.style.display = 'none';
    }
}

// }}}
// serializer/phpSerializer.js
// {{{ HTML_AJAX_Serialize_PHP

/**

 * PHP serializer

 *

 * This class can be used to serialize and unserialize data in a

 * format compatible with PHP's native serialization functions.

 *

 * @version     0.0.3

 * @copyright   2005 Arpad Ray <arpad@php.net>

 * @license     http://www.opensource.org/licenses/lgpl-license.php  LGPL

 *

 * See Main.js for Author/license details

 */

function HTML_AJAX_Serialize_PHP() {}

HTML_AJAX_Serialize_PHP.prototype = {

    error: false,

    message: "",

    cont: "",

    defaultEncoding: 'UTF-8',

    contentType: 'application/php-serialized; charset: UTF-8',

    // {{{ serialize

    /**

    *  Serializes a variable

    *

    *  @param     mixed  inp the variable to serialize

    *  @return    string   a string representation of the input, 

    *                      which can be reconstructed by unserialize()

    *  @author Arpad Ray <arpad@rajeczy.com>

    *  @author David Coallier <davidc@php.net>

    */

    serialize: function(inp) {

        var type = HTML_AJAX_Util.getType(inp);

        var val;

        switch (type) {

            case "undefined":

                val = "N";

                break;

            case "boolean":

                val = "b:" + (inp ? "1" : "0");

                break;

            case "number":

                val = (Math.round(inp) == inp ? "i" : "d") + ":" + inp;

                break;

            case "string":

                val = "s:" + inp.length + ":\"" + inp + "\"";

                break;

            case "array":

                val = "a";

            case "object":

                if (type == "object") {

                    var objname = inp.constructor.toString().match(/(\w+)\(\)/);

                    if (objname == undefined) {

                        return;

                    }

                    objname[1] = this.serialize(objname[1]);

                    val = "O" + objname[1].substring(1, objname[1].length - 1);

                }

                var count = 0;

                var vals = "";

                var okey;

                for (key in inp) {

                    okey = (key.match(/^[0-9]+$/) ? parseInt(key) : key);

                    vals += this.serialize(okey) + 

                            this.serialize(inp[key]);

                    count++;

                }

                val += ":" + count + ":{" + vals + "}";

                break;

        }

        if (type != "object" && type != "array") val += ";";

        return val;

    },

    // }}} 

    // {{{ unserialize

    /**

     *  Reconstructs a serialized variable

     *

     *  @param    string inp the string to reconstruct

     *  @return   mixed the variable represented by the input string, or void on failure

     */

    unserialize: function(inp) {

        this.error = 0;

        if (inp == "" || inp.length < 2) {

            this.raiseError("input is too short");

            return;

        }

        var val, kret, vret, cval;

        var type = inp.charAt(0);

        var cont = inp.substring(2);

        var size = 0, divpos = 0, endcont = 0, rest = "", next = "";



        switch (type) {

        case "N": // null

            if (inp.charAt(1) != ";") {

                this.raiseError("missing ; for null", cont);

            }

            // leave val undefined

            rest = cont;

            break;

        case "b": // boolean

            if (!/[01];/.test(cont.substring(0,2))) {

                this.raiseError("value not 0 or 1, or missing ; for boolean", cont);

            }

            val = (cont.charAt(0) == "1");

            rest = cont.substring(1);

            break;

        case "s": // string

            val = "";

            divpos = cont.indexOf(":");

            if (divpos == -1) {

                this.raiseError("missing : for string", cont);

                break;

            }

            size = parseInt(cont.substring(0, divpos));

            if (size == 0) {

                if (cont.length - divpos < 4) {

                    this.raiseError("string is too short", cont);

                    break;

                }

                rest = cont.substring(divpos + 4);

                break;

            }

            if ((cont.length - divpos - size) < 4) {

                this.raiseError("string is too short", cont);

                break;

            }

            if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\";") {

                this.raiseError("string is too long, or missing \";", cont);

            }

            val = cont.substring(divpos + 2, divpos + 2 + size);

            rest = cont.substring(divpos + 4 + size);

            break;

        case "i": // integer

        case "d": // float

            var dotfound = 0;

            for (var i = 0; i < cont.length; i++) {

                cval = cont.charAt(i);

                if (isNaN(parseInt(cval)) && !(type == "d" && cval == "." && !dotfound++)) {

                    endcont = i;

                    break;

                }

            }

            if (!endcont || cont.charAt(endcont) != ";") {

                this.raiseError("missing or invalid value, or missing ; for int/float", cont);

            }

            val = cont.substring(0, endcont);

            val = (type == "i" ? parseInt(val) : parseFloat(val));

            rest = cont.substring(endcont + 1);

            break;

        case "a": // array

            if (cont.length < 4) {

                this.raiseError("array is too short", cont);

                return;

            }

            divpos = cont.indexOf(":", 1);

            if (divpos == -1) {

                this.raiseError("missing : for array", cont);

                return;

            }

            size = parseInt(cont.substring(1, divpos - 1));

            cont = cont.substring(divpos + 2);

            val = new Array();

            if (cont.length < 1) {

                this.raiseError("array is too short", cont);

                return;

            }

            for (var i = 0; i + 1 < size * 2; i += 2) {

                kret = this.unserialize(cont, 1);

                if (this.error || kret[0] == undefined || kret[1] == "") {

                    this.raiseError("missing or invalid key, or missing value for array", cont);

                    return;

                }

                vret = this.unserialize(kret[1], 1);

                if (this.error) {

                    this.raiseError("invalid value for array", cont);

                    return;

                }

                val[kret[0]] = vret[0];

                cont = vret[1];

            }

            if (cont.charAt(0) != "}") {

                this.raiseError("missing ending }, or too many values for array", cont);

                return; 

            }

            rest = cont.substring(1);

            break;

        case "O": // object

            divpos = cont.indexOf(":");

            if (divpos == -1) {

                this.raiseError("missing : for object", cont);

                return;

            }

            size = parseInt(cont.substring(0, divpos));

            var objname = cont.substring(divpos + 2, divpos + 2 + size);

            if (cont.substring(divpos + 2 + size, divpos + 4 + size) != "\":") {

                this.raiseError("object name is too long, or missing \":", cont);

                return;

            }

            var objprops = this.unserialize("a:" + cont.substring(divpos + 4 + size), 1);

            if (this.error) {

                this.raiseError("invalid object properties", cont);

                return;

            }

            rest = objprops[1];

            var objout = "function " + objname + "(){";

            for (key in objprops[0]) {

                objout += "this." + key + "=objprops[0]['" + key + "'];";

            }

            objout += "}val=new " + objname + "();";

            eval(objout);

            break;

        default:

            this.raiseError("invalid input type", cont);

        }

        return (arguments.length == 1 ? val : [val, rest]);

    },

    // }}}

    // {{{ getError

    /**

    *  Gets the last error message

    *

    *  @return    string   the last error message from unserialize()

    */    

    getError: function() {

        return this.message + "\n" + this.cont;

    },

    // }}}

    // {{{ raiseError

    /**

    *  Raises an eror (called by unserialize().)

    *

    *  @param    string    message    the error message

    *  @param    string    cont       the remaining unserialized content

    */    

    raiseError: function(message, cont) {

        this.error = 1;

        this.message = message;

        this.cont = cont;

    }

    // }}}

}

// }}}