/* 
 /////////////////////////////////
 Version history:
 /////////////////////////////////
 1.0   	05.07.2007
 - inital Release
 1.1   	09.07.2007
 - some improvements and fixed for injectinto display
 1.2   	10.07.2007
 - message display center fix for injectinto display for ie
 1.3   	11.07.2007
 - inject into display fixed to ie disappearing after more than one dynamic display
 1.4	17.07.2007
 - added align center attribute to inject into div to fiv display in firefox
  1.5	11.10.2007
 - fixed display of inject into mode when no message should be displayed
 1.6	18.10.2007
 - fixed display bug in ie with loaderDiv.injectInside( bodyNode ) not working
 1.7	8.11.2007
 - fixed bug with inject into mode, loader node will be injected back into body node when the loader will be hidden 
 */
/* 
 /////////////////////////////////
 Doku:
 /////////////////////////////////
 - todo
 */
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CLASS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

var zxAjaxLoader = zxBaseClass.extend(
{
	///////////////////////////////////////////////////////////////////////////////////////////////
	// PUBLIC
	///////////////////////////////////////////////////////////////////////////////////////////////
	
	initialize: function(customDefaultOptions)
	{
		this.parent();
		
		this.setDefaultCustomOptions(customDefaultOptions);
		this.setDefaultOptions(new zxAjaxLoaderDefaultOptions());
	},
	
	
	registerForMethod: function(ajaxObj, ajaxMethodName, callBackObj, callBackMethodName, options)
	{
		if (!ajaxObj) 
			return;
		if (!ajaxMethodName) 
			return;
		
		// create loader div for this specific function and inject it into document
		var loaderNode = this._createLoaderNode(options);
		
		var bodyNode = $E('body');
		loaderNode.injectTop(bodyNode);
		
		// capture ajax data function
		this._wrapMethod(ajaxObj, ajaxMethodName, this._showLoader.bind(this).pass(options));
		
		// capture callback function if specified
		if (callBackObj && callBackMethodName) 
		{
			this._wrapMethod(callBackObj, callBackMethodName, this._hideLoader.bind(this).pass(options));
		}
	},
	
	getDefaultOptions: function(displayMode)
	{
		var options = new Object();
		
		switch (displayMode)
		{
			case zxAjaxLoaderDisplayMode.LikeCSS:
				options.displayMode = displayMode;
				options.sizeMode = zxAjaxLoaderSizeMode.LikeCSS;
				options.messagePositionMode = zxAjaxLoaderPositionMode.BottomCenter;
				
				break;
			case zxAjaxLoaderDisplayMode.Inside:
				options.displayMode = displayMode;
				options.sizeMode = zxAjaxLoaderSizeMode.SameAsParent;
				options.positionMode = zxAjaxLoaderPositionMode.MiddleCenter;
				options.messagePositionMode = zxAjaxLoaderPositionMode.BottomCenter;
				
				break;
			case zxAjaxLoaderDisplayMode.Outside:
				options.displayMode = displayMode;
				options.sizeMode = zxAjaxLoaderSizeMode.LikeCSS;
				options.positionMode = zxAjaxLoaderPositionMode.MiddleRight;
				options.messagePositionMode = zxAjaxLoaderPositionMode.MiddleRight;
				
				break;
			case zxAjaxLoaderDisplayMode.InjectInto:
				options.displayMode = displayMode;
				options.messagePositionMode = zxAjaxLoaderPositionMode.BottomCenter;
				
				break;
			case zxAjaxLoaderDisplayMode.FullWindow:
				options.displayMode = displayMode;
				options.positionMode = zxAjaxLoaderPositionMode.MiddleCenter;
				options.messagePositionMode = zxAjaxLoaderPositionMode.BottomCenter;
				
				break;
		}
		
		return options;
	},
	
	///////////////////////////////////////////////////////////////////////////////////////////////
	// PRIVATE
	///////////////////////////////////////////////////////////////////////////////////////////////
	
	_showLoader: function(options)
	{
		var loaderNode = this.getOption('loaderNode', options);
		loaderNode.setHTML(this.getOption('loaderNodeHTML', options));
		
		// apply current configuration settings to div node
		this._applyOptionsToLoaderDiv(options);
		
		// display loader div
		loaderNode.setStyle('display', 'block');
	},
	
	_hideLoader: function(options)
	{
		var loaderNode = this.getOption('loaderNode', options);
		
		// hide loader div		
		loaderNode.setStyle('display', 'none');
		
		var displayMode = this.getOption('displayMode', options);
		
		// inject loader node back into body node if display mode was inject into
		if (displayMode == zxAjaxLoaderDisplayMode.InjectInto) 
		{
			var bodyNode = $E('body');
			loaderNode.injectTop(bodyNode);
		}
	},
	
	_wrapMethod: function(obj, methodName, customFunction)
	{
		// does method exist?
		if (!(methodName in obj)) 
			return;
		
		// is method function?
		if (typeof(obj[methodName]) != 'function') 
			return;
		var origFunction = obj[methodName];
		
		var newFunction = function()
		{
			// custom stuff
			customFunction();
			
			origFunction.apply(this, arguments);
		}
		
		obj[methodName] = newFunction;
	},
	
	_createLoaderNode: function(options)
	{
		var outerNode = null;
		
		var displayMode = this.getOption('displayMode', options);
		
		// create outer node (=loader Div) according to the display mode
		switch (displayMode)
		{
			case zxAjaxLoaderDisplayMode.InjectInto:
				outerNode = this._createOuterNodeForInjectInto(options);
				outerNode.setStyle('position', 'static');
				outerNode.setAttribute('align', 'center');
				
				break;
			case zxAjaxLoaderDisplayMode.Inside:
				outerNode = this._createOuterNodeForDefault(options);
				outerNode.setStyle('position', 'absolute');
				
				break;
			case zxAjaxLoaderDisplayMode.Outside:
				outerNode = this._createOuterNodeForDefault(options);
				outerNode.setStyle('position', 'absolute');
				
				break;
			case zxAjaxLoaderDisplayMode.FullWindow:
				outerNode = this._createOuterNodeForDefault(options);
				outerNode.setStyle('position', 'absolute');
				outerNode.setStyle('border', 'none');
				
				break;
			default:
				outerNode = this._createOuterNodeForDefault(options);
				
				break;
		}
		
		// hide outer node
		outerNode.setStyle('display', 'none');
		outerNode.addClass(this.getOption('cssOuter', options));
		
		// remember link to div node in options
		options = this.setOption('loaderNode', outerNode, options);
		options = this.setOption('loaderNodeHTML', outerNode.innerHTML, options);
		
		return outerNode;
	},
	
	_createOuterNodeForInjectInto: function(options)
	{
		var outerNode = new Element('div');
		
		var tableHTML = '';
		tableHTML += '<table cellpadding="0" cellspacing="0" style="display:inline">';
		tableHTML += '<tr><td></td><td class="T_o_p"></td><td></td></tr>';
		tableHTML += '<tr><td class="L_e_f_t"></td><td class="C_e_n_t_e_r" align="center"></td><td class="R_i_g_h_t"></td></tr>';
		tableHTML += '<tr><td></td><td class="B_o_t_t_o_m"></td><td></td></tr>';
		tableHTML += '</table>';
		
		outerNode.setHTML(tableHTML);
		
		var cssIcon = this.getOption('cssIcon', options);
		
		var iconNode = new Element('div');
		iconNode.addClass(cssIcon);
		
		var centerTd = $E('.C_e_n_t_e_r', outerNode);
		iconNode.injectTop(centerTd);
		
		var message = this.getOption('message', options);
		if (message != null) 
		{
			var messagePositionMode = this.getOption('messagePositionMode', options);
			var cssMessage = this.getOption('cssMessage', options);
			
			switch (messagePositionMode)
			{
				case zxAjaxLoaderPositionMode.TopLeft:
					var topTd = $E('.T_o_p', outerNode);
					topTd.setStyle('text-align', 'left');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					break;
				case zxAjaxLoaderPositionMode.TopCenter:
					var topTd = $E('.T_o_p', outerNode);
					topTd.setStyle('text-align', 'center');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.TopRight:
					var topTd = $E('.T_o_p', outerNode);
					topTd.setStyle('text-align', 'right');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.MiddleLeft:
					var leftTd = $E('.L_e_f_t', outerNode);
					leftTd.setStyle('text-align', 'right');
					leftTd.addClass(cssMessage);
					leftTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.MiddleRight:
					var rightTd = $E('.R_i_g_h_t', outerNode);
					rightTd.setStyle('text-align', 'left');
					rightTd.addClass(cssMessage);
					rightTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.BottomLeft:
					var topTd = $E('.B_o_t_t_o_m', outerNode);
					topTd.setStyle('text-align', 'left');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.BottomCenter:
					var topTd = $E('.B_o_t_t_o_m', outerNode);
					topTd.setStyle('text-align', 'center');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					
					break;
				case zxAjaxLoaderPositionMode.BottomRight:
					var topTd = $E('.B_o_t_t_o_m', outerNode);
					topTd.setStyle('text-align', 'right');
					topTd.addClass(cssMessage);
					topTd.setHTML(message);
					
					break;
			}
		}
		
		return outerNode;
	},
	
	_createOuterNodeForDefault: function(options)
	{
		var outerNode = new Element('div');
		
		var iconNode = new Element('div');
		iconNode.setHTML('&#160;');
		iconNode.setStyle('position', 'absolute');
		iconNode.addClass(this.getOption('cssIcon', options));
		
		var messageNode = new Element('div');
		messageNode.setHTML('&#160;');
		messageNode.setStyle('position', 'absolute');
		messageNode.addClass(this.getOption('cssMessage', options));
		
		var message = this.getOption('message', options);
		if (message != null) 
		{
			messageNode.setHTML(message);
		}
		else 
		{
			// hide text node if no message is present
			messageNode.setStyle('display', 'none');
		}
		
		iconNode.injectInside(outerNode);
		messageNode.injectInside(outerNode);
		
		return outerNode;
	},
	
	_applyOptionsToLoaderDiv: function(options)
	{
		// get parentnode
		var parentNode = this.getOption('parentNode', options);
		
		// get loader div	
		var loaderNode = this.getOption('loaderNode', options);
		
		// get coords from loader div node (need to display block to get coords first)
		loaderNode.setStyle('visibility', 'hidden');
		loaderNode.setStyle('display', 'block');
		var loaderNodeCoords = loaderNode.getCoordinates();
		loaderNode.setStyle('display', 'none');
		loaderNode.setStyle('visibility', 'visible');
		
		// get important options
		var displayMode = this.getOption('displayMode', options);
		var sizeMode = this.getOption('sizeMode', options);
		var positionMode = this.getOption('positionMode', options);
		
		var top = 0;
		var left = 0;
		var width = 0;
		var height = 0;
		
		switch (displayMode)
		{
			case zxAjaxLoaderDisplayMode.Inside:
				// parent node must be defined in this case
				if (!parentNode) 
					return;
				
				// add mootools functionality
				parentNode = $(parentNode);
				
				// get coords from parent element
				var parentNodeCoords = parentNode.getCoordinates();
				
				switch (sizeMode)
				{
					case zxAjaxLoaderSizeMode.SameAsParent:
						// set the size the same as the perant
						loaderNode.setStyle('top', parentNodeCoords.top);
						loaderNode.setStyle('left', parentNodeCoords.left);
						loaderNode.setStyle('width', parentNodeCoords.width);
						loaderNode.setStyle('height', parentNodeCoords.height);
						
						break;
					case zxAjaxLoaderSizeMode.LikeCSS:
						// set top left position of loader
						switch (positionMode)
						{
							case zxAjaxLoaderPositionMode.TopLeft:
							case zxAjaxLoaderPositionMode.MiddleLeft:
							case zxAjaxLoaderPositionMode.BottomLeft:
								left = parentNodeCoords.left;
								break;
							case zxAjaxLoaderPositionMode.TopCenter:
							case zxAjaxLoaderPositionMode.MiddleCenter:
							case zxAjaxLoaderPositionMode.BottomCenter:
								left = parentNodeCoords.left + parentNodeCoords.width / 2 - loaderNodeCoords.width / 2;
								break;
							case zxAjaxLoaderPositionMode.TopRight:
							case zxAjaxLoaderPositionMode.MiddleRight:
							case zxAjaxLoaderPositionMode.BottomRight:
								left = parentNodeCoords.left + parentNodeCoords.width - loaderNodeCoords.width;
								break;
						}
						
						switch (positionMode)
						{
							case zxAjaxLoaderPositionMode.TopLeft:
							case zxAjaxLoaderPositionMode.TopCenter:
							case zxAjaxLoaderPositionMode.TopRight:
								top = parentNodeCoords.top;
								break;
							case zxAjaxLoaderPositionMode.MiddleLeft:
							case zxAjaxLoaderPositionMode.MiddleCenter:
							case zxAjaxLoaderPositionMode.MiddleRight:
								top = parentNodeCoords.top + parentNodeCoords.height / 2 - loaderNodeCoords.height / 2;
								break;
							case zxAjaxLoaderPositionMode.BottomLeft:
							case zxAjaxLoaderPositionMode.BottomCenter:
							case zxAjaxLoaderPositionMode.BottomRight:
								top = parentNodeCoords.top + parentNodeCoords.height - loaderNodeCoords.height;
								break;
						}
						
						loaderNode.setStyle('top', top);
						loaderNode.setStyle('left', left);
						
						break;
				}
				
				break;
			case zxAjaxLoaderDisplayMode.Outside:
				// parent node must be defined in this case
				if (!parentNode) 
					return;
				
				// add mootools functionality
				parentNode = $(parentNode);
				
				// get coords from parent element
				var parentNodeCoords = parentNode.getCoordinates();
				
				if (sizeMode == zxAjaxLoaderSizeMode.SameAsParent) 
				{
					// set the size the same as the perant
					loaderNode.setStyle('width', parentNodeCoords.width);
					loaderNode.setStyle('height', parentNodeCoords.height);
					
					loaderNode.setStyle('visibility', 'hidden');
					loaderNode.setStyle('display', 'block');
					loaderNodeCoords = loaderNode.getCoordinates();
					loaderNode.setStyle('display', 'none');
					loaderNode.setStyle('visibility', 'visible');
				}
				
				// set top left position of loader
				switch (positionMode)
				{
					case zxAjaxLoaderPositionMode.TopLeft:
					case zxAjaxLoaderPositionMode.MiddleLeft:
					case zxAjaxLoaderPositionMode.BottomLeft:
						left = parentNodeCoords.left - loaderNodeCoords.width;
						break;
					case zxAjaxLoaderPositionMode.TopCenter:
					case zxAjaxLoaderPositionMode.MiddleCenter:
					case zxAjaxLoaderPositionMode.BottomCenter:
						left = parentNodeCoords.left + parentNodeCoords.width / 2 - loaderNodeCoords.width / 2;
						break;
					case zxAjaxLoaderPositionMode.TopRight:
					case zxAjaxLoaderPositionMode.MiddleRight:
					case zxAjaxLoaderPositionMode.BottomRight:
						left = parentNodeCoords.left + parentNodeCoords.width;
						break;
				}
				
				switch (positionMode)
				{
					case zxAjaxLoaderPositionMode.TopLeft:
					case zxAjaxLoaderPositionMode.TopCenter:
					case zxAjaxLoaderPositionMode.TopRight:
						top = parentNodeCoords.top;
						break;
					case zxAjaxLoaderPositionMode.MiddleLeft:
					case zxAjaxLoaderPositionMode.MiddleCenter:
					case zxAjaxLoaderPositionMode.MiddleRight:
						top = parentNodeCoords.top + parentNodeCoords.height / 2 - loaderNodeCoords.height / 2;
						break;
					case zxAjaxLoaderPositionMode.BottomLeft:
					case zxAjaxLoaderPositionMode.BottomCenter:
					case zxAjaxLoaderPositionMode.BottomRight:
						top = parentNodeCoords.top + parentNodeCoords.height - loaderNodeCoords.height;
						break;
				}
				
				loaderNode.setStyle('top', top);
				loaderNode.setStyle('left', left);
				
				break;
			case zxAjaxLoaderDisplayMode.FullWindow:
				var sizes = this.getPageSizeInfos();
				
				// set loader size to full page
				loaderNode.setStyle('top', 0);
				loaderNode.setStyle('left', 0);
				loaderNode.setStyle('width', sizes.pageWidth);
				loaderNode.setStyle('height', sizes.pageHeight);
				
				break;
			case zxAjaxLoaderDisplayMode.InjectInto:
				// parent node must be defined in this case
				if (!parentNode) 
					return;
				
				// add mootools functionality
				parentNode = $(parentNode);
				
				// empty parent element first
				parentNode.empty();
				
				// inject loader into parent node without any positioning
				loaderNode.injectTop(parentNode);
				
				break;
			case zxAjaxLoaderDisplayMode.LikeCSS:
				switch (sizeMode)
				{
					case zxAjaxLoaderSizeMode.SameAsParent:
						// if parent node is defined, make same size as him
						if (parentNode) 
						{
							// add mootools functionality
							parentNode = $(parentNode);
							
							// get coords from parent element
							var parentNodeCoords = parentNode.getCoordinates();
							
							// set the size the same as the perant
							loaderNode.setStyle('width', parentNodeCoords.width);
							loaderNode.setStyle('height', parentNodeCoords.height);
						}
						
						break;
				}
				
				break;
		}
		
		var loaderIconNode = $E('.' + this.getOption('cssIcon', options), loaderNode);
		var loaderTextNode = $E('.' + this.getOption('cssMessage', options), loaderNode);
		
		// set positions of icon and message node if the loader should not be injected into a page
		if (displayMode != zxAjaxLoaderDisplayMode.InjectInto) 
		{
			loaderNode.setStyle('visibility', 'hidden');
			loaderNode.setStyle('display', 'block');
			var loaderNodeCoords = loaderNode.getCoordinates();
			var loaderIconNodeCoords = loaderIconNode.getCoordinates();
			var loaderTextNodeCoords = loaderTextNode.getCoordinates();
			loaderNode.setStyle('display', 'none');
			loaderNode.setStyle('visibility', 'visible');
			
			// correct values for full window display to display loading message in the middle even if page is bigger than window (scrolling possible)
			if (displayMode == zxAjaxLoaderDisplayMode.FullWindow) 
			{
				var sizes = this.getPageSizeInfos();
				
				loaderNodeCoords.width = sizes.windowWidth;
				loaderNodeCoords.height = sizes.windowHeight;
			}
			
			var messagePositionMode = this.getOption('messagePositionMode', options);
			
			var iconTop = 0;
			var iconLeft = 0;
			var textTop = 0;
			var textLeft = 0;
			
			switch (messagePositionMode)
			{
				case zxAjaxLoaderPositionMode.TopLeft:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderTextNodeCoords.height;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					break;
				case zxAjaxLoaderPositionMode.MiddleLeft:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width / 2 + loaderTextNodeCoords.width;
					textTop = loaderNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width / 2;
					break;
				case zxAjaxLoaderPositionMode.BottomLeft:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderIconNodeCoords.height;
					textLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					break;
					
				case zxAjaxLoaderPositionMode.TopCenter:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderTextNodeCoords.height;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 - loaderTextNodeCoords.width / 2;
					break;
				case zxAjaxLoaderPositionMode.MiddleCenter:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 - loaderTextNodeCoords.width / 2;
					break;
				case zxAjaxLoaderPositionMode.BottomCenter:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderIconNodeCoords.height;
					textLeft = loaderNodeCoords.width / 2 - loaderTextNodeCoords.width / 2;
					break;
				case zxAjaxLoaderPositionMode.TopRight:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderTextNodeCoords.height;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 + loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width;
					break;
				case zxAjaxLoaderPositionMode.MiddleRight:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					textLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width / 2 + loaderIconNodeCoords.width;
					break;
				case zxAjaxLoaderPositionMode.BottomRight:
					iconTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2;
					iconLeft = loaderNodeCoords.width / 2 - loaderIconNodeCoords.width / 2;
					textTop = loaderNodeCoords.height / 2 - loaderIconNodeCoords.height / 2 - loaderTextNodeCoords.height / 2 + loaderIconNodeCoords.height;
					textLeft = loaderNodeCoords.width / 2 + loaderIconNodeCoords.width / 2 - loaderTextNodeCoords.width;
					break;
			}
			
			if (displayMode == zxAjaxLoaderDisplayMode.Outside) 
			{
				switch (positionMode)
				{
					case zxAjaxLoaderPositionMode.TopLeft:
					case zxAjaxLoaderPositionMode.MiddleLeft:
					case zxAjaxLoaderPositionMode.BottomLeft:
						switch (messagePositionMode)
						{
							case zxAjaxLoaderPositionMode.TopLeft:
							case zxAjaxLoaderPositionMode.BottomLeft:
								iconLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								textLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								break;
							case zxAjaxLoaderPositionMode.MiddleLeft:
								iconLeft = loaderNodeCoords.width - loaderIconNodeCoords.width;
								textLeft = loaderNodeCoords.width - loaderIconNodeCoords.width - loaderTextNodeCoords.width;
								
								break;
							case zxAjaxLoaderPositionMode.TopRight:
							case zxAjaxLoaderPositionMode.BottomRight:
								iconLeft = loaderNodeCoords.width - loaderIconNodeCoords.width;
								textLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								
								break;
							case zxAjaxLoaderPositionMode.MiddleRight:
								iconLeft = loaderNodeCoords.width - loaderTextNodeCoords.width - loaderIconNodeCoords.width;
								textLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								
								break;
							case zxAjaxLoaderPositionMode.TopCenter:
							case zxAjaxLoaderPositionMode.MiddleCenter:
							case zxAjaxLoaderPositionMode.BottomCenter:
								textLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								iconLeft = textLeft + loaderTextNodeCoords.width / 2;
								
								break;
						}
						
						break;
						
					case zxAjaxLoaderPositionMode.TopRight:
					case zxAjaxLoaderPositionMode.MiddleRight:
					case zxAjaxLoaderPositionMode.BottomRight:
						switch (messagePositionMode)
						{
							case zxAjaxLoaderPositionMode.TopLeft:
							case zxAjaxLoaderPositionMode.MiddleLeft:
							case zxAjaxLoaderPositionMode.BottomLeft:
								iconLeft = loaderTextNodeCoords.width;
								textLeft = 0;
								
								break;
							case zxAjaxLoaderPositionMode.TopRight:
							case zxAjaxLoaderPositionMode.MiddleRight:
							case zxAjaxLoaderPositionMode.BottomRight:
								iconLeft = 0;
								textLeft = loaderIconNodeCoords.width;
								
								break;
							case zxAjaxLoaderPositionMode.TopCenter:
							case zxAjaxLoaderPositionMode.MiddleCenter:
							case zxAjaxLoaderPositionMode.BottomCenter:
								textLeft = loaderNodeCoords.width - loaderTextNodeCoords.width;
								iconLeft = textLeft + loaderTextNodeCoords.width / 2;
								
								break;
						}
						
						break;
				}
			}
			
			loaderIconNode.setStyle('top', iconTop);
			loaderIconNode.setStyle('left', iconLeft);
			
			loaderTextNode.setStyle('top', textTop);
			loaderTextNode.setStyle('left', textLeft);
		}
	}
});


var zxAjaxLoaderDefaultOptions = new Class(
{
	///////////////////////////////////////////////////////////////////////////////////////////////
	// PUBLIC
	///////////////////////////////////////////////////////////////////////////////////////////////
	
	initialize: function()
	{
		this.cssOuter = 'ajaxLoaderOuter';
		this.cssIcon = 'ajaxLoaderIcon';
		this.cssMessage = 'ajaxLoaderMessage';
		
		this.displayMode = zxAjaxLoaderDisplayMode.Inside;
		this.positionMode = zxAjaxLoaderPositionMode.MiddleCenter;
		this.sizeMode = zxAjaxLoaderSizeMode.SameAsParent;
		
		this.message = null;
		this.messagePositionMode = zxAjaxLoaderPositionMode.BottomCenter;
		
		this.parentNode = null;
	}
});


var zxAjaxLoaderDisplayMode = 
{
	LikeCSS: 0,
	Inside: 1,
	Outside: 2,
	InjectInto: 3,
	FullWindow: 4
};

var zxAjaxLoaderPositionMode = 
{
	TopLeft: 0,
	TopCenter: 1,
	TopRight: 2,
	MiddleLeft: 3,
	MiddleCenter: 4,
	MiddleRight: 5,
	BottomLeft: 6,
	BottomCenter: 7,
	BottomRight: 8
};

var zxAjaxLoaderSizeMode = 
{
	LikeCSS: 0,
	SameAsParent: 1
};

