var Ajax = {
  server:'',
  debug:true,
  requests:{},
  requests_num:0,
  callFunction:function(){
	var r = new AjaxRequest(); //this.getTransport();
	r.callFunction(arguments);
  },
  $:function(id){
    return document.getElementById(id);
  },
  callFunctionArg:function(func_name,args){
	var r = new AjaxRequest(); //this.getTransport();
	r.callFunctionArg(func_name,args);
  },  
  toJSONString:function(value){
  		if (value==null) return 'null';
        switch (typeof value) {
        case 'object':
        	if (value.constructor === Array){
				return this.arrayToJSONString(value);
			}
			else {
				return this.objectToJSONString(value);
			}
        case 'string':
           	return this.stringToJSONString(value);
        case 'number':
           	return this.numberToJSONString(value);
        case 'boolean':
           	return this.booleanToJSONString(value);
        }  
  },
  arrayToJSONString:function(value) {
        var a = [], i,          // Loop counter.
            l = value.length,
            v;          // The value to be stringified.
        for (i = 0; i < l; i += 1) {
            v = value[i];
            a.push(this.toJSONString(v));
        }
        return '[' + a.join(',') + ']';
  },
  booleanToJSONString:function (value) {
        return String(value);
  },
  dateToJSONString:function (value) {
        function f(n) {
            return n < 10 ? '0' + n : n;
        }
        return '"' + value.getUTCFullYear() + '-' +
                f(value.getUTCMonth() + 1) + '-' +
                f(value.getUTCDate()) + 'T' +
                f(value.getUTCHours()) + ':' +
                f(value.getUTCMinutes()) + ':' +
                f(value.getUTCSeconds()) + 'Z"';
  },
  numberToJSONString:function (value) {
        return isFinite(value) ? String(value) : 'null';
  },  
  objectToJSONString:function (value) {
        var a = [],     // The array holding the partial texts.
            k,          // The current key.
            v;          // The current value.
        if (value==null) return 'null';
        for (k in value) {
            if (typeof k === 'string' && Object.prototype.hasOwnProperty.apply(value, [k])) {
                v = value[k];
                switch (typeof v) {
                case 'object':
                	if (v.constructor === Array){
						a.push(this.stringToJSONString(k) + ':' + this.arrayToJSONString(v));
					}
					else {
						a.push(this.stringToJSONString(k) + ':' + this.objectToJSONString(v));
					}
				break;
                case 'string':
                	a.push(this.stringToJSONString(k) + ':' + this.stringToJSONString(v));
                break;
                case 'number':
                	a.push(this.stringToJSONString(k) + ':' + this.numberToJSONString(v));
                break;
                case 'boolean':
                    a.push(this.stringToJSONString(k) + ':' + this.booleanToJSONString(v));
                break;
                }
            }
        }
        return '{' + a.join(',') + '}';
  },  
  stringToJSONString:function (value) {
        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };
        if (/["\\\x00-\x1f]/.test(value)) {
                return '"' + value.replace(/[\x00-\x1f\\"]/g, function (a) {
                    var c = m[a];
                    if (c) {
                        return c;
                    }
                    c = a.charCodeAt();
                    return '\\u00' +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + value + '"';
  },
  parseJSON:function (value,filter) {
    var j;
    function walk(k, v) {
                var i;
                if (v && typeof v === 'object') {
                    for (i in v) {
                        if (Object.prototype.hasOwnProperty.apply(v, [i])) {
                            v[i] = walk(i, v[i]);
                        }
                    }
                }
                return filter(k, v);
    }
    if (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/.test(value.
                    replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) {
                j = eval('(' + value + ')');
                return typeof filter === 'function' ? walk('', j) : j;
    }
    else {
    	if (this.debug){
    		alert(value);
    	}
    	throw new SyntaxError('parseJSON');
    }
  },
  renderResponses:function(responses){
  	for(var i=0;i<responses.length;i++){
  		var response = responses[i];
  		this.renderResponse(response);
  	}
  },
  renderResponse:function(response){
    //alert(this.toJSONString(response));
    if (response.c=='cm'){ //call method
      var params = [];
      for(var i=0;i<response.a.length;i++){
        params[i] = "response.a["+i+"]";
      }
      var s = response.o+"."+response.m+"("+params.join(",")+")";
      eval(s);
    }
    if (response.c=='sc'){ //script call
      var params = [];
      for(var i=0;i<response.a.length;i++){
        params[i] = "response.a["+i+"]";
      }
      var s = response.f+"("+params.join(",")+")";
      eval(s);
    }    
    else if (response.c=='a'){ //call method
      alert(response.m);
    }
	else if (response.c=='e'){ //eval script
      eval(response.s);
    }
	else if (response.c=='s'){ //aSsign
      var obj = this.$(response.e);
      if (obj) {
          obj[response.p] = response.v;
          AT.update(obj);
      }
    }         
  },
  getTransport:function(){
  		try {
			return new ActiveXObject("Microsoft.XMLHTTP");
		} 
		catch (e) {}
		try {
			return new XMLHttpRequest();
		} 
		catch (e) {}
		
  },
  getFormValues:function (frm){
	var objForm;
	var submitDisabledElements=false;
	if(arguments.length > 1 && arguments[1]==true)
		submitDisabledElements=true;var prefix="";
	if(arguments.length > 2)
		prefix=arguments[2];
	if(typeof(frm)=="string") objForm=$(frm);
	else objForm=frm;
	var values = {};
	if(objForm && objForm.tagName.toUpperCase()=='FORM'){
		var formElements=objForm.elements;
		for(var i=0;i < formElements.length;i++){
			if(!formElements[i].name) continue;
			if(formElements[i].name.substring(0,prefix.length)!=prefix) continue;
			if(formElements[i].type && (formElements[i].type=='radio' 
			|| formElements[i].type=='checkbox') && formElements[i].checked==false) continue;
			if(formElements[i].disabled && formElements[i].disabled==true && submitDisabledElements==false) continue;
			var name=formElements[i].name;
			if(name){
				values[name] = formElements[i].value;
			}
		}
	}
	return values;
  }
  
}


function AjaxRequest(){
	this.xmlhttp = Ajax.getTransport();
}
AjaxRequest.prototype.callFunction = function(args){
	var func = args[0];
	var el_argx = [];
	for(var i=1;i<args.length;i++){
	  el_argx.push(args[i]); 
	}
	var request = {'f':func,'a':el_argx};
	var json_request = Ajax.toJSONString(request);
	this.xmlhttp.open('post',Ajax.server,true);
	this.xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	this.xmlhttp.send('r='+encodeURIComponent(json_request));
	var this1 = this;
	this.xmlhttp.onreadystatechange = function(){
	  if (this1.xmlhttp.readyState==4){
	  	var responses = Ajax.parseJSON(this1.xmlhttp.responseText);
	  	Ajax.renderResponses(responses);
	  }
	}
}
AjaxRequest.prototype.callFunctionArg = function(func_name,args){
	var el_argx = [];
	for(var i=0;i<args.length;i++){
	  el_argx.push(args[i]); 
	}
	var request = {'f':func_name,'a':el_argx};
	var json_request = Ajax.toJSONString(request);
	this.xmlhttp.open('post',Ajax.server,true);
	this.xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	this.xmlhttp.send('r='+encodeURIComponent(json_request));
	var this1 = this;
	this.xmlhttp.onreadystatechange = function(){
	  if (this1.xmlhttp.readyState==4){
	  	var responses = Ajax.parseJSON(this1.xmlhttp.responseText);
	  	Ajax.renderResponses(responses);
	  }
	}
}

