var Flyout = function() {
	
	// Definitionen der benötigten Keys
	var KEY_END				 = 35;
	var KEY_HOME			 = 36;
	var KEY_LEFT			 = 37;
	var KEY_UP				 = 38;
	var KEY_RIGHT			 = 39;
	var KEY_DOWN			 = 40;
	var KEY_SPACE			 = 32;
	var KEY_ESC				 = 27;
	var KEY_TAB				 = 9; 
	var KEY_RETURN		     = 13;
	
	var cfe = ''; // Current Focused Element
		
	// Konstruktor	
	this.init = function() {
		var i = 0;
		var f = $('#flyout ul li a');	
				
		// Landmark-Role des Flyout-Windows
		$('#flyout').attr('role', 'application');
		
		// Landmark-Role im Haupttab-UL
		$('#flyout ul').attr('role', 'tablist');
				
		// Landmark-Role der Haupttab-LI
		$('#flyout ul li').attr('role', 'tab');
		//$('#flyout ul li').attr('tabindex', '0');
		
		// Präparation der Haupttab-Ankers
		f.each(function() {
			//$(this).attr('onfocus', 'this.blur()');			// Blur-Rahmen entfernen (Keypress-Event wird entfernt)
			$(this).attr('name', i);											// Name-Tag hinzufügen
			$(this).attr('id', 'label-main-'+i);					// ID inzufügen
			$(this).attr('class', 'no-focus flyout-tab');	// Tab-Klassen vergeben
			i++;
		});
		
		// Eventhandling für Haupttab-Klick
		f.live('click', function(e) {
			var id = $(this).attr('name');
			$(this).createFlyoutWindow(id);
			e.preventDefault();
			return false;
		});
		
		// Eventhandling für Close-Button
		$('#flyout-close, #flyout-cover').live('click', function(e) {
			$(this).removeFlyoutWindow();
			e.preventDefault();
			return false;
		});	
		
		// Eventhandling für Top-Nav
		$('#flyout-body .nav-content-tab ul li a').live('click', function(e) {
			$(this).prepareTabAndContent($(this), '#flyout-body .nav-content-tab', 'label-nav-content', '.flyout-inner');
			e.preventDefault();
			return false;												 
		});
		
		// Eventhandling für Sub-Nav-Tabs
		$('.flyout-sub-nav ul li a').live('click', function(e) {
			$(this).prepareTabAndContent($(this), '.flyout-sub-nav', 'label-sub-nav', '#flyout-content');
			e.preventDefault();
			return false;
		});				 
		
		// Eventhandling für Left-Side-Tabs
		$('ul.flyout-nav-side li a').live('click', function(e) {
			$(this).prepareTabAndContent($(this), 'ul.flyout-nav-side', 'label-nav-side', '.flyout-content-right');
			e.preventDefault();
			return false;
		});
		
		// Eventhandling für Board-Boxen
		$('.board-boxes ul li a').live('click', function(e){
			$('.board-boxes').addClass('active');	 
			
			var n = $(this).prepareTabAndContent($(this), '.board-boxes', 'board-selected', null);
			setTimeout(function(){
				$('#board-content').remove();
				$('.board-boxes').after('<div id="board-content" role="tabpanel" aria-labelledby="board-selected" aria-live="polite"></div>');
				// URL-Beispiel: ajax/board.jsp.?id=n
				$(this).insertCodeInto($(document).data("config").path + $(document).data("config").board + n + $(document).data("config").suffix, '#board-content');
			}, 300);
			e.preventDefault();
			return false;
		});	 
		
		// Eventhandling für die Tastaturnavigation auf die Ankers der Navigationsklassen mappen
		$('.flyout-nav-az a, #flyout-body .nav-content-tab a, .flyout-nav-side a, .flyout-sub-nav a, .board-boxes a').live('focus', function() {
			cfe = $(this).getClassNameOfParentDIV(this);
		});
		
		$('#flyout a, #flyout-body a').live('focus', function(e){
		  $('.pseudofocus').removeClass('pseudofocus');
		  $(e.target).addClass('pseudofocus');
		});

		// Keypress-Event
		if ($.browser.msie){
			$("#flyout, #flyout-body").live('keydown', function(e) { $(this).keyEvent(e); });
		} else if ($.browser.webkit){
		  $("#flyout, #flyout-body").live('keyup', function(e) { $(this).keyEvent(e); });
		} else {
			$("#flyout, #flyout-body").live('keypress', function(e) { $(this).keyEvent(e); });
		}
		
	};
	this.init(); // Ausführen
		
	/**
	 * Erstellt das Flyout-Window und die transparente Abdeckung
	 * @param id			Die ID entspricht dem name-Tag des LI.
	 */
	$.prototype.createFlyoutWindow = function(id) {	
		var current_id = $('#flyout ul li.active a').attr('name');
		$(this).removeFlyoutWindow();
		if( id != current_id ) {
			var basename = $('#flyout').attr('name') ? $('#flyout').attr('name') : 'start';
			$('#flyout').after('<div id="flyout-cover" style="height: '+$(document).height()+'px"></div><div id="flyout-body" role="tabpanel" aria-live="polite"><a id="flyout-close" href="#">' + $(document).data("config").close + '</a><div id="flyout-wrapper"></div>');
			$('#flyout-body').hide();
			$('#flyout-body').attr('aria-labelledby', 'label-main-'+id);
			var l = $('.flyout-tab[name="'+id+'"]').parents().filter('li');
			l.addClass('active').attr('aria-selected', 'true');
			// URL-Beispiel: ajax/flyout.jsp?name=basename&id=id
			$(this).insertCodeInto($(document).data("config").path + $(document).data("config").flyout + basename + $(document).data("config").delim + id + $(document).data("config").suffix, '#flyout-wrapper');
		}
	};
		
	/**
	 * Entfernt das Flyout-Window und die transparente Abdeckung
	 */
	$.prototype.removeFlyoutWindow = function() {
		if ($('#flyout-cover').size() > 0){
			$('#flyout-cover').remove();
			$('#flyout-body').remove();
			$('#flyout ul li').removeClass('active');
			$('.komp-flash object, .komp-flash embed, #content-column iframe').css('visibility','visible');
		}
	};
	
	/**
	 * AJAX-Call; Stellt das Inner-HTML eines Sourcefiles im Zielcontainer dar
	 * @param sourcefile		 Quelle der Datei (Root ist das Root des Dokuments)
	 * @param targetcontainer ID oder Klassenname des Zielcontainers 
	 */
	$.prototype.insertCodeInto = function(sourcefile, targetcontainer){
	 var container = targetcontainer;
		$.ajax({
				url:	sourcefile,
				type:	'GET',
				async:	true,
				success: function(c) {
					$('.komp-flash object, .komp-flash embed, #content-column iframe').css('visibility', 'hidden');
					$(container).html(c);
					if ($(container).find('ul[role=tablist] li.active').size() === 0){
					  $(container).find('ul[role=tablist] li:first-child a').attr('tabindex', '0');
					} else {
					  $(container).find('ul[role=tablist] li.active a').attr('tabindex', '0');
					}
					$('#flyout-body').fadeIn('fast');
				},
				error:  function() {
					var errorfile = $(document).data("config").path + $(document).data("config").error + $(document).data("config").suffix;
					// URL-Beispiel: ajax/error.jsp
					if (sourcefile != errorfile){
						 $(this).insertCodeInto(errorfile, container);
					}
				}
		});
	};
	
	/**
	 * Komfortfunktion, welches die wichtigens LI- und ARIA-Handlings vollzieht
	 * @param object			$(this)-Objekt der $.click-Funktion
	 * @param mainclass	Klasse oder ID der Tablist
	 * @param arialabel	ID des Ankers des aktiven LI-Tabs
	 * @param sourcecontainer		ID oder Klassenname des Zielcontainers 
	 * @return						Inhalt vom Name-Attribut des Ankers des aktiven LI-Tabs
	 */	
	$.prototype.prepareTabAndContent = function(object, mainclass, arialabel, sourcecontainer) {
      $(mainclass + ' li').removeClass('active');
      $(mainclass + ' li[aria-selected]').removeAttr('aria-selected');
      $(mainclass + ' a#' + arialabel + ' span.hidden').remove();
      var a = $(mainclass + ' a#' + arialabel);
      a.removeAttr('id');
      a.attr('tabindex', '-1');
      object.attr('id', arialabel);
      object.attr('tabindex', '0');
      object.append('<span class="hidden"> (Ausgew&auml;lt)</span>');
      var l = object.parent();
      l.addClass('active');
      l.attr('aria-selected', 'true');
      var n = object.attr('name');
      if (sourcecontainer !== null){
			// URL-Beispiel: ajax/tab.jsp?id=n
			object.insertCodeInto($(document).data("config").path + $(document).data("config").tab + n + $(document).data("config").suffix, sourcecontainer);
		}
		return n;
	};
	
	/**
	 * Fragt den Namen des Parent-DIV ab
	 * @param object	Objekt einer Fokusierten Ankers
	 * @return			Name des übergeordneten DIV-Containers
	 */
	$.prototype.getClassNameOfParentDIV = function(object) {
	  var focus;
	  if ($.browser.msie && ($.browser.version.substr(0, 1) < 8)){
	    focus = $(object);
	  } else {
	    focus = $(':focus');
	    if (focus.size() === 0){
	      focus = $(object);
	    }
	  }
	  var classname = focus.closest('div').attr('class');
	  if (classname == '') return '#flyout';
	  else return '#flyout-body .' + classname.replace(' ', '.');
	};
	
	/**
	 * Setzt den Fokus auf einen Anker und führt den HREF aus.
	 * @param object	Anker-Objekt
	 */
	$.prototype.setFocusAndExecute = function(object) {
		object.click();
		object.focus();
	};
	
	/**
	 * Keyboard-Mapping
	 * @param e		Keystroke-Event
	 */
	$.prototype.keyEvent = function(e) {
		var c = e.keyCode > 0 ? e.keyCode : e.which;
		// alert(c);
		cfe = $(this).getClassNameOfParentDIV(e.target);
		switch(c) {
			
			case KEY_ESC:			
									$(this).removeFlyoutWindow();
									break;			
									
			case KEY_DOWN:
			case KEY_RIGHT:
		              var next;
		              if ($.browser.msie && ($.browser.version.substr(0, 1) < 8)){
		                next = $(cfe + ' a.pseudofocus').parent().next();
		              } else {
		                next = $(cfe + ' a:focus').parent().next();
		              }
		              if (next.size() === 0){
		                next = $(cfe + ' li[aria-disabled!="true"]:first');
		              } else {
                    Enabled: while (next.attr('aria-disabled') == 'true'){
                      if (next.size() === 0){
                        next = $(cfe + ' li[aria-disabled!="true"]:first');
                        break Enabled;
                      }
                      next = next.next();
                    }
		              }
									$(this).setFocusAndExecute(next.find('a'));									
									break;									
									
			case KEY_UP:
			case KEY_LEFT:
									var prev;
									if ($.browser.msie && ($.browser.version.substr(0, 1) < 8)){
		                prev = $(cfe + ' a.pseudofocus').parent().prev();
		              } else {
		                prev = $(cfe + ' a:focus').parent().prev();
		              }
		              if (prev.size() === 0){
		                prev = $(cfe + ' li[aria-disabled!="true"]:last');
		              } else {
                    Enabled: while (prev.attr('aria-disabled') == 'true'){
                      if (prev.size() === 0){
                        prev = $(cfe + ' li[aria-disabled!="true"]:last');
                        break Enabled;
                      }
                      prev = prev.prev();
                    }
		              }
									$(this).setFocusAndExecute(prev.find('a'));								
									break;
									
			case KEY_HOME:			
									c = $(cfe + ' li[aria-disabled!="true"]:first a');
									$(this).setFocusAndExecute(c);
									break;
			
			case KEY_END:			
									c = $(cfe + ' li[aria-disabled!="true"]:last a');
									$(this).setFocusAndExecute(c);
									break;
									
		  default:
		              return;
		}
		e.preventDefault();
	};
	
};

if($) {
	$(document).ready(function(){
		$.getJSON('scripts/config.json', function(data){
			$(document).data("config", data);
		});
		var fo = new Flyout($);	
	});
}
