
// FISpopMenu Version 1.01
// FISolution
// 17. Juli 2009 20:06:37
// Uses mootools-beta-1.2b1-compatible.js
 
var FISpopMenu = new Class(
{
	// Optionen Implementieren
	Implements : [Options],
 
	// Default Optionen setzen
	options : {
		'id'		 : 'blobme',
		'preclass'   : 'FISpop',
		'startclass' : 'startblob',
		'horizontal' : true,
		'duration'   : 100,
		'transition' : Fx.Transitions.Sine.easeInOut,
		'oversizex'  : 5,
		'oversizey'  : 5,
		'oversize2x' : 0,
		'oversize2y' : 0,	
		'subOpacity' : 1,
		'subSizeMain': true,
 
		'morphuse'   : true,
 
		'blobuse'    : true,
		'blobcolor'  : '#FF0000',
		'blobduration': 400,
		'blobopacity': 0.6,
		'blobtransition' : Fx.Transitions.Sine.easeInOut,
 
		'timeout'    : 400
	},
 
	blob : false,
	start : false,
	stopped : false, 
	popsettings : {
		start  : false,
		fx	 : false
	},
 
	blobsettings : {
		start  : false,
		fx	 : false
	},
 
	activeMenues : new Array(),
	parent : null,
 
	createMenu: function(ul, parent, horizontal, main) {
  		var table = new Element('table', {
  			'class': this.options.preclass + " " + this.options.preclass + (main ? '_main' : '_sub') + ''
  		});
		var tbody = new Element('tbody');
		tbody.inject(table);
 
		if(horizontal) {
			var tr = new Element('tr');
			tr.inject(tbody);
		}
 
		table.addEvent('mouseleave', function() {
			if(this.stopped == true) return;
			this.setTimeoutInterval();
		}.bind(this));		
		table.addEvent('mouseenter', function() {
			if(this.stopped == true) return;
			this.clearTimeoutInterval();
		}.bind(this));	
 
 
  		var surroundingDiv = new Element('div', {
			'class':this.options.preclass + '_sub_outer',
			'styles': {
				'position': 'absolute',
				'display': 'none',
				'opacity': 0
			}
		});
 
		surroundingDiv.gone = false;	
 
  		var tdClass = this.options.preclass + '_item_' + (main ? 'main' : 'sub');
 
  		ul.getChildren('li').each(function(li) {
  			var a = li.getChildren('a');
  			if(a.length > 0) {
	  			a = a[0];
	  			var td = new Element('td', {
					'class'	: tdClass + ' ' + (li.className.match(/(^|\s)active(\s|$)/) ? 'active' : ''),
					'styles' : {
						'z-index'  : 100,
						'cursor'   : 'pointer'						
					}
				});
				if(this.options.morphuse) {
					var subMorph = new Fx.Morph(td, {wait: false, transition:this.options.transition, duration:this.options.duration});
					td.highlight = function() {
						subMorph.start("." + tdClass + '_hover');
					}
					td.fade = function() {
						subMorph.start("." + tdClass);
					}
					td.addEvent('mouseleave', function() {
						if(this.stopped == true) return;
						var open = false; 
						for(var i = this.activeMenues.length - 1; i >= 0; i--) {
							if(this.activeMenues[i].td == td) {
								open = true;
								break;
							}
						}
						if(!open) td.fade();						
					}.bind(this));
				}
				else {
					td.highlight = function() {
						td.className = tdClass + ' ' + tdClass + '_hover';
					}
					td.fade = function() {
						td.className = tdClass;
					}
				}
 
				td.addEvent('mouseenter', function() {
					if(this.stopped == true) return;
					td.openAnyway = false;
					td.highlight();
				}.bind(this));
				td.addEvent('mouseleave', function() {
					if(this.stopped == true) return;
					td.openAnyway = false;
					var open = false; 
					for(var i = this.activeMenues.length - 1; i >= 0; i--) {
						if(this.activeMenues[i].td == td) {
							open = true;
							break;
						}
					}
					if(!open) {
						td.fade();
					}
				}.bind(this));
				var href = a.href;
				var target = a.target;
				td.addEvent('click', function(e) {
					new Event(e).stop();
					this.stopped = true;
					if(target == '' || target == '_self') {  
						location.href = href;
					}
					else {
						window.open(href, target, '');
					}
				});
 			
				var span = new Element('a', {
					'href': href,
					'target': target
				});
				span.innerHTML = a.innerHTML;
				span.setStyles( {
					'position':'relative', 
					'z-index':101
				});
				span.inject(td);
 
				if(!horizontal) {
					tr = new Element('tr');
					tr.inject(tbody);
				}
  				td.inject(tr);
 
  				var submenu = null;
  				var subul = li.getChildren('ul');
  				if(subul.length > 0) {
  					submenu = this.createMenu(subul[0], td);
  					submenu.td = td;
  					td.submenu = submenu;
  				}
				td.addEvent('mouseenter', function() {
					if(this.stopped == true) return;
					if(surroundingDiv.gone) return;
					for(var i = this.activeMenues.length - 1; i >= 0; i--) {
						if(table != this.activeMenues[i] && (submenu == null || this.activeMenues[i] != submenu)) {
							this.activeMenues[i].slideOut();
							this.activeMenues[i].td.fade();
							this.activeMenues.pop();
						}
						else {
							break;
						}
					}
					if(submenu && !td.ignoreSub && (submenu.openAnyway || this.activeMenues.length == 0 || (this.activeMenues[i] && this.activeMenues[i] != submenu))) {
						this.activeMenues[this.activeMenues.length] = submenu;
						submenu.slideIn();						
					}
				}.bind(this));	
 
				if(main && this.options.blobuse) {
					td.addEvent('mouseenter', function() {
						if(this.stopped == true) return;
						if(surroundingDiv.gone) return;
						this.moveBlob(td);
					}.bind(this));					
				}
			}
  		}.bind(this));
 
 
  		if(!main) {
			surroundingDiv.inject(this.parent);
			table.inject(surroundingDiv);	
 
			surroundingDiv.setStyles( {
			} );
 
			var fade = new Fx.Styles(surroundingDiv, {	wait:false, 
												transition:this.options.transition, 
												duration:this.options.duration,
												onComplete: function() {
							  						if(surroundingDiv.gone) surroundingDiv.style.display = 'none';
							  					}
							  				});
			table.slideOut = function() {
  				surroundingDiv.gone = true;
  				fade.start( {
  					'opacity': 0
  				});
  			}
  			table.slideIn = function() {
  				surroundingDiv.gone = false;
  				var pos = parent.getPosition();
  				var left = 0;
  				var top = 0;
  				if(parent.className.match(/item_main/)) {
	  				left = pos.x;
					top = pos.y + parent.offsetHeight;
				}
				else {
					left = pos.x + parent.offsetWidth;
					top = pos.y;
				}
				if(this.options.subSizeMain && parent.className.match(/_item_main/)) {
					table.setStyles( {
						'width': parent.offsetWidth + "px"
					});
				} 
				surroundingDiv.setStyles( {
					'left': left,
					'top': top,
					'display': 'block'
				});
 
  				fade.start( {
  					'opacity': this.options.subOpacity	
  				});
  			}.bind(this);
  		}
  		else {
  			var xtds = table.getElements('tr')[0].getElements('td');
  			xtds[xtds.length - 1].setStyle('paddingRight', 0);
  			table.inject(this.parent);  		
  		}
  		return table;
 
  	},
 
  	timeoutInterval : null,
 
  	setTimeoutInterval : function() {
  		this.clearTimeoutInterval();
  		this.timeoutInterval = window.setInterval(function() {
			if(this.stopped == true) return;
			this.highlightStart();
		}.bind(this), this.options.timeout);
  	},
  	clearTimeoutInterval : function() {
  		window.clearInterval(this.timeoutInterval);
  	},
 
	// init
	initialize: function(options) {
		// optionen uebernehmen
		this.setOptions(options);
 
 
		tmp = $(this.options.id);
		this.parent = new Element('div').inject($(this.options.id).getParent());
 
		var menu = this.createMenu(tmp, this.parent, this.options.horizontal, true);
 
		$(this.options.id).remove();
		this.parent.id = this.options.id;
 
		var actives = $$('.' + this.options.preclass + "_main .active");
		if(actives.length > 0) {
			this.start = actives[0];
			this.highlightStart();
		}
	},
 
  	start: false,
 
  	highlightStart: function() {
  		if(this.stopped == true) return;
  		for(var i = this.activeMenues.length - 1; i >= 0; i--) {
			this.activeMenues[i].slideOut();
			this.activeMenues[i].td.fade();
			this.activeMenues.pop();
		}
		if(!this.start) return;
		this.start.ignoreSub = true;
		this.start.openAnyway = true;
		this.start.fireEvent('mouseenter');
		this.start.ignoreSub = false;
  	},
 
	// blob bewegen
	moveBlob: function(el) {
		if(this.stopped == true) return;
		if(!el) return;
		if($(el.target)) el = $(el.target);
		if(el.getTag() != 'td') {
			el = el.getParent('td');
		}  
 
		// position des aktuellen elements bestimmen
		var pos = el.getPosition();
		var left = pos.x - this.options.oversize2x;
		var top = pos.y - this.options.oversize2y;
 
		if(!this.blob) {
			this.blob = new Element('div', {
				'class'        : this.options.preclass + '_blob',
				'styles'       : {
					'background-color' : this.options.blobcolor,
					'position'         : 'absolute',
					'left'             : left,
					'top'              : top,
					'width'            : 0,
					//'cursor'           : 'pointer',
					'height'           : 0,
					'opacity'          : 0,
					'z-index'          : 0
		      	}
			});
 
			// fx morph init
			this.blobsettings.fx = new Fx.Morph($(this.blob), {
				duration   : this.options.blobduration,
				transition : this.options.blobtransition,
				link       : 'cancel'
			});
 
			this.blob.inject($(this.options.id)); 
 
			this.blobsettings.fx.set({
		        'left'   : left,
		        'width'  : el.offsetWidth + (this.options.oversize2x*2),        
		        'top'    : top,
		        'height' : el.offsetHeight + (this.options.oversize2y*2),
		        'opacity': 1
			});
 
			this.blob.datedTo = el;
 
			return
		}		
		else if(el == this.blob.datedTo) {
			return;
		}
 
		this.blob.datedTo = el;
 
 
		// animation starten
		this.blobsettings.fx.start({
	        'left'   : pos.x - this.options.oversizex,
	        'width'  : el.offsetWidth + (this.options.oversizex*2),        
	        'top'    : pos.y - this.options.oversizey,
	        'height' : el.offsetHeight + (this.options.oversizey*2),
	        'opacity': this.options.blobopacity     
		}).chain(function(){
	     	// 2. schritt der animation
	      	this.blobsettings.fx.start({
		        'left'   : left,
		        'width'  : el.offsetWidth + (this.options.oversize2x*2),        
		        'top'    : top,
		        'height' : el.offsetHeight + (this.options.oversize2y*2),
		        'opacity': 1
			});
	    }.bind(this));		
	}
 
});