var AjaxConnectionManagerKeepAlive = Class.create();

AjaxConnectionManagerKeepAlive.prototype = {
	initialize: function(ajax_connection_manager)
	{
		this.ajax_connection_manager = ajax_connection_manager;
		
		this.frequency = 300000;
		this.status = "";
		
		this.waiting = {
			trigger: false
		};
	},
	activate: function()
	{
		if ( this.status == "" )
		{
			// Starting...
			this.status = "active";
			this.notifyReset();
		}
	},
	
	notifyReset: function()
	{
		if ( this.status == "active" )
		{
			if (this.waiting.trigger != false)
			{
				clearTimeout(this.waiting.trigger);
			}
			this.waiting.trigger = false;
			this.waiting.trigger = setTimeout(this.check.bindAsEventListener(this), this.frequency);
		}
		
	},
	
	check: function()
	{
		var ajax = new AjaxController();
		
		var data  = "data[protocol]="+escape('beep');

		var callback = {
			success: function(o)
			{				
				var ajax_result = YAHOO.lang.JSON.parse(o.responseText);
				if ( ajax_result.ok )
				{
					//console.debug(ajax_result.ok);
				}
				else
				{
					//console.debug('error');
				}
				
			}.bind(this)
		};
		
		ajax.request('POST', '/jx/keep_alive', callback, data);
	}
};

var AjaxConnectionManager = Class.create();

AjaxConnectionManager.prototype = {
	initialize: function()
	{
		this.current_requesting = null;
		this.request_queue = [];
		
		this.ajax_connectors = [];
		
		this.keep_alive = new AjaxConnectionManagerKeepAlive(this);
		this.keep_alive.activate();
	},
	register: function(ajax_connector)
	{
		// Ensure no duplicate
		if ( !this.isRegistered(ajax_connector) )
		{
			this.ajax_connectors.push(ajax_connector);
		}
	},
	
	isRegistered: function(ajax_connector)
	{
		var found = false;
		this.ajax_connectors.each( function(existing_ajax_connector, existing_ajax_connector_index)
		{
			if (existing_ajax_connector == ajax_connector) 
			{
				found = true;
				return;
			}
					
		}.bind(this));
		
		return found;
	},
	
	notifyRequestCompleted: function(ajax_connector)
	{
		if ( this.isRegistered(ajax_connector) ) 
		{
			// find the request_queue from queue
			var found_request = null;
			this.request_queue.each( function(request, request_index)
			{
				if ( request.ajax_connector == ajax_connector )
				{
					found_request = request;
				}
				
			}.bind(this));
			
			// If found, remove it
			if ( found_request )
			{
				this.request_queue = this.request_queue.without(found_request);
				this.current_requesting = null;
			}
			
			this.checkQueue();
		}
	},
	
	pushRequestIntoQueue: function(request)
	{
		if ( this.isRegistered(request.ajax_connector) )
		{
			this.request_queue.push(request);
		}
	},
	
	checkQueue: function()
	{
		if ( this.request_queue.length > 0 )
		{
			if ( this.current_requesting == null ) 
			{
				var first_request = this.request_queue.first();
				this.current_requesting = first_request;
				
				// Execute the request
				this.keep_alive.notifyReset();
				first_request.execute_request();
			}
			else
			{
				// Some ajax is running, wait for the ajax complete.
			}
		}
	}
};
var ajax_connection_manager = new AjaxConnectionManager(); // Singelton


var AjaxController = Class.create();

AjaxController.prototype = {
	initialize: function(display_canvas_el, loading_canvas_el)
	{
		this.use_loading_canvas = false;
		this.is_loading = false;
		
		// AjaxConnectionManager
		this.ajax_connection_manager = ajax_connection_manager;
		this.ajax_connection_manager.register(this);
		
		this.loading_canvas_el = loading_canvas_el;
		this.display_canvas_el = display_canvas_el;
		
		if ( this.display_canvas_el != null && !Object.isUndefined(this.display_canvas_el) && this.loading_canvas_el != null || !Object.isUndefined(this.loading_canvas_el) )
		{
			this.use_loading_canvas = true;
			this.loading_canvas_el.hide();
		}
		
	},
	
	alertCanvas: function()
	{	
		if ( this.use_loading_canvas )
		{
			//Element.clonePosition(this.loading_canvas_el, this.display_canvas_el);
			// Clone position
			
			var display_canvas_el_position = this.display_canvas_el.positionedOffset();
			var display_canvas_el_dimension = this.display_canvas_el.getDimensions();
			this.loading_canvas_el.setStyle({
				top: display_canvas_el_position[1]+'px',
				left: display_canvas_el_position[0]+'px',
				width: display_canvas_el_dimension.width+'px',
				height: display_canvas_el_dimension.height+'px'
			});
			
			var table_el = fetchSingleElement(this.loading_canvas_el, ".table");
			var loading_canvas_dimension = this.loading_canvas_el.getDimensions();
			
			if ( !Object.isUndefined(table_el) )
			{	
				table_el.setStyle({
					width: loading_canvas_dimension.width+"px",
					height: loading_canvas_dimension.height+"px"
				});
			}
		}
	},
	
	request: function(method, url, callback, data)
	{
		if ( !this.is_loading ) 
		{
			this.ajax_connection_manager.pushRequestIntoQueue({
				ajax_connector:this,
				execute_request: function(){ this.__executeRequest(method, url, callback, data)}.bindAsEventListener(this)
			});
			
			this.ajax_connection_manager.checkQueue();
		}
	},
	
	__executeRequest: function(method, url, callback, data)
	{
		var default_callback = {
			cache: false
		};
		default_callback.success = function(o)
		{
			default_callback.response(o, '_success');
			
		}.bind(this);
		default_callback.failed = function(o)
		{
			default_callback.response(o, '_failed');
			
		}.bind(this);
		default_callback.response = function(o, type)
		{
			if ( !Object.isUndefined(default_callback[type]) && Object.isFunction(default_callback[type]) )
			{
				// Call function
				var func = default_callback[type];
				func(o);
				
				setTimeout(function()
				{
					if ( this.use_loading_canvas)
					{
						this.alertCanvas();
						this.loading_canvas_el.hide();
					}
					this.is_loading = false;
				
				}.bindAsEventListener(this), 200);
				
				// Notify the AjaxConnectionManager
				this.ajax_connection_manager.notifyRequestCompleted(this);
			}
			
		}.bind(this);
		
		// Override
		if ( !Object.isUndefined(callback.success) )
		{
			default_callback._success = callback.success;
		}
		if ( !Object.isUndefined(callback.failed) )
		{
			default_callback._failed = callback.failed;
		}
		
		if ( this.use_loading_canvas )
		{
			this.alertCanvas();
			this.loading_canvas_el.show();
		}
		
		this.is_loading = true;
		YAHOO.util.Connect.asyncRequest(method, url, default_callback, data);
	}
	
};
