
// wait till DOM is ready
jQuery(function() {
	var $=jQuery;

	// init tooltip
	var $window			= $(window);
	var $body			= $('body');

	var tooltipReferences		= {};
	var counter			= 0;

	var defaultOptions		= {
		// tooltip dummy with selector for elm where to put in the message
		$dummy:			$("<div class='tooltip' />").wrapInner("<div wclass='clearfix' />"),
		dummyContentSelector:	':first',
//		$target:		$body, // elm's parent (is set dynamically)

		// settings for jQuery UI .position()
		tipPosition:		'center bottom',	// tip's position compared to it's parent, ie. 'center bottom'
		parentPosition:		'center top',		// tip's parent's position compared to tip, ie. 'center top'
		offset:			'0 0',			// ie. '0 10' (x/y offset)

		// settings for animation
		effect:			'fade',
		duration:		250,
		animations:		true,

		// rest
		windowResize:		!true
	};

	var effects			= {
		// do not use show() and hide(), $tip is detached by doneFunc() (using these functions can cause awkward repositioning)
		fade: function($tip , showHide , api , doneFunc) {
//			if (showHide=='show')	$tip.show().animate({opacity:1} , api.options.duration);
//			else			$tip.animate({opacity:0} , api.options.duration , function() {$tip.hide(); doneFunc(); });

			if (showHide=='show')	$tip.animate({opacity:1} , api.options.duration);
			else			$tip.animate({opacity:0} , api.options.duration , doneFunc);
		},
		shift: function($tip , showHide , api , doneFunc) {
			if (showHide=='show')	$tip.css('opacity' , .5).animate({top:'-=10' , opacity:1} , api.options.duration);
			else			$tip.animate({top:'+=10' , opacity:.5} , api.options.duration , doneFunc);
		}
	};

	// add tooltip to jQuery functions
//	$.fn.tooltip			= _mainFunc;
	$.fn.tooltip = function(action , message , options) {
		$(this).each(function(i,elm) {
			_mainFunc($(elm) , action , message , options);
		});
		return this;
	}

	/*******************************************/
	/*** SET OBJECT FOR GLOBAL COMMUNICATION ***/
	/*******************************************/

	window.tooltip = tooltip = {
		// getter/setter for defaultOptions
		defaultOptions: function(a1 , a2 , a3) {
			if (a1 && typeof(a1)=='object')	$.extend(defaultOptions , a1);
			return defaultOptions;
		}
	};

	/***********************/
	/*** LOCAL FUNCTIONS ***/
	/***********************/

	function _mainFunc($elm , action , message , options) { // ($elm , action [ , message , options])
		if (!options)	options={}; // $target, $dummy , dummyContentSelector

		var api		= $elm.data('tooltip');
		if (!api) {
			// options:	marge empty object with defaultOptions and options
			// state:	shown/hidden (or animating to be shown or hidden)
			options	= $.extend({} , defaultOptions , options);
			api	= {
				$tip:		options.$dummy.clone(true),
				options:	options,
				message:	message,
				state:		'hidden'
			};

			// place tooltip in $elm's parent if no $target defined (check parent's display property)
			if (!api.options.$target)				api.options.$target=$elm.parent();
			if ( api.options.$target.css('display')=='static')	alert('ERROR: tooltip $targets cannot have static display (tooltip.js)');
			if (options.windowResize) {
				$elm.addClass('repositionOnWindowResize');
				$window.bind('resize.tooltip' , _windowResizeFunc);
			}

			api.$tip.addClass('tooltip' + (++counter));
		}
		else {
			if (options) $.extend(api.options , options);
		}

		var $tip = api.$tip;

		if (action=='show') {
			// set and save message
			if (message) {
				api.message = message;
				$tip.find(api.options.dummyContentSelector).html(message);
			}

			// (re-)insert $tip in DOM (if no parent, elm is not in DOM)
			if ($tip.parent().length==0) $tip.appendTo(api.options.$target);

			// if tip is hidden or being animated to be hidden
			if (api.state=='hidden') {
				// stop all animations before (re-)positioning
				$tip.stop(true).show();

				// position $tip to $elm
				_position($elm , $tip , api.options);

				if (api.options.animations)	effects[api.options.effect]($tip , 'show' , api);
				else				$tip.show();
			}

			api.state = 'shown';
		}
		else {
			// if tip is shown or being animated to be shown
			if (api.state=='shown') {
				var callback	= function() {
					$tip.detach();

					var api	= $elm.data('tooltip');
					api.state='hidden';
					$elm.data('tooltip' , api);
				};

				if (api.options.animations)	effects[api.options.effect]($tip.stop(true) , 'hide' , api , callback);
				else				{$tip.hide(); callback(); }

				api.state='hidden';
			}
		}

		// save api
		$elm.data('tooltip' , api);

		return $elm;
	}

	function _windowResizeFunc() {
		var $elms = $('.repositionOnWindowResize');
		if ($elms.length>0) {
			$elms.stop(true,true).each(function(i,elm) {
				// reposition $tip to $elm
				// _position($elm , $tip , options);
			});
		}
		else $window.unbind("resize.tooltip");
	};

	function _position($elm , $tip , options) {
		$tip.position({
			of:	$elm,
			my:	options.tipPosition,
			at:	options.parentPosition,
			offset:	options.offset
			// using: using,
			// collision: $( "#collision_horizontal" ).val() + ' ' + $( "#collision_vertical" ).val()
		});
//document.title = $tip.css('top');
	}
});

