(function($) {
	//If the UI scope is not availalable, add it
	$.ui = $.ui || {};
	$.fn.urlretry = null; // this is for setInterval
	
	$.fn.loader = function(options) {
		var defaults = {
					text: 'loading....',
					align: 'center',
					valign:'center',
					errormsg: 'Failed to load url.<br />Please check that the url is valid and your have not lost connection.',
					retries:3,
					timeout:5000
				};

		options = $.extend({},defaults, options);

		return $.extend(this.each(function() {
								$.extend($.fn.loader.control,new $.ui.loader(this,options));
							}),$.fn.loader.control);

	}

	$.fn.loader.control = {
			load: function(url,params,callback,onError)
			{					
					this.options.url = url || false;
					this.options.params = params || {};
					this.options.callback = callback || null;
					this.options.onError = onError || null;	
					var el = this;
					var callback = this.options.callback;
					var onError = this.options.onError;
					var retryAttempt = this.options.retries;
					this.init();		
					options = this.options;			
					
					if(this.options.url !=false){
						var ajaxError = function(request)
										{
												ajaxOptions = this;
												clearInterval($.fn.urlretry);								
												if(retryAttempt > 0)
												{
													$.fn.urlretry = setTimeout('$.ajax(ajaxOptions);',options.timeout);					
												}
												
												retryAttempt--;					
												
												if(typeof(onError) == 'function'){
													onError({
														message : options.errormsg,
														retries :options.retries,
														retryAttempt   : (options.retries - retryAttempt),
														url		: this.url,
														statusText: request.statusText,
														status : request.status,
														timeout: options.timeout
													});	
												}							
										};							
						
						var ajaxSuccess =  function(response)
											{		
													el.html(response);							
													if(typeof(callback) == 'function')
													{
														callback();
													}
													if($.fn.urlretry != null)
													{
														clearTimeout($.fn.urlretry);
														$.fn.urlretry = null;									
													}								
											};
							
						
						$.ajax({ 
											global: false, 
											type: "POST", 
											url: this.options.url, 
											data: this.options.params, 
											success: ajaxSuccess,
											error: ajaxError
										});
					}
					
			}
	}
	
	
	$.ui.loader = function(el,objOptions)
	{
					if(!objOptions) var objOptions = {};
					this.element = el;
					this.options = {};
					$.extend(this.options, objOptions);
	}


	$.extend($.ui.loader.prototype, {
		init: function()
		{
				var loadertpl = '<div class="loader" id="loader" name="loader"><span class="loader-icon"></span>'+this.options.text+'</div>';
				$(this.element).html(loadertpl);
				this.loaderEl = $('#loader',this.element);
				this.position();
		},
		position: function()
		{
			var elW =0,elH = 0;
			var el = this.element;

			while(elH == 0 || elW == 0)
			{
				if(elH ==0 ) elH = el.offsetHeight;
				if(elW ==0 ) elW = el.offsetWidth;
				el = el.offsetParent;
			}

			switch(this.options.align.toLowerCase())
			{
				case 'left'	 : this.loaderEl.css('margin-left','0px');
					break;
				case 'center': this.loaderEl.css('margin-left',Math.ceil(elW/2 - this.loaderEl.width()/2)+'px');
					break;
				case 'right' :this.loaderEl.css('margin-left',(elW - this.loaderEl.width())+'px' );
					break;
			}

			switch(this.options.valign.toLowerCase())
			{
				case 'top'	 : this.loaderEl.css('margin-top','0px');
					break;
				case 'center': this.loaderEl.css('margin-top',Math.ceil(elH/2 - this.loaderEl.height()/2)+'px');
					break;
				case 'bottom' :this.loaderEl.css('margin-top',(elH - this.loaderEl.height())+'px' );
					break;
			}
		}
	});

})(jQuery);
