var Bubbles = Class.create  (
{
	ajaxCache: [],	
	showEvent: 'click',
	showCallback: null,
	hideCallback: null,
	appearDuration: 0.2,
	fadeDuration: 0,
	align: 'left', //bubble
	valign: 'top', //bubble
	referencePointAlign:'left', //invoker
	referencePointVAlign:'top',//invoker
	bubbleSuffix:'_Bubble',
	useCSSPosition: false, //ak true offsetX a offsetY sa preber z CSS bubliny top a left, inac sa bude ratat podla referencePoint a alignov  z options
	offsetX: 0,
	offsetY: 0,
	ajaxUse: false,
	ajaxBubbleId: '',
	ajaxInvokerIdPrefix: '',
	
	invokerId:null,
	currentInvoker:null,
	invokerClassName:'',
	invokerOutDelayOn: true,
	invokerOutTimerId:null,
	outDelayTime: 2,
	
	
	//nastavia sa eventy pre zobrazenie a schovanie bublinky pre vsetky prvky danej triedy
	create: function(className)	{
		
		this.invokerClassName = className;
		
		if(this.showEvent == 'click')
		{
			$$('html').first().observe('click', this.invokerOutClick.bind(this, className));
		}
		
		//priradenie event handlerov pre vsetky invokeri a bublinky
		$$('.' + className).each(
			function(invoker)
			{
				
				if (this.useCSSPosition)
				{
					var bubble = $(invoker.identify() + this.bubbleSuffix);					
					
					//zapnutie kvoli zisteniu css hodnot
					bubble.style.visibility = "hidden";					
					bubble.show();					
					this.offsetX = bubble.offsetLeft;
					this.offsetY = bubble.offsetTop;
					bubble.style.visibility = "visible";
					bubble.hide();					
				}
				
				//priradenie eventov				
				invoker.observe(this.showEvent, this.invokerOver.bind(this, invoker));				
				if(this.showEvent != 'click')
				{
					invoker.observe('mouseout', this.invokerOut.bind(this, invoker ));
				}
				
			}.bind(this)
		)
	},
	
	invokerOutClick: function(className, event)
	{
		window.clearTimeout(this.invokerOutTimerId);
		this.invokerOutTimerId = null;
			
		if(this.invokerId)
		{
			if (!event) var event = window.event;
			var tg = (window.event) ? event.srcElement : event.target;
			while (tg.nodeName != 'BODY')
			{	
				if ($(tg).identify() == this.invokerId) return; 
				var bubble = $(this.invokerId + this.bubbleSuffix);	
				if (tg == bubble) return; 
				
				tg = tg.parentNode;
			}
			
			var bubble = $(this.invokerId + this.bubbleSuffix);	
			this.hideBubble(bubble);		
			$(this.invokerId).removeClassName('over');
			this.invokerId = null;
		}
		
	},
	
	
	invokerOut: function(invoker, event)
	{
		var bubble = $(invoker.identify() + this.bubbleSuffix);	
		
		//quirksmode.org - zistenie kci naozaj kurzor opustil aktivnu plochu invokera
		if (!event) var event = window.event;
		
		var tg = (window.event) ? event.srcElement : event.target;
		var reltg = $((event.relatedTarget) ? event.relatedTarget : event.toElement);		
		
		while ((reltg != tg) && reltg.nodeName != 'BODY')
		{	
			//prechod do bublinky 
			if (reltg == bubble) return; 
			reltg = reltg.parentNode;
		}
		// prechod v ramci invokera
		if (reltg == tg  ) return;		

		
		//zapnutie invoker out delay
		this.invokerOutDelayOn = true;
		this.currentInvoker = invoker;
		
		$(invoker).removeClassName('over');
		
//		console.log('ivokerOut: ' + this.currentInvoker.identify());
		this.invokerOutTimerId = this.invokerOutDelay.bind(this).delay(this.outDelayTime,this.currentInvoker);
	},
	
	invokerOutDelay:function(invoker)
	{
//		console.log('ivokerOutDelay: ' + invoker.identify());
		
		window.clearTimeout(this.invokerOutTimerId);		
		var bubble = $(invoker.identify() + this.bubbleSuffix);			
		this.hideBubble(bubble);		
		$(invoker).removeClassName('over');
		this.invokerId = null;
	},
	
	invokerOver: function(invoker, event)
	{
//		console.log('invokerOver: ' + invoker.identify());
				
		//rovnaky invoker, event bubbling 
		if(this.invokerId == invoker.identify())
		{
			//zrusenie oneskorenia, vratil som sa spat	
			window.clearTimeout(this.invokerOutTimerId);
			return;
		}
		else
		{
			var bubble = $(this.invokerId + this.bubbleSuffix);	
		
			if (!event) var event = window.event;
			
			var reltg = invoker;		
			var found = false;
			while (reltg.nodeName != 'BODY')
			{	
				if (reltg == bubble) 
				{
					found = true; 
					break;
				}
				reltg = reltg.parentNode;
			}
			
			if(!found)
			{
				//okamzite schovanie aktivnej bublinky a invokera
				if (this.currentInvoker && this.currentInvoker != invoker)	this.invokerOutDelay(this.currentInvoker);			
				if (this.invokerId && this.invokerId != invoker.identify())	this.invokerOutDelay($(this.invokerId));			
			}
		}
		
		//console.log('invokerOver ' + invoker.identify());
		
		//priradenie bublinky podla invokera
		var bubble = $(invoker.identify() + this.bubbleSuffix);				
		$(invoker).addClassName('over');
		
		if(bubble)
		{
		
			//ulozi sa novy invoker pre ktoreho sa zobrazuje bublinka
			this.invokerId = invoker.identify();			

			//NASTAVENIE POZICIE BUBLINKY
			//vertikalna pozicia
			var referencePointOffsetY;
			var referencePointOffsetX;
			
			if (this.useCSSPosition)
			{
				bubble.style.left = this.offsetX + "px";
				bubble.style.top = this.offsetY + "px";
			
			}
			else
			{
			
				switch(this.referencePointVAlign)
				{
					case 'top':referencePointOffsetY = invoker.offsetTop;
								break;
					case 'bottom':referencePointOffsetY = invoker.offsetTop + invoker.getHeight();
								break;
					case 'middle': referencePointOffsetY = invoker.offsetTop + Math.round(invoker.getHeight() / 2);
									break;
					default:referencePointOffsetY = invoker.offsetTop;
								break;
				}
				
				switch(this.referencePointAlign)
				{
					case 'left':referencePointOffsetX = invoker.offsetLeft;
								break;
					case 'right':referencePointOffsetX = invoker.offsetLeft + invoker.getWidth();
								break;
					case 'middle':referencePointOffsetX = invoker.offsetLeft + Math.round(invoker.getWidth() / 2);
								break;
					default:referencePointOffsetX = invoker.offsetLeft;
								break;
				}
				
				
				var bubbleOffsetX;	
				var bubbleOffsetY;				
				switch (this.valign)
				{
					case 'top': bubbleOffsetY = 0;
								break;
					case 'bottom': bubbleOffsetY = -bubble.getHeight();
								break;
					case 'middle': bubbleOffsetY = - Math.round(bubble.getHeight() / 2);
								break;
					case 'default': bubbleOffsetY = 0;
								break;
				}
					
				switch (this.align)
				{
					case 'left': bubbleOffsetX = 0;
								break;
					case 'right': bubbleOffsetX = - bubble.getWidth();
								break;
					case 'middle': bubbleOffsetX = - Math.round(bubble.getWidth() / 2);
								break;
					case 'default': bubbleOffsetX = 0;
								break;
				}				
				
				bubble.style.left = bubbleOffsetX + referencePointOffsetX + this.offsetX + "px";
				bubble.style.top = bubbleOffsetY + referencePointOffsetY + this.offsetY + "px";
			}
						
			//zobrazenie bublinky			
			this.showBubble(bubble);
			
			
		}
	},
	
	showBubble: function(bubble)
	{
		if (bubble)
		{
			if(this.appearDuration == 0 || Prototype.Browser.IE)
			{
				bubble.show();	
			}
			else
			{
				Effect.Appear(bubble.identify(), {duration: this.appearDuration});
			}
			
			//priradenie eventov	
			bubble.observe('mouseover', this.bubbleOver.bind(this, bubble));
			bubble.observe('mouseout', this.bubbleOut.bind(this, bubble));
		}
		

	},
	
	hideBubble:function(bubble)
	{
		if (bubble) bubble.hide();		
		/*console.log('fade');
		Effect.Fade(bubble.identify(), {duration:0.2})*/
	},
	
	bubbleOut: function(bubble,event)
	{
		var bubbleInvokerId = bubble.identify().replace(this.bubbleSuffix, '');
		
		//quirksmode.org - zistenie kci naozaj kurzor opustil aktivnu plochu invokera
		if (!event) var event = window.event;
		
		var tg = (window.event) ? event.srcElement : event.target;
		var reltg = $((event.relatedTarget) ? event.relatedTarget : event.toElement);		
		
		while ((reltg != tg) && reltg.nodeName != 'BODY')
		{	
			//prechod vramci bublinky 
			if (reltg == bubble) return; 
			//prechod vramci bublinky 
			if (bubbleInvokerId && reltg.identify() == bubbleInvokerId) return; 
			reltg = $(reltg.parentNode);
			
		}
		// prechod v ramci bublinky
		if (reltg == tg  ) return;	
		
//		console.log('bubbleOut: ' + bubble.identify());

		$(bubbleInvokerId).removeClassName('over');	

		if(this.currentInvoker && this.currentInvoker.identify() == bubbleInvokerId)
		{
			window.clearTimeout(this.invokerOutTimerId);
		}
		
		var invokerOutTimerId = this.bubbleOutDelay.bind(this).delay(this.outDelayTime,bubble);		
		if(this.showEvent == 'click')
		{
			window.clearTimeout(this.invokerOutTimerId);
			this.invokerOutTimerId = invokerOutTimerId;
		}
	},
	
	bubbleOutDelay:function(bubble)
	{
		this.hideBubble(bubble);
		this.invokerId = null;
		
		//odstranenie over class name invokera 
//		$$('.' + this.invokerClassName+'.over').each(
//			function(invoker)
//			{
//				if(invoker.identify() != this.invokerId)
//				{
//					$(invoker).removeClassName('over');	
//				}
//				
//			}.bind(this)
//		)
	},
	bubbleOver: function(bubble,event)
	{
		var bubbleInvokerId = bubble.identify().replace(this.bubbleSuffix, '');
		if(this.currentInvoker && this.currentInvoker.identify() == bubbleInvokerId)
		{
//			console.log('bubbleOver: ' + bubble.identify());
			window.clearTimeout(this.invokerOutTimerId);
			this.invokerOutTimerId = null;
		}
		$(bubbleInvokerId).addClassName('over');
	}
	
});


$(document).observe('dom:loaded', function() {
	if($('langSelectBoxHolder'))	$('langSelectBoxHolder').hide();
	if($('langDropDownLink')) $('langDropDownLink').show();
	/*$('colorDropDownLink').show();*/
	var bubble = new Bubbles;
	bubble.align = 'right';
	bubble.referencePointAlign = 'right';
	bubble.create('selectButton');
	
	$$('.radioSelectBt').each(Element.show);
	$$('.radioBlindSelectBox').each(Element.hide);
	
	var radioBubble = new Bubbles;
	radioBubble.create('radioSelectBt');
	
	
/*	var multilevelBubble = new Bubbles;
	multilevelBubble.showEvent = 'mouseover';
	multilevelBubble.outDelayTime = 0;
	multilevelBubble.referencePointAlign = 'right';
	multilevelBubble.create('multilevelMenuLink');*/
	
});
