/*******************************************************************************
 *                                   AJAX.                                                            
 ******************************************************************************/ 
/*******************************************************************************
 * Instance of a ajaxController class:
 * 
 * this object provide work with AJAX,
 * don`t edit this name!!!;
 */
var ajaxController = new ajaxController(); 

/*******************************************************************************
 * Create XmlHttpRequest object:
 * 
 * @return  object  return XmlHttpRequest object or null if error detect;
 */
function createXmlHttpRequestObject()
{        
  var xmlHttpRequest = null;
  
  try {        
    xmlHttpRequest = new XMLHttpRequest();
  } catch (error) {
    //for MS IE
    try {
      xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (error) {
      try {
        xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (error) {
        xmlHttpRequest = null;
        alert("Ошибка создания XMLHttpRequest объекта!");
      }
    }
  }
  	
  return xmlHttpRequest; 
}

/*******************************************************************************
 */
function requestData(httpMethod, actionScriptUrl, requestBody, responseHandlerData)
{  
    this.method       = httpMethod;
    this.url          = actionScriptUrl;
    this.body         = requestBody;
    this.handlerName  = responseHandlerData['name'];
    this.handlerParam = responseHandlerData['param'];       
}

/*******************************************************************************
 */ 
function ajaxController()
{
  this.xhr                  = createXmlHttpRequestObject();    
  this.responseHandlerList  = {};
  this.requestDataCache     = [];  
  this.responseHandlerName  = '';
  this.responseHandlerParam = null;
    
  //регистрация(добавление) обработчика
  this.addHandler = function(responseHandlerName, responseHandlerBody)
  {
    this.responseHandlerList[responseHandlerName] = responseHandlerBody;
  }
  
  //регистрация(добавление) запроса
  this.addRequest = function(httpMethod, actionScriptUrl, requestBody, responseHandlerData, requestType)
  {
    var newRequestData = new requestData(httpMethod, actionScriptUrl, requestBody, responseHandlerData);
    
    switch (requestType) {
      case 0: {
        this.requestDataCache.push(newRequestData);                
        break;
      }
      case 1: {
        this.requestDataCache.unshift(newRequestData);
        break;
      }
      case 2: {
        this.requestDataCache = [newRequestData];
        break;
      }
    }    
   
    this.send();   
  }
  
  //функция оправки запроса
  this.send = function()
  {        
    var request;
            
    if ((this.xhr.readyState == 4 || this.xhr.readyState == 0) && this.requestDataCache.length > 0) {                
      request = this.requestDataCache.shift();            
      
      this.xhr.open(request.method, request.url, true);            
      if (request.method == "POST" || request.method == "post" || request.method == "Post") {
          this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      }
      this.xhr.onreadystatechange = this.processRequestStateChanges;            
      this.responseHandlerName    = request.handlerName;
      this.responseHandlerParam   = request.handlerParam;            
      this.xhr.send(request.body);      
    }
  }

  //встроенная обработка ответа
  this.processRequestStateChanges = function()
  {      
    if (ajaxController.xhr.readyState != 4) {
      return;
    }
    
    //выполнить пользовательский обработчик ответа
    ajaxController.responseHandlerList[ajaxController.responseHandlerName](ajaxController.responseHandlerParam, ajaxController.xhr);      
    setTimeout("ajaxController.send();", 500);
  }    
}

/*******************************************************************************
 * Функция для трансляции данных элементов формы в строку
 * для передачи в AJAX-запросе.
 * 
 * @var object  активный элемент формы;
 *       
 * @return  string  кодированная строка с данными формы;
 */
function getFormData(formActivElem)
{
    var formObj   = formActivElem.form;
    var crntElem  = "";
    var formData  = "";
    
    for (var i=0; i<formObj.elements.length; i++) {
        crntElem = formObj.elements[i];
        
        switch (crntElem.type) {
            case "text":  
            case "hidden":  
            case "password":  
            case "textarea":                                              
                formData += crntElem.name + "=" + encodeURIComponent(crntElem.value) + "&";  
                break;  

            case "checkbox":  
            case "radio":
                if (crntElem.checked) {
                    formData += crntElem.name + "=" + encodeURIComponent(crntElem.value) + "&";
                }                  
                break;  
  
            case "select-one":  
                formData += crntElem.name + "=" + encodeURIComponent(crntElem.options[crntElem.selectedIndex].value) + "&";  
                break;
            
            case "button":  
                if (crntElem == formActivElem) {
                    formData += crntElem.name + "=" + encodeURIComponent(crntElem.value) + "&";
                }  
                break;
        }
    }
    
    return formData.substr(0,(formData.length-1));
}
