/**
 * The basic functionality for the Still Drift modules
 *
 * @copyright	bitExpert AG <info@bitExpert.de>
 * @version	$Revision$
 * @date	$Date$
 *
 * Depends:
 *	ui.core.js
 */
(function($){
	$.widget('ui.module', {
		config: {

		},

		_init: function()
		{
			var widget = this;

			var COOKIE_NAME = widget.element[0].id;
			var inHandle = false;

			var leftValue;
			var topValue;

			this.config = {};

			if(null === $.cookie('user_layout'))
			{
				$.cookie('user_layout', true);
			}

			var moduleHandle = $('.handle');

			$(document).bind('clickMe', function(event){

				if(widget === event.module)
				{
					inHandle = widget._clickedInHandle(event);
				}
			});

			$('.controls .close', widget.element).click(function(){
				widget._remove();
				return false;
			});

			$('.controls .stickIt', widget.element).click(function(){
				widget.toggleSticky();
				return false;
			});


			if(widget.element[0] === $('.sd_module:last').get(0))
			{
				widget._focusMe(widget.element[0]);
			}

			widget.element.draggable(
			{
				start: function(event, ui)
				{
					widget._focusMe(event.target);
				},

				drag: function(event, ui){
					// check the position of the mouse pointer, if the pointer hover the trashcan add hover effect
					var overTrashCan = ((event.pageX >= $('#trashIt').offset().left) && (event.pageX <= ($('#trashIt').offset().left + $('#trashIt').width())));
					overTrashCan = overTrashCan && (event.pageY >= $('#trashIt').offset().top && event.pageY <= ($('#trashIt').offset().top + $('#trashIt').height()));

					if(overTrashCan)
					{
						$('#trashIt').addClass('hover');
					}
					else
					{
						$('#trashIt.hover').removeClass('hover');
					}
				},

				stop: function(event, ui)
				{
					var widgetPos = widget._checkPosition(ui.absolutePosition);
					
					widget._checkToRemove(event);

					widget._savePositionToCookie(widgetPos);
				},

				handle: moduleHandle
			});


			if(widget.options.bProcessOptions)
			{
				widget._processOptions();
				widget.moveInPlace();
			}

			if(document.cookie)
			{
				this._fillConfig();
				widget._setPosition(COOKIE_NAME);
			}

			$(widget.element).mousedown(function(e)
			{
				var event = new jQuery.Event('clickMe');
				event.module = widget;
				event.pageX = e.pageX;
				event.pageY = e.pageY;
				$(document).trigger(event);

				if(inHandle)
				{
					widget._focusMe(this);
				}
				else
				{
					widget._checkToFocus(event);
				}
			});

			widget._saveToCookie();

			if(this.config['bPinned'])
			{
				$('#' + this.element[0].id).find('.controls .stickIt').addClass('highlight');
			}

		//	$('#'+this.element[0].id).animate({'opacity' : 1.0}, 1000);
		},

		_checkPosition: function(pos)
		{
			var screenDims = getAvailableViewPort();

			var currentModule = $('#' + this.element[0].id);
			var outerBounds = {bottom: currentModule.height() + pos.top, right: currentModule.width() + pos.left};

			if(outerBounds.bottom > screenDims.iHeight)
			{
				currentModule.css('top', screenDims.iHeight - currentModule.height() + 'px');
			}

			if(outerBounds.right > screenDims.iWidth)
			{
				currentModule.css('left', screenDims.iWidth - currentModule.width() + 'px');
			}
			
			window.scrollTo(0,0);

			return currentModule.offset();

		},


		_clickedInHandle: function(event)
		{
			var bReturn = false;

			try
			{
				var thisModule = $(event.module.element.get(0));
				var handle = $('.handle',thisModule);

				// iterate over all found handles in the current module
				handle.each(function(){
					var handlePos = $(this).offset();
					var cursorPos = {'top': event.pageY , 'left': event.pageX};

					var verticalWithin = (cursorPos.top - handlePos.top) < $(this).height();
					var horizontalWithin = (cursorPos.left - handlePos.left) < $(this).width();
					var verticalPositive = (cursorPos.top - handlePos.top) > 0;
					var horizontalPositive = (cursorPos.left - handlePos.left) > 0;

					// if one test returns true, bReturn will be set to true and keeps this state
					// no matter, what results will be returned by the following tests
					bReturn = bReturn || (verticalWithin && verticalPositive && horizontalWithin && horizontalPositive);
				});
			}
			catch(err)
			{
				bReturn = false;
			}
			return bReturn;
		},

		_checkToFocus: function(event)
		{
			var widget = this;

			$('.sd_module:not(.focussed)').each(function(obj){
				var modulePos = $(this).offset();
				var mousePos = { 'top': event.pageY, 'left': event.pageX };

				if(((mousePos.top - modulePos.top) < $(this).height())
					&& ((mousePos.left - modulePos.left) < $(this).width())
					&& ((mousePos.left - modulePos.left) > 0)
					&& ((mousePos.top - modulePos.top) > 0))
				{
					widget._focusMe(this);
				}
			});
		},

		_savePositionToCookie: function(position)
		{
			this.config.sTop = position.top + 'px';
			this.config.sLeft = position.left +'px';
			this._saveToCookie();
		},

		_setPosition: function(cookiename)
		{
			var screenDims = getAvailableViewPort();

			if(this.config.sFix)
			{
				try
				{
					var positions = this.config.sFix.split(';');

					for(var i = 0; i < positions.length; i++)
					{
						switch(positions[i])
						{
							default:
							break;

							case 'sTop':
								$('#' + this.element[0].id).css({'top': this.config[positions[i]]});
							break;

							case 'sRight':
								$('#' + this.element[0].id).css({'right': this.config[positions[i]]});
							break;

							case 'sBottom':
								$('#' + this.element[0].id).css({'bottom': this.config[positions[i]]});
							break;

							case 'sLeft':
								$('#' + this.element[0].id).css({'left': this.config[positions[i]]});
							break;
						}
					}
				}
				catch(err)
				{
					// do sth
				}
			}
			else
			{
				try
				{
					var position = this._readPosition(cookiename);
					var offsetTop = parseInt((parseInt(this.config.sTop) / parseInt(screenDims.iHeight)) * 100) + '%';
					var offsetLeft = parseInt((parseInt(this.config.sLeft) / parseInt(screenDims.iWidth)) * 100) + '%';
					$('#' + this.element[0].id).css({'top': offsetTop , 'left': offsetLeft });
				}
				catch(err)
				{
					// do sth
				}
			}
		},

		_readPosition: function(pModuleId)
		{
			var oModule = {};

			var cookieValues = $.cookie(this.element[0].id);
			cookieValues.match(/^{(.*)}$/);
			cookieValues = RegExp.$1;

			// convert the JSON string to an array
			var stringArray = cookieValues.split(',');
			for(var i = 0; i < stringArray.length; i++)
			{
				var aJSONValues = stringArray[i].split(':');
				oModule[aJSONValues[0].match(/"(.*)"/)[1]] = aJSONValues[1].match(/"(.*)"/)[1];
			}

			return oModule;

		},

		_processOptions: function()
		{
			for(var option in this.options)
			{
				this.config[option] = this.options[option];
			}

			if(this.config.sTitle)
			{
				$('.content', this.element).html('<h1>' + this.config.sTitle + '</h1>' + $('.content', this.element).html());
			}

			if(this.config.sLeft)
			{
				this.leftValue = this.config.sLeft;
			}

			if(this.config.sTop)
			{
				this.topValue = this.config.sTop;
			}
		},

		_focusMe: function(div){
			var isFocussed = $(div).hasClass('focussed');
			if(!isFocussed)
			{
				$('.sd_module').each(function(){
					$(this).removeClass('focussed');
				});

				$(div).addClass('focussed');
			}
		},


		moveInPlace: function()
		{
			try
			{
				sTop = this.topValue;
				sLeft = this.leftValue;
				if(sTop.substr(sTop.length-2, 2) != 'px')
				{
					var offsetTop = sTop + 'px';
				}
				else
				{
					var offsetTop = sTop;
				}

				if(sLeft.substr(sLeft.length-2, 2) != 'px')
				{
					var offsetLeft = sLeft + 'px';
				}
				else
				{
					var offsetLeft = sLeft;
				}

				$('#' + this.element[0].id).css({'top': offsetTop , 'left': offsetLeft });

				this.config.sTop = offsetTop;
				this.config.sLeft = offsetLeft;

				this._saveToCookie();
			}
			catch(err)
			{
				// do sth
			}
		},

		show: function()
		{


			$('#' + this.element[0].id).css({'visibility': 'visible'});

		},


		_remove: function()
		{
			var widget = this;
			if($('#' + this.element[0].id).get(0))
			{
				$.cookie(this.element[0].id, null);
				$('#' + this.element[0].id).fadeOut(function()
				{
					$(widget.element[0]).remove();
				});
			}
		},


		fadeAndDelete: function(callback)
		{
			$.cookie(this.element[0].id, null);
			$('#' + this.element[0].id).fadeOut();

		},


		moveTo: function(cookiename, sVertical, sHorizontal, sVOrientation, sHOrientation)
		{
			try
			{
				var screenDims = getAvailableViewPort();

				if(sVOrientation == 'top')
				{
					sTop = sVertical;
				}
				else
				{
					// px abschneiden um rechnen zu können
					sVertical = sVertical.substring(0, sVertical.length-2);
					sTop = screenDims.iHeight - parseInt(sVertical) - $('#' + this.element[0].id).height();
					sTop = sTop+"px";
				}

				if(sHOrientation == 'left')
				{
					sLeft = sHorizontal;
				}
				else
				{
					// px abschneiden um rechnen zu können
					sHorizontal = sHorizontal.substring(0, sHorizontal.length-2);
					sTop = screenDims.iWidth - parseInt(sHorizontal) - $('#' + this.element[0].id).width();
					sTop = sTop+"px";
				}


//				$('#' + this.element[0].id).css({'top': sTop , 'left': sLeft });
				$('#' + this.element[0].id).animate({'top': sTop , 'left': sLeft });


				this.config.sTop = sTop;
				this.config.sLeft = sLeft;

				this._saveToCookie();
			}
			catch(err)
			{
				// do sth
			}
		},

		moveToOptionPosition: function(cookiename)
		{
			try
			{
//				$('#' + this.element[0].id).css({'top': sTop , 'left': sLeft });
				$('#' + this.element[0].id).animate({'top': sTop , 'left': sLeft });
				//console.log('move .. '+this.element[0].id);


				this.config.sTop = sTop;
				this.config.sLeft = sLeft;

				this._saveToCookie();
			}
			catch(err)
			{
				// do sth
			}
		},

		updateOption: function(optionName, value)
		{
			try
			{
				this.config[optionName] = value;

				this._saveToCookie();
			}
			catch(err)
			{
				alert('err: '+err);
				// do sth
			}
		},

		toggleSticky: function()
		{
			var widget = this;

			if($('#' + this.element[0].id).get(0))
			{
				if(this.config['bPinned'])
				{
					widget.updateOption('bPinned', null);
					$('#' + this.element[0].id).find('.controls .stickIt').removeClass('highlight');
				}
				else
				{
					widget.updateOption('bPinned', true);
					$('#' + this.element[0].id).find('.controls .stickIt').addClass('highlight');
				}
			}
		},

//-------------------   parsing the instance name -----------------------
		_getCompTypeFromInstanceName: function(sCookieName)
		{
			aParts = sCookieName.split('_');
			return aParts[1];
		},

		_getInstanceNameFromCookieVar: function(sCookieVar)
		{
			return $.trim(sCookieVar.substring(0, sCookieVar.lastIndexOf('_')));
		},


		/*
		 * convert an array or object to a JSON String
		 *
		 *
		 */
		_toJSON: function(obj)
		{
			var sReturnString = '';

			var count = 0;

			for(var entry in obj)
			{
				var separator = (count > 0) ? ',' : '';
				if(null !== obj[entry])
				{
					sReturnString += separator + '"' + entry + '":' + '"' + obj[entry] + '"';
					count++;
				}
			}

			return '{' + sReturnString + '}';
		},


		/**
		 *
		 * write the JSON String to the cookie
		 *
		 *
		 */
		_saveToCookie: function()
		{
			var sStringToSave = this._toJSON(this.config);
			$.cookie(this.element[0].id, sStringToSave);
		},


		/**
		 *
		 * writes the values read from the cookie into the config object
		 *
		 */
		_fillConfig: function()
		{
			var cookieValues = $.cookie(this.element[0].id);
			if(cookieValues != null)
			{
				cookieValues.match(/^{(.*)}$/);
				cookieValues = RegExp.$1;

				// convert the JSON string to an array
				var stringArray = cookieValues.split(',');
				for(var i = 0; i < stringArray.length; i++)
				{
					var aJSONValues = stringArray[i].split(':');
					this.config[aJSONValues[0].match(/"(.*)"/)[1]] = aJSONValues[1].match(/"(.*)"/)[1];
				}
			}
		},

		_checkToRemove: function(event)
		{
			// check the position of the mouse pointer, when the module is released
			// delete the module, if the mouse pointer was positioned over the trash can
			var overTrashCan = ((event.pageX >= $('#trashIt').offset().left) && (event.pageX <= ($('#trashIt').offset().left + $('#trashIt').width())));
			overTrashCan = overTrashCan && (event.pageY >= $('#trashIt').offset().top && event.pageY <= ($('#trashIt').offset().top + $('#trashIt').height()));

			if(overTrashCan)
			{
				this._remove();
			}

			$('#trashIt.hover').removeClass('hover');
		}
	});
})(jQuery);