/**
 * @attention for sliders and device property windows
 */
(function($) {
	var helper,
		tTitle,
		tBody,
		tID;
	
	$.fn.Tooltip = function(settings) {
		settings = $.extend($.extend({}, arguments.callee.defaults), settings || {});
		if( !helper ) {
			closeHTML = '';
			if(settings.closeText) closeHTML = '<a href="javascript:void(0);" onclick="$(this.parentNode).hide();" class="close" title="'+settings.closeText+'"></a>';
			helper = $('<div id="tooltip">'+closeHTML+'<h3></h3><div class="body"></div></div>')
				.hide()
				.css({ position: 'absolute', zIndex: 3000 })
				.appendTo('body');
				
			tTitle = $('h3', helper);
			tBody = $('div:eq(0)', helper);
		}
		
		$(this).filter('[@name]')
			.each(function() {
				this.tSettings = settings;
			})
			.bind(settings.event, save)
			.bind(settings.event, handle);
		return this;
	};
	
	function handle(event){
		
		if(this.tSettings.track){
			$('body').bind('click', update);
		}

		if(this.tSettings.extraClass){
			helper.addClass(this.tSettings.extraClass);
		}
			
		update(event);
		$('a.close', helper).bind('click', hide);
		if(!this.tSettings.dontHide) $(this).bind('mouseout', hide);
	}
	
	function save() {
		if(this.tSettings.delay){
			tID = setTimeout(show, this.tSettings.delay);
		} else {
			show();
		}

		var source = $(this),
			settings = this.tSettings;

		title = source.attr('name');
		if(settings.showBody){
			var parts = title.split(settings.showBody);
			tTitle.html(parts.shift());
			tBody.empty();

			for(var i = 0, part; part = parts[i]; i++) {
				if(i > 0)
					tBody.append("<br/>");
				tBody.append(part);
			}

			if(tBody.html()){
				tBody.show();
			} else {
				tBody.hide();
			}

		} else {
			tTitle.html(title);
			tBody.hide();
		}
	}
	
	function show() {
		tID = null;
		helper.show();
		update();
	}
	
	function update(event)	{
		var left = helper[0].offsetLeft;
		var top = helper[0].offsetTop;
		if(event){
			function pos(c) {
				var p = c == 'X' ? 'Left' : 'Top';
				return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;
			}

			left = pos('X') + 10;
			top = pos('Y') + 10;
			helper.css({
				left: left + 'px',
				top: top + 'px'
			});
		}
		
		var v = viewport(),
			h = helper[0];
		// check horizontal position
		if(v.x + v.cx < h.offsetLeft + h.offsetWidth) {
			left -= h.offsetWidth + 20;
			helper.css({left: left + 'px'});
		}
		// check vertical position
		if(v.y + v.cy < h.offsetTop + h.offsetHeight) {
			top -= h.offsetHeight + 20;
			helper.css({top: top + 'px'});
		}
	}
	
	function viewport() {
		var e = document.documentElement || {},
			b = document.body || {},
			w = window;

		return {
			x: w.pageXOffset || e.scrollLeft || b.scrollLeft || 0,
			y: w.pageYOffset || e.scrollTop || b.scrollTop || 0,
			cx: min( e.clientWidth, b.clientWidth, w.innerWidth ),
			cy: min( e.clientHeight, b.clientHeight, w.innerHeight )
		};

		function min() {
			var v = Infinity;
			for( var i = 0;  i < arguments.length;  i++ ) {
				var n = arguments[i];
				if( n && n < v ) v = n;
			}
			return v;
		}
	}
	
	function hide() {
		if(tID) clearTimeout(tID);
		helper.hide();

		if(this.tSettings && this.tSettings.extraClass ) {
			helper.removeClass(this.tSettings.extraClass);
		}
	}
	
	// default sets
	$.fn.Tooltip.defaults = {
		delay: 250,
		event: "mouseover",
		track: false,
		showBody: null,
		extraClass: null,
		dontHide: false,
		closeText: null
	};

})(jQuery);
