  var xmlHttp = createXmlHttpRequestObject(); // переменная для хранения ссылки на объект XMLHttpRequest
  var serverAddress = "/";       // адресс сервера
  var serverParams = "";                      // парамерты запроса
  var modelCache = new Array();


  // создает экземпляр объекта XMLHttpRequest
  function createXmlHttpRequestObject(){
    // переменная для хнанения ссылки на объект XMLHttpRequest
    var xmlHttp;
    // эта часть кода должна работать во всех броузерах, за исключением
    // IE6 и более старых его версий
    try{
      // попытаться создать объект XMLHttpRequest
      xmlHttp = new XMLHttpRequest();
    }
    catch(e){
      // предполагается, что в качестве броузера используется
      // IE6 или более старая его версия
      try {
        // попытаться создать объект XMLHttpRequest
        xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch (e) {
        try {
          // попытаться создать объект XMLHttpRequest
          xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        catch (e) {}
      }

    }
    // вернуть созданный объект или вывести сообщение об ошибке
    if (!xmlHttp)
      alert("Uneble to create object XMLHttpRequest.");
    else
      return xmlHttp;
  }


  // вызывается для чтения файла с сервера
  function processGET(Params){    // продолжить только если в xmlHttp не пустая ссылка
    if (xmlHttp){
      // попытаться установить соединение с сервером
      try{
        // инициировать асинхронный запрос HTTP
        xmlHttp.open("GET", serverAddress + "ajax/index.php?"+Params, true);
        xmlHttp.onreadystatechange = handleRequestStateChange;
        xmlHttp.send(null);
      }
      catch(e){
        alert("Uneble to connect with server:\n"+e.toString());
      }
    }
  }


  // эта функция вызывается при изменении состояния запроса HTTP
  function handleRequestStateChange(){
    // когда readyState = 4, мы можем прочитать ответ сервера
    if (xmlHttp.readyState == 4){
      // продолжать, только если статус HTTP равен "OK"
      if (xmlHttp.status == 200){
        try{
          // обрабатывать ответ полученный от сервера
          handleServerResponse();
        }
        catch(e){
          // вывести сообщение об ошибке
          alert("Error answer read: "+e.toString());
        }
      }
      else{
        // вывести сообщения о состоянии
        alert("Unable to resive data:\n" + xmlHttp.statusText);
      }
    }
  }



  // обрабатывает ответ, полученный от сервера
  function handleServerResponse(){
    //получить ответ сервера в виде объекта DOM XML
    var xmlResponse = xmlHttp.responseXML;
    // Предотвратить потенциально возможные ошибки в IE и Opera
    if (!xmlResponse || !xmlResponse.documentElement)
      throw("Неверная структура XML:\n" + xmlHttp.responseText);
    // Предотвратить потенциально возможные ошибки в Firefox
    var rootNodeName = xmlResponse.documentElement.nodeName;
    if (rootNodeName == "parsererror")
      throw("Неверная структура XML:\n" + xmlHttp.responseText);
    // Получить ссылку на корнеуой элемент документа XML
    var xmlRoot = xmlResponse.documentElement;
    // проверить корректность принятого документа XML
    if (rootNodeName != 'response' || !xmlRoot.firstChild)
      throw("Неверный формат документа XML:\n" + xmlHttp.responseText);
    // значение которое требуется отобразить, находится
    // в дочернем элементе корневого элемента <response>
    var action = xmlRoot.getAttribute("action");

    switch(action){
      case "login":
        LoginResult(xmlRoot);
        break;
      case "commenttimelimit":
        CommentResult(xmlRoot);
        break;
      case "comcommenttimelimit":
        ComCommentResult(xmlRoot);
        break;
      case "setmark":
        SetMarkResult(xmlRoot);
        break;
      
    }
  }



  // ==========================================================================================================
  // ==========================================================================================================

  // Запрашиваем у сервера модели производителя, либо достаем из кэша
  // getModelByProducerId
  function getModels(Id){
    if (Id != 0){
      var model = document.getElementById("catModel").options;
      model.length = 0;
      model[0] = new Option("Loading...", 0, false, false);

      if (modelCache[Id])
        InsertModelToDocument("catModule", null, Id)
      else
        processGET("action=getmodel&parent_id="+Id);
    }
    else{
      var model = document.getElementById('catModel').options;
      model.length = 0;
      model[0] = new Option('--',0,false,false);
    }
  }

  // Вставляем в селект модели производителя из xmlDoc,
  // если мы эти модели уже получали то достаем из кэша (modelCache)
  function InsertModelToDocument(elementId, xmlDoc, Id){
    var model = document.getElementById('catModel').options;
    model.length = 0;

    if (modelCache[Id]){
      for (var i=0; i < modelCache[Id].length; i++){
        name = modelCache[Id][i][0];
        id   = modelCache[Id][i][1];
        model[i] = new Option(name, id, false, false);
      }
    }
    else{
//      auto = xmlDoc.firstChild;
      parent_id = xmlDoc.getAttribute("id");

      modelCache[parent_id] = new Array();

      autoArray = xmlDoc.getElementsByTagName('auto');
      for (var i=0; i < autoArray.length; i++){
        name = autoArray[i].childNodes.item(1).firstChild.nodeValue;
        id = autoArray[i].childNodes.item(0).firstChild.nodeValue;
        modelCache[parent_id][i] = new Array(name, id);
        model[i] = new Option(name, id, false, false);
      }
    }

//    alert(autoArray[1].childNodes.item(0).firstChild.nodeValue)
//    alert(autoArray[1].childNodes.item(1).firstChild.nodeValue)
  }


  // ==========================================================================================================
  // ==========================================================================================================


  function getGenerationByModelId(Id, elementId){
    if (Id != 0){
      document.getElementById(elementId).innerHTML = "Loading...";
      processGET("action=getgeneration&id="+Id);
    }
  }

  function InsertGenerationsToDocument(elementId, xmlDoc){
    var string = '<table>';
    autoArray = xmlDoc.getElementsByTagName("generation");
    for (var i=0; i < autoArray.length; i++){
      var id = autoArray[i].childNodes.item(0).firstChild.nodeValue;
      var firm = autoArray[i].childNodes.item(1).firstChild.nodeValue;
      var model = autoArray[i].childNodes.item(2).firstChild.nodeValue;
      var syear = autoArray[i].childNodes.item(3).firstChild.nodeValue;
      var eyear = autoArray[i].childNodes.item(4).firstChild.nodeValue;
      var frames = autoArray[i].childNodes.item(5).firstChild.nodeValue;
      var bodytype = autoArray[i].childNodes.item(6).firstChild.nodeValue;
      var img = autoArray[i].childNodes.item(7).firstChild.nodeValue;
      string += '<tr><td class="autocat1"><a href="?gen='+id+'"><img src="'+img+'" width="200px" /></a></td><td><a href="?gen='+id+'">'+firm+' '+model+'</a><p />'+syear+' - '+eyear+'<p /> '+bodytype+' <p /> '+frames+' </td></tr>';
    }
    string += '</table>';
    document.getElementById(elementId).innerHTML = string;
  }


  // ==========================================================================================================
  // ==========================================================================================================

function Dump(d,l) {
    if (l == null) l = 1;
    var s = '';
    if (typeof(d) == "object") {

        s += typeof(d) + " {<br />";

        for (var k in d) {
            for (var i=0; i<l; i++) s += "  ";
            s += k+": " + d[k] + "<br />";;
//            s += k+": " + Dump(d[k],l+1);
        }

        for (var i=0; i<l-1; i++) s += "  ";

        s += "}<br />"
    } else {
        s += "" + d + "<br />";
    }
    return s;
}
