function Ajax()
{
   // Булевая переменная, признак синхронного запроса.
   this.synchronous = false;

   // Назначение: получение объекта XMLHttpRequest.
   this.getRequestObject = function()
   {
      var req = null;
      if (typeof XMLHttpRequest != "undefined") req = new XMLHttpRequest();
      if (!req && typeof ActiveXObject != "undefined")
      {
         try {req = new ActiveXObject("Msxml2.XMLHTTP");}
         catch(e)
         {
            try {req = new ActiveXObject("Microsoft.XMLHTTP");}
            catch (e2)
            {
               try {req = new ActiveXObject("Msxml2.XMLHTTP.4.0");}
               catch (e3) {req = null;}
            }
         }
      }
      if(!req && window.createRequest) req = window.createRequest();
      if (!req) alert("Request Object Instantiation failed.");
      return req;
   }

   // Назначение: исполнение ajax - запроса.
   // url - uri документа;
   // params - массив параметров, передаваемых документу;
   // httpMethod - способ передачи данных (POST или GET).
   // Функция возвращает true, в случае успеха и false, в случае неудачи.
   this.sendRequest = function(url, params, httpMethod)
   {
      if (url.charAt(url.length-1) == '#') url = url.substr(0, url.length-1);
      if (!httpMethod) httpMethod = "POST";
      var req = this.getRequestObject();
      if (req)
      {
         ajax.showAjaxLoader();
         req.open(httpMethod, url, !this.synchronous);
         req.setRequestHeader("Method", "POST " + url + " HTTP/1.1");
         req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
         req.onreadystatechange = function()
         {
            if (req.readyState != 4) return;
            if (req.status == 200 || req.status == 0)
            {
               eval(req.responseText);
               ajax.hideAjaxLoader();
               delete req;
            }
            else
            {
               ajax.hideAjaxLoader();
               alert("Error: the server returned the following HTTP status: " + req.status);
               return false;
            }
         }
         req.send(params);
         return true;
      }
      return false;
   }

   // Назначение: вызов ajax-функции.
   // func - имя ajax-функции.
   this.call = function(func)
   {
      var url = new String(window.location);
      var params = "", i = 1;
      var args = arguments;
      if (arguments.length == 2 && typeof(arguments[1]) == 'object')
      {
        args = arguments[1];
        i = 0;
      }
      params += "ajaxfunc=" + encodeURIComponent(func);
      for (; i<args.length; i++)
        params += "&ajaxargs[]=" + encodeURIComponent(ajax.encodeObj(args[i]));
      return this.sendRequest(url, params);
   }

   // Назначение: преобразование js-объекта или js-массива в строку.
   // param - js-объект или js-массив.
   this.encodeObj = function(param)
   {
      if (typeof(param) == 'object')
      {
         var obj = "<ajaxarray>";
         for (i in param)
         {
             if (i == 'constructor' || param[i] && typeof(param[i]) == 'function') continue;
             obj += "<k>"+i+"</k><v>"+ajax.encodeObj(param[i])+"</v>";
         }
         obj += "</ajaxarray>";
         return obj;
      }
      return param;
   }

   // Назначение: отображение признака выполнение запроса.
   this.showAjaxLoader = function()
   {
      if (document.body) document.body.style.cursor = 'wait';
      if (e('ajax_loader'))
      {
         var el = e('ajax_loader');
         el.style.position = 'absolute';
         el.style.left = document.body.scrollLeft+document.body.clientWidth/2-15;
         el.style.top = document.body.scrollTop+document.body.clientHeight/2-15;
         show('ajax_loader');
      }
   }

   // Назначение: скрытие признака выполнения запроса.
   this.hideAjaxLoader = function()
   {
      if (document.body) document.body.style.cursor = 'default';
      hide('ajax_loader');
   }
   
   this.getFormValues = function(form, pref)
   {
      var objForm;
      if (typeof(form) == "string") objForm = $(form);
      else objForm = form;
      if (objForm)
      {
         var values = new Array();
         var elements = objForm.getFormElements();
         for(var i = 0; i < elements.length; i++)
         {
            if (elements[i].type && (elements[i].type == 'radio' || elements[i].type == 'checkbox') && elements[i].checked == false) continue;
            var name = elements[i].name;
            if (pref)
            {
               var k = name.indexOf(pref);
               if (k != -1) name = name.substr(0, k);
            }
            if (name)
            {
               if (elements[i].type == 'select-multiple')
               {
                  for (var j = 0; j < elements[i].length; j++)
                  {
                     if (elements[i].options[j].selected == true)
                       if (name.substr(name.length - 2) == '[]')
                       {
                  	      name = name.substr(0, name.length - 2);
                  	      if (typeof(values[name]) == 'undefined') values[name] = new Array();
                  	      values[name][values[name].length] = elements[i].options[j].value;
                       }
                       else values[name][j] = elements[i].options[j].value;
                  }
               }
               else
               {
                  if (name.substr(name.length - 2) == '[]')
                  {
                  	 name = name.substr(0, name.length - 2);
                  	 if (typeof(values[name]) == 'undefined') values[name] = new Array();
                  	 values[name][values[name].length] = elements[i].value;
                  }
                  else values[name] = elements[i].value;
               }
            }
         }
         return values;
      }
   }
}

// Создание объекта ajax.
var ajax = new Ajax();