/*
 AjaxRequest - внешний интерфейс к асинхронному механизму запросов.
*/
var URLRegexp = new RegExp();
URLRegexp.compile("^http://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_\/.]+$");

//----- debug
function printr(o){ s = ""; for(k in o){s += k +"=["+eval("o[k]")+"], ";} alert(s);}

function validateUrl(str){
 //  return  URLRegexp.test(str);
 	return true;
}

function Dispatcher(){
  this.collection = new Array();
  this.add   = function(obj){
    this.collection[this.collection.length] = obj;
    return this.collection.length-1;
  }
  this.get   = function(num){return this.collection[num];}
  this.unset = function(num){return this.collection[num]=null;}
}

var Globals = new Dispatcher;

function isMethodBelongToObject(obj,method){
  return typeof(method)=='string'
  && method.length!=0
  && eval('obj.' + method)!=undefined
  && typeof(eval('obj.' + method))=='function';
}

function isUrl(param){
    return typeof(param)=='string'
          && param.length>0
          && validateUrl(param);
}

function isObject(param){
  return typeof(param)=='object';
}

function CreateAjaxRequest(customer, url, successMeth, unSuccessMeth, traceArgs){
    if(isObject(customer)
    && isMethodBelongToObject(customer,successMeth)
    && isMethodBelongToObject(customer,unSuccessMeth)
    && isUrl(url)
    ){
     return new AjaxRequest(customer, url, successMeth, unSuccessMeth, traceArgs);
   }else{
     return null;
   }
}

function AjaxRequest(customer, url, successMeth, unSuccessMeth, traceArgs){
   this.method        = 'GET';                    // HTTP метод
      this.url           = url;                      // url
         this.traceArgs     = traceArgs || null;        // набор аргументов для методов заказчика
            this.successCode   = '200';                    // код успешного запроса
               this.timeout       = 5000;                     // временной лимит
                  this.timer         = null;                     // таймер
                     this.body          = null;                     // тело запроса
                        this.customer      = customer;                 // внешний объект-заказчик
                        
   this.successMeth   = successMeth;              // имя метода, который будет вызван  в случае успешного завершения
   
   this.unSuccessMeth = unSuccessMeth;            // имя метода, который будет вызван  в случае провала
   
   this.result        = null;                     // текст ответа
   
   this.params        = [];                       // набор GET-параметров
   
   this.randurl       = false;                     // random в url, по умолчанию включен
   
   this.provider      = new AjaxProcessor(this);  // обработчик запроса
   
   this.dnum          = Globals.add(this);        // регистрируемся в диспетчере
   
   this.async         = true;                     // флаг
   
}

AjaxRequest.prototype.setTimeout           = function(timeout){
  this.timeout = timeout;
}

AjaxRequest.prototype.getTimeout           = function(timeout){
  return this.timeout;
}

AjaxRequest.prototype.calculateUrl         = function(){
  var fullUrl = this.url;
  full    = this.params.length || this.randurl  ?'?':'';
  for(var i=0;i<this.params.length;i++) {
    full += '&' + this.params[i][0] + '=' + encodeURIComponent(this.params[i][1].toString()); //.replace(/&/,'%26').replace(/\+/,'%2B');
  }
  full += this.randurl?'&rnd='+ Math.random():'';
  if (this.method=='POST') {
	this.body=full;
	return this.url;
	}
  return this.url+full;
}

AjaxRequest.prototype.setSuccessCode = function(sCode){
  this.successCode = sCode;
  return true;
}

AjaxRequest.prototype.setParam       = function(name,value,index){
  var pos = isNaN(index)?this.params.length:index;
  this.params[pos]=[name,value];
  return pos;
}

AjaxRequest.prototype.setMethod      = function(sMethod){
  if(sMethod=='GET'||sMethod=='POST'){
    this.method=sMethod;
    return true;
  }
  return false;
}

AjaxRequest.prototype.getMethod      = function(){
  return this.method;
}

AjaxRequest.prototype.start          = function(){
  return this.provider.start();
}

AjaxRequest.prototype.wakeup    = function(httpCode,text){
  
  if(this.timer){clearTimeout(this.timer);}
  //alert(this.calculateUrl());
  //alert(httpCode+"\n-----\n"+text);
  //this.provider.stop();
  
  var args = (this.traceArgs!=null?

	(typeof(this.traceArgs)=='object'?'this.traceArgs':'"'+this.traceArgs+'"')
		
	:'"0"');
//	alert(this.successMeth   + '(text' + (args?', '+args:'')+')');

  eval('this.customer.' + (httpCode==this.successCode
                            ? this.successMeth   + '(text' + ', '+args+')'
                            : this.unSuccessMeth + '('+ args + ')'
                          )
      );
 }

AjaxRequest.prototype.sleep     = function(){
  this.timer = window.setTimeout('Globals.get('+this.dnum+').wakeup();', this.timeout);
}