function formSender(f){
    var callback = typeof(arguments[1])=="undefined" ? null : arguments[1];
    var fmt = typeof(arguments[2])=="undefined" ? null : arguments[2];
    if(f){
        var oldOnLoad = window.onload;
        /*window.onload = function(){
		    if(typeof(oldOnLoad)!="undefined" && oldOnLoad!=null)
			    oldOnLoad();
            var q = new formSender(0);
            q.init(f, callback, fmt);
        }*/
        if(typeof(oldOnLoad)!="undefined" && oldOnLoad!=null)
            window.onload = function(){
		        oldOnLoad();
                var q = new formSender(0);
                q.init(f, callback, fmt);
            }
        else
            window.onload = function(){
                var q = new formSender(0);
                q.init(f, callback, fmt);
            }

    }
}

formSender.prototype.init = function(form_id, callback, fmt){
    var th = this;
    var p = form_id.split(".");
    this.formId = p[1];
    this.cls = p[0];
    document.getElementById(this.formId).onsubmit = function(){
        th.send(callback, fmt);
        return false;
    }
}

formSender.prototype.send = function(callback, fmt){
    var th = this;
    var form = document.getElementById(this.formId);
    try {
       var errorTitle = document.getElementById('errorTitle');
       document.getElementById(th.formId.split('_')[0]+'_div').removeChild(errorTitle);        
    }
    catch(e){}
    try {
       var successTitle = document.getElementById('successTitle');
       document.getElementById(th.formId.split('_')[0]+'_div').removeChild(successTitle);        
    }
    catch(e){}
    var par = this.serialize(form);
    if(par==null)
        return;
    var http = this.ajax();
    //var url = '/cls/call?cls='+this.cls+'&fun='+this.formId.split('_')[0] + (fmt == null ? "" : "&fmt="+fmt);
    var url = '/fun/?cls='+this.cls+'&fun='+this.formId.split('_')[0] + (fmt == null ? "" : "&fmt="+fmt);
    http.open('POST', url, true);
    //Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.setRequestHeader("Content-length", par.length);
    http.setRequestHeader("Connection", "close");

    http.onreadystatechange = function() {//Call a function when the state changes.
	    if(http.readyState == 4 && http.status == 200) {
	            if(callback!=null)
	            {
                    th.callback = callback;
                    th.callback(http.responseText);
                }
	            else
                {
                    var node = document.getElementById(th.formId.split('_')[0]+'_div');
                    var successTitle = document.createElement("h2");
                    successTitle.setAttribute("id","successTitle")
                    successTitle.innerHTML = http.responseText;
                    node.insertBefore(successTitle, node.firstChild);
                    document.getElementById(th.formId).reset();
                }
	    }
	    if(http.readyState == 4 && http.status == 500) {
	        //var patt = new RegExp("ORA-20000: GearExp:(.*)");
	        var patt = new RegExp("ORA-20000: (.*)");
            try{
                var node = document.getElementById(th.formId.split('_')[0]+'_div');
                var errorTitle = document.createElement("h2");
                errorTitle.setAttribute("id","errorTitle")
                errorTitle.style.color = "red";
                errorTitle.innerHTML = patt.exec(http.responseText)[1];
                node.insertBefore(errorTitle, node.firstChild);
            }
            catch(e)
            {
                var node = document.getElementById(th.formId.split('_')[0]+'_div');
                var errorTitle = document.createElement("h2");
                errorTitle.setAttribute("id","errorTitle")
                errorTitle.style.color = "red";
                errorTitle.innerHTML = "Ошибка при вызове функции";
                node.insertBefore(errorTitle, node.firstChild);
            }
            window.scrollTo(0,0);
        }
    }
    http.send(par);
}

formSender.prototype.serialize = function(form){
    var result = '';
    var delim = '';
    var cur;
    var formPrefix = this.formId.split('_')[0];
    try {
       var errorTitle = document.getElementById('errorTitle');
       errorTitle.parentNode.removeChild(errorTitle);        
    }
    catch(e){}
    for(var i=0;i<form.elements.length;i++)
    {
        cur = form.elements[i];
        if(cur.id.indexOf(formPrefix)==0 || cur.id.indexOf('req_'+formPrefix)==0)
        {
            if(cur.id.indexOf('req_'+formPrefix)==0){
                cur.className = "txt"; //думаем что ошибки больше нет
                if(cur.value && cur.value != "undefined")
                    var value = cur.value;
                else
                    var value = cur.innerHTML;
                if(!value)
                {
                    cur.focus();
                    cur.className = "txtError";     //ошибка все таки есть
                    var errorTitle = document.createElement("span");
                    errorTitle.setAttribute("id","errorTitle")
                    errorTitle.className = "errorTitle";
                    errorTitle.innerHTML = 'Заполните обязательное поле "'+cur.title+'"';
                    cur.parentNode.appendChild(errorTitle);
                    return null;
                }
                else
                {
                    var reg = document.getElementById(cur.id).getAttribute("regvalid");

                    if(reg && reg !="undefined")
                    {
                        reg = reg.split("/");
                        var reg = new RegExp(reg[1],reg[2]);
                        if(!reg.test(value))
                        {
                            cur.focus();
                            cur.className = "txtError";     //ошибка все таки есть
                            var errorTitle = document.createElement("span");
                            errorTitle.setAttribute("id","errorTitle")
                            errorTitle.className = "errorTitle";
                            errorTitle.innerHTML = 'Поле "'+cur.title+'" заполнено неверно';
                            cur.parentNode.appendChild(errorTitle);
                            return null;
                        }
                    }
                }
            }
            switch(cur.type)
            {
                case 'textarea':
                case 'text':
                case 'hidden':
                    result += delim + this.c_encode(cur.name) + '=' + this.c_encode(cur.value);
                    delim = '&';
                break;
                case "radio":
                case 'checkbox':
                    if(cur.checked){
                        result += delim + this.c_encode(cur.name) + '=' + this.c_encode(cur.value);
                        delim = '&';
                    }
                break;
                case 'select-multiple':
                    var val = '';
                    var qdelim = '';
                    for(var k=0;k<cur.options.length;k++)
                    {
                        if(cur.options[k].selected)
                        {
                            f = 1;
                            val += qdelim+this.c_encode(cur.options[k].value);
                            qdelim = ';';
                        }
                    }
                    if(val!=''){
                        result += delim + this.c_encode(cur.name)+'='+val;
                        delim = '&';
                    }
                break;
                case 'select-one':
                    result += delim + this.c_encode(cur.name) + '=' + this.c_encode(cur.options[cur.selectedIndex].value);
                    delim = '&';
                break;
            }
        }
    }
    return result;
}

formSender.prototype.ajax = function(){
    var xmlHttp = false;
    try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e2) {
        xmlHttp = false;
      }
    }
    if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
      xmlHttp = new XMLHttpRequest();
    }
    return xmlHttp;
}

formSender.prototype.c_encode_ie = function(s) {
        s = s.toString();
        var i,r = [];
        for (i = 0; i < s.length; i++) switch (s.charAt(i)) {
            case '\r': r.push('\\r'); break;
            case '\n': r.push('\\n'); break;
            case '\t': r.push('\\t'); break;
            case '\\': r.push('\\\\'); break;
            default : r.push(s.charAt(i));
        }
        return r.join("");
    }

formSender.prototype.c_encode = function(s){
    if(s.length<=1)
        return s;
    if(s.length<100)
        return this.c_encode_old(s);
    if(!arguments.callee.fun)
        arguments.callee.fun = (window.navigator.userAgent.toString().match(new RegExp(".*MSIE.*","i"))) ? this.c_encode_ie : this.c_encode_old;
    return arguments.callee.fun(s);
}

formSender.prototype.c_encode_old = function(s) {
s = ""+s;
var i,r="";
for(i=0;i<s.length;i++) switch(s.charAt(i)) {
 case '\r': r+='\\r'; break;
 case '\n': r+='\\n'; break;
 case '\t': r+='\\t'; break;
 case '\\': r+='\\\\'; break;
 default : r+=s.charAt(i);
 }
return r;
}
