
/*   Developed by Uharanov Murad, 2007-2008
 *
 *
 *
 *
 *
 *
 *
 */

// classic trim()
String.prototype.trim = function() { 
   return this.replace(/^\s+|\s+$/g,''); 
}

// classic now()
now = function(){
	return new Date().getTime();
}


// http://snippets.dzone.com/posts/show/4655
function serialize(value) {
	return JSerialize(value);
}





//
 //   Loading Manager
  //
  

  
//// Class of one cache record  
function /* record */ cl_lm_cache_record(arg_url, arg_req_data, arg_data, arg_death_time) {

	//alert('new lmcr ' + arg_url + arg_death_time);
	
	this.url = null;
	this.req_data = null;
  this.data = null;
  this.death_time = null;
  
  if(typeof arg_death_time != 'undefined') {
		this.url = arg_url;
		this.req_data = arg_req_data;
	  this.data = arg_data;
	  this.death_time = arg_death_time;
  }
  
}



//// Main class
function /* class */ cl_loading_manager(arg_cache_time) {

  this.cache = Array();
  this.cache_time = -1;
  
  if(typeof arg_cache_time != 'undefined') {
  	this.cache_time = arg_cache_time;
  }
  
}

// Add to cache
cl_loading_manager.prototype.add_to_cache = function(url, req_data, data, death_time){
  
	this.kill_old_data();
	
	req_data = serialize(req_data);
	
	// Ishem, est li uge zapis' s takim url
	var i = 0; var len = this.cache.length;
	var ind = -1;
	for (i = 0; i < len; i++){
		if (this.cache[i]){
			if ((this.cache[i].url == url) && (this.cache[i].req_data == req_data)) {
				ind = i; break;
			}
		}
		
	}
	
	
	// esli est, perepisat' ee
	if (ind > -1){
		this.cache[ind].url = url;
		this.cache[ind].req_data = req_data;
		this.cache[ind].data = data;
		this.cache[ind].death_time = death_time;
	
	// esli net, ishem pustie zapisi
	} else {
		var ind = -1;
		for (i = 0; i < len; i++){
			if (this.cache[i] == null) {
				ind = i; break;
			}
		}
		
		// esli est pustaya zapis', zanimaem ee
		if (ind > -1){
			this.cache[ind] = new cl_lm_cache_record(url, req_data, data, death_time);
		
		// esli net, dobavlyaem v konec spiska
		} else {
			this.cache.push(new cl_lm_cache_record(url, req_data, data, death_time));
		}
	}
	
	//alert(Dump(this.cache));
	
	
}//fn

// Proverka, est li v keshe zapis s dannim url
cl_loading_manager.prototype.cached_check = function(url, req_data){
  
	this.kill_old_data();
	
	req_data = serialize(req_data);

	var i = 0; var len = this.cache.length;
	for (i = 0; i < len; i++){
		//alert('req_data:'+ req_data );
		//alert('req_data in cache:'+ this.cache[i].req_data);
		//alert('ravenstvo:'+ (this.cache[i].req_data == req_data));
		if (this.cache[i]){
			if ((this.cache[i].url == url) && (this.cache[i].req_data == req_data)) {
				//alert('hurray');
				return true;
			}
		}
	}
	return false;
	
}

// Load from cache
cl_loading_manager.prototype.load_from_cache = function(url, req_data){
  
	this.kill_old_data();
	
	req_data = serialize(req_data);

	var i = 0; var len = this.cache.length;
	for (i = 0; i < len; i++){
		if (this.cache[i]){
			if ((this.cache[i].url == url) && (this.cache[i].req_data == req_data)) {
				return this.cache[i].data;
			}
		}
	}
	
}
  
// Delete from cache
cl_loading_manager.prototype.delete_from_cache = function(url, req_data){
  
	req_data = serialize(req_data);

	var i = 0; var len = this.cache.length;
	for (i = 0; i < len; i++){
		if (this.cache[i]){
			if ((this.cache[i].url == url) && (this.cache[i].req_data == req_data)) {
				this.cache[i] = null;
			}
		}
	}
	
}

// Kill old cache records
cl_loading_manager.prototype.kill_old_data = function(){
  
	var t = now();
	var i = 0; var len = this.cache.length;
	for (i = 0; i < len; i++){
		if (this.cache[i]){
			if (this.cache[i].death_time <= t) {
				this.cache[i] = null;
			}
		}
		
	}

}//fn



//
 //   Dispatcher class
  //

function /* class */ cl_dispatcher(arg_lm, arg_method, arg_caching, arg_cache_time) {

  this.http_request = null;
  this.method = 'post';
  this.loading_manager = null;
  this.caching = true;
  this.cache_time = -1;
  
  if(typeof arg_caching != 'undefined') {
  	if (arg_caching == false) this.caching = false;
  }
  if(typeof arg_cache_time != 'undefined') {
  	this.cache_time = arg_cache_time;
  }
  if(typeof arg_method != 'undefined') {
  	if (arg_method.trim() == 'get') this.method = 'get';
  	if (arg_method.trim() == 'post') this.method = 'post';
  }
  if(typeof arg_lm != 'undefined') {
  	this.loading_manager = arg_lm;
  }
  
  
  this.state = null;
  this.response = null;
  this.from_cache = null;
  this.current_url = null;
  
  // call constructor
  this.constructor();
}
  
cl_dispatcher.prototype.constructor = function(){
  
  // create object http_request
  var browser = navigator.appName;
  if (browser == "Microsoft Internet Explorer") {
    this.http_request = new ActiveXObject("Microsoft.XMLHTTP");
  } else {
    this.http_request = new XMLHttpRequest();
  }
	this.http_request = new JsHttpRequest();
}

// AJAX request
cl_dispatcher.prototype.send_request = function(url, req_data, fn_r, start_fn){
  
	//alert(Dump(req_data));
	
	if ((this.caching)/* && (this.cache_time > -1)*/){
	
		if (this.loading_manager.cached_check(url, req_data)){
	  	this.from_cache = true;
		  this.state = 4;
		  this.response = this.loading_manager.load_from_cache(url, req_data);
	  	fn_r();
		} else {
	  	this.from_cache = false;
	  	this.current_url = url;
	  	this.current_req_data = req_data;
	  	
			this.http_request.open(this.method, url);
			this.http_request.onreadystatechange = fn_r;
			this.http_request.send(req_data);

			if (start_fn) start_fn();
		}
		
	} else {
  	
		this.http_request.open(this.method, url);
		this.http_request.onreadystatechange = fn_r;
		this.http_request.send(req_data);
	  
	  if (start_fn) start_fn();
	}
	
	
}


// check response state
cl_dispatcher.prototype.get_state = function(){
  
  
	if ((this.from_cache == false) || (this.caching == false)/* || (this.cache_time < 0)*/){
  	this.state = this.http_request.readyState;
  }
  return this.state;
}


// AJAX response
cl_dispatcher.prototype.get_response = function(){
  
	if ((this.from_cache == false) || (this.caching == false)/* || (this.cache_time < 0)*/){
		this.response = this.http_request.responseJS;
		//alert('current_url_to_cache -> ' + this.current_url);
		if ((this.current_url) && (this.caching == true)/* && (this.cache_time > -1)*/){
			
		
			// Define cache time depending on priority
			var final_cache_time;
			if (this.cache_time > -1) {
				
				final_cache_time = this.cache_time;
			
			} else if (this.loading_manager.cache_time > -1){
				
				final_cache_time = this.loading_manager.cache_time;
					
			} else {
				
				final_cache_time = 0;
				
			}
			
			/*
			
			Priority:
			
			
			3. cl_dispather.cache_time
			
			4. loading_manager.cache_time
			
			5. non cache
			
			*/
			
			this.loading_manager.add_to_cache(this.current_url, this.current_req_data, this.response, now() + final_cache_time);
			
			//alert(Dump(this.loading_manager.cache));
		}
  } 
  return this.response;
		
}

cl_dispatcher.prototype.get_response_text = function(){
  
	this.response_text = this.http_request.responseText;
  return this.response_text;
		
}


