function callInProgress (xmlhttp) {
	switch (xmlhttp.readyState) {
		case 1: 
		case 2: 
		case 3:
			return true;
			break;
		// Case 4 and 0
		default:
			return false;
			break;
	}
}
function showFailureMessage(_microsec) {
	// delete Prozess-DIV
	if( $('prozess') ){$('prozess').hide();}
	if( (typeof winID!='undefined') && $$('div.default_content')){
		var _sec = _microsec/1000;	
		var _content = "<div id=\"info-content\"><h4><span><b>&nbsp;</b></span></h4><div class=\"tab_content_out\"><br style=\"clear: both;\" /><div class=\"disclaimer ajax_error_msg\" id=\"tab_content_in\"><fieldset><legend>Error Message</legend><form method=\"post\" action=\"#\"><p>There are any problems with network connection, because no answer until "+_sec+" sec. Please try again later.</p><p>Contact administration, if the problem is not be fixed.</p><b class=\"submit\"><em><span><input name=\"accept_disclaimer\" id=\"accept_disclaimer\" value=\"OK\" class=\"submit\" type=\"submit\" onclick=\"Windows.close('"+winID+"\', event); return false;\"></span></em></b></form></fieldset></div></div></div>";	
		$$('div.default_content')[0].update(_content);
	}
}
// Register global responders that will occur on all AJAX requests
var lastAJAXRequest;

Ajax.Responders.register({
	onCreate: function(request) {		
		var _microsec = 20000; // Two seconds
		// global speichern des letzten AJAXRequestObjects
		lastAJAXRequest = request.transport;
		
		request['timeoutId'] = window.setTimeout(
			function() {
				// If we have hit the timeout and the AJAX request is active, abort it and let the user know
				if (callInProgress(request.transport)) {
					request.transport.abort();
					showFailureMessage(_microsec);
					// Run the onFailure method if we set one up when creating the AJAX object
					if (request.options['onFailure']) {
						request.options['onFailure'](request.transport, request.json);
					}
				}
			},
		_microsec
		);
	},
	onComplete: function(request) {
		// Clear the timeout, the request completed ok
		window.clearTimeout(request['timeoutId']);
	}
});

// Erweitert die Window._createWindow Klasse um angepasstes HTML// // @autor: kuehnj // @date: 12.08.2008
Object.extend(Window.prototype, {  // Creates HTML window code
   close: function() {
    // Asks closeCallback if exists
    if (this.visible) {
      if (this.options.closeCallback && ! this.options.closeCallback(this)) 
        return;

      if (this.options.destroyOnClose) {
        var destroyFunc = this.destroy.bind(this);
        if (this.options.hideEffectOptions.afterFinish) {
          var func = this.options.hideEffectOptions.afterFinish;
          this.options.hideEffectOptions.afterFinish = function() {func();destroyFunc() }
        }
        else 
          this.options.hideEffectOptions.afterFinish = function() {destroyFunc() }
      }
      
      // checkt, ob XMLRequest noch aktiv -> Abbruch des Request
	  if (lastAJAXRequest){
		lastAJAXRequest.abort();
      }
      
      Windows.updateFocusedWindow();
      
      this.doNotNotifyHide = true;
      this.hide();
      this.doNotNotifyHide = false;
      this._notify("onClose");
    }
  },
  setAjaxContent: function(url, options, showCentered, showModal) {
    this.showFunction = showCentered ? "showCenter" : "show";
    this.showModal = showModal || false;
  
  	// delete Prozess-DIV
    if( $('prozess') ){
		// $('prozess').setAttribute('class', "");
		$('prozess').show();
	}
  
    options = options || {};

    // Clear HTML (and even iframe)
    this.setHTMLContent("");
 
    this.onComplete = options.onComplete;
    if (! this._onCompleteHandler)
      this._onCompleteHandler = this._setAjaxContent.bind(this);
    options.onComplete = this._onCompleteHandler;
   
    new Ajax.Request(url, options);    
    options.onComplete = this.onComplete;
  },
  _setAjaxContent: function(originalRequest) {
    var new_Request = originalRequest.responseText;
  	  	
  	//if(!( $('overlay_modal') && ($('overlay_modal').getAttribute('style').match(/(display: none;)/ig)))) {
  	if( $('overlay_modal')  ){
	  	
	  	// delete Prozess-DIV
	    if( $('prozess') ){
			// $('prozess').setAttribute('class', "hidden");
			$('prozess').hide();
		}
	  		  	
	 	Element.update(this.getContent(), new_Request);
	    if (this.onComplete)
	      this.onComplete(originalRequest);
	    this.onComplete = null;
	    this[this.showFunction](this.showModal)
	}    
  },
  _createWindow: function(id) {
    var className = this.options.className;
    var win = document.createElement("div");
    win.setAttribute('id', id);
    win.className = "dialog";
    var content;
    if (this.options.url)
      content= "<iframe frameborder=\"0\" name=\"" + id + "_content\"  id=\"" + id + "_content\" src=\"" + this.options.url + "\"> </iframe>";
    else
      content ="<div id=\"" + id + "_content\" class=\"" +className + "_content\">  </div>";

    var closeDiv = this.options.closable ? "<div id=\"prozess\"><div id=\"prozess_image\" class=\"" + className + "_progress\">  </div></div><div class='"+ className +"_close' id='"+ id +"_close' onclick='Windows.close(\""+ id +"\", event)'><a class=\"close\" href=\"#\">&nbsp;</a></div>" : "";
    //var closeDiv = this.options.closable ? "</div><div class='"+ className +"_close' id='"+ id +"_close' onclick='Windows.close(\""+ id +"\", event)'><a class=\"close\" href=\"#\">&nbsp;</a></div>" : "";
    var seAttributes = this.options.resizable ? "class='" + className + "_sizer' id='" + id + "_sizer'" : "class='"  + className + "_se'";
    
    var table_top = "<table id='"+ id +"_row1' class=\"top table_window\"><tr><td class='"+ className +"_nw'></td><td class='"+ className +"_n'><div id='"+ id +"_top' class='"+ className +"_title title_window'>"+ this.options.title +"</div></td><td class='"+ className +"_ne'></td></tr></table>"; 
    var table_content = "<table id='"+ id +"_row2' class=\"mid table_window\"><tr><td class='"+ className +"_w'></td><td id='"+ id +"_table_content' class='"+ className +"_content' valign='top'>" + content + "</td><td class='"+ className +"_e'></td></tr></table>";
    var table_bottom = "<table id='"+ id +"_row3' class=\"bot table_window\"><tr><td class='"+ className +"_sw'></td><td class='"+ className +"_s'><div id='"+ id +"_bottom' class='status_bar'><span style='float:left; width:1px; height:1px'></span></div></td><td " + seAttributes + "></td></tr></table>";
    
    win.innerHTML = closeDiv + table_top + table_content + table_bottom;
    Element.hide(win);
    this.options.parent.insertBefore(win, this.options.parent.firstChild);
    Event.observe($(id + "_content"), "load", this.options.onload);
    return win;
  },
  initialize: function() {
    var id;
    var optionIndex = 0;
    // For backward compatibility like win= new Window("id", {...}) instead of win = new Window({id: "id", ...})
    if (arguments.length > 0) {
      if (typeof arguments[0] == "string" ) {
        id = arguments[0];
        optionIndex = 1;
      }
      else
        id = arguments[0] ? arguments[0].id : null;
    }
    
    // Generate unique ID if not specified
    if (!id)
      id = "window_" + new Date().getTime();
      
    if ($(id))
      alert("Window " + id + " is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor");

    this.options = Object.extend({
      className:         "dialog",
      blurClassName:     null,
      minWidth:          100, 
      minHeight:         20,
      resizable:         true,
      closable:          true,
      minimizable:       true,
      maximizable:       true,
      draggable:         true,
      userData:          null,
      showEffect:        (Window.hasEffectLib ? Effect.Appear : Element.show),
      hideEffect:        (Window.hasEffectLib ? Effect.Fade : Element.hide),
      showEffectOptions: {},
      hideEffectOptions: {},
      effectOptions:     null,
      parent:            document.body,
      title:             "&nbsp;",
      url:               null,
      onload:            Prototype.emptyFunction,
      width:             200,
      height:            300,
      opacity:           1,
      recenterAuto:      true,
      wiredDrag:         false,
      closeCallback:     null,
      destroyOnClose:    false,
      gridX:             1, 
      gridY:             1,
      fixed:			 true      
    }, arguments[optionIndex] || {});
    if (this.options.blurClassName)
      this.options.focusClassName = this.options.className;
      
    if (typeof this.options.top == "undefined" &&  typeof this.options.bottom ==  "undefined") 
      this.options.top = this._round(Math.random()*500, this.options.gridY);
    if (typeof this.options.left == "undefined" &&  typeof this.options.right ==  "undefined") 
      this.options.left = this._round(Math.random()*500, this.options.gridX);

    if (this.options.effectOptions) {
      Object.extend(this.options.hideEffectOptions, this.options.effectOptions);
      Object.extend(this.options.showEffectOptions, this.options.effectOptions);
      if (this.options.showEffect == Element.Appear)
        this.options.showEffectOptions.to = this.options.opacity;
    }
    if (Window.hasEffectLib) {
      if (this.options.showEffect == Effect.Appear)
        this.options.showEffectOptions.to = this.options.opacity;
    
      if (this.options.hideEffect == Effect.Fade)
        this.options.hideEffectOptions.from = this.options.opacity;
    }
    if (this.options.hideEffect == Element.hide)
      this.options.hideEffect = function(){ Element.hide(this.element); if (this.options.destroyOnClose) this.destroy(); }.bind(this)
    
    if (this.options.parent != document.body)  
      this.options.parent = $(this.options.parent);
      
    this.element = this._createWindow(id);       
    this.element.win = this;
    
    // Bind event listener
    this.eventMouseDown = this._initDrag.bindAsEventListener(this);
    this.eventMouseUp   = this._endDrag.bindAsEventListener(this);
    this.eventMouseMove = this._updateDrag.bindAsEventListener(this);
    this.eventOnLoad    = this._getWindowBorderSize.bindAsEventListener(this);
    this.eventMouseDownContent = this.toFront.bindAsEventListener(this);
    this.eventResize = this._recenter.bindAsEventListener(this);
 
    this.topbar = $(this.element.id + "_top");
    this.bottombar = $(this.element.id + "_bottom");
    this.content = $(this.element.id + "_content");
    
    Event.observe(this.topbar, "mousedown", this.eventMouseDown);
    Event.observe(this.bottombar, "mousedown", this.eventMouseDown);
    Event.observe(this.content, "mousedown", this.eventMouseDownContent);
    Event.observe(window, "load", this.eventOnLoad);
    Event.observe(window, "resize", this.eventResize);
    Event.observe(window, "scroll", this.eventResize);
    Event.observe(this.options.parent, "scroll", this.eventResize);
    
    if (this.options.draggable)  {
      var that = this;
      [this.topbar, this.topbar.up().previous(), this.topbar.up().next()].each(function(element) {
        element.observe("mousedown", that.eventMouseDown);
        element.addClassName("top_draggable");
      });
      [this.bottombar.up(), this.bottombar.up().previous(), this.bottombar.up().next()].each(function(element) {
        element.observe("mousedown", that.eventMouseDown);
        element.addClassName("bottom_draggable");
      });
      
    }    
    
    if (this.options.resizable) {
      this.sizer = $(this.element.id + "_sizer");
      Event.observe(this.sizer, "mousedown", this.eventMouseDown);
    }  
    
    this.useLeft = null;
    this.useTop = null;
    if (typeof this.options.left != "undefined") {
      this.element.setStyle({left: parseFloat(this.options.left) + 'px'});
      this.useLeft = true;
    }
    else {
      this.element.setStyle({right: parseFloat(this.options.right) + 'px'});
      this.useLeft = false;
    }
    
    if (typeof this.options.top != "undefined") {
      this.element.setStyle({top: parseFloat(this.options.top) + 'px'});
      this.useTop = true;
    }
    else {
      this.element.setStyle({bottom: parseFloat(this.options.bottom) + 'px'});      
      this.useTop = false;
    }
      
    this.storedLocation = null;
    
    this.setOpacity(this.options.opacity);
    if (this.options.zIndex)
      this.setZIndex(this.options.zIndex)

    if (this.options.destroyOnClose)
      this.setDestroyOnClose(true);

    this._getWindowBorderSize();
    this.width = this.options.width;
    this.height = this.options.height;
    this.visible = false;
    
    this.constraint = false;
    this.constraintPad = {top: 0, left:0, bottom:0, right:0};
    
    if (this.width && this.height)
      this.setSize(this.options.width, this.options.height);
    this.setTitle(this.options.title)
    Windows.register(this);
    
    if (this.options.fixed)
      this.options.fixed = this.options.fixed;
      
  },
  _center: function(top, left) {    
    var windowScroll = WindowUtilities.getWindowScroll(this.options.parent);    
    var pageSize = WindowUtilities.getPageSize(this.options.parent);    
    if (typeof top == "undefined")
      top = (pageSize.windowHeight - (this.height + this.heightN + this.heightS))/2;
    if(!this.options.fixed)
    	top += windowScroll.top
    
    if (typeof left == "undefined")
      left = (pageSize.windowWidth - (this.width + this.widthW + this.widthE))/2;
    left += windowScroll.left      
    this.setLocation(top, left);
    this.toFront();
  }  
});

// Prueft Datum [date_from < date_to],
// setzt sonst anderes Datum auf selben Tag
//
// @autor: kuehnj
// @date: 23.02.2009
function checkFromTo(source, set){
				
	/* Create the DateFormatter */
	_df = new DatePickerFormatter([ "yyyy", "mm", "dd" ], "-" );

	/* fromData validieren */
	var from_date 	= _df.match($F('date_from'));			
	var _fromDate	= new Date(Number(from_date[0]), Number(from_date[1]) - 1, Number(from_date[2]));

	/* toData validieren */
	var to_date 	= _df.match($F('date_to'));
	var _toDate		= new Date(Number(to_date[0]), Number(to_date[1]) - 1, Number(to_date[2]));
				
	if( _fromDate > _toDate ){					
		
		if(set){
			if(source == "from"){
				var new_to_date = new Date(Number(from_date[0]), Number(from_date[1]) - 1, Number(from_date[2]));
				Form.Element.setValue("date_to", this._df.date_to_string(new_to_date.getFullYear(), (new_to_date.getMonth()+1), new_to_date.getDate(), "-"));
			}else{
				var new_from_date = new Date(Number(to_date[0]), Number(to_date[1]) - 1, Number(to_date[2]));
				Form.Element.setValue("date_from", this._df.date_to_string(new_from_date.getFullYear(), (new_from_date.getMonth()+1), new_from_date.getDate(), "-"));
			}
		}
		
		return false;
	}
	
	return true;				
}

// Prueft Datum [date_from < date_min],
// setzt sonst From-Datum auf Min-Datum und To-Datum auf Min-Datum + 30Tage
//
// @autor: kuehnj
// @date: 19.03.2009
function checkDateMin(date_min, set){
				
	/* Create the DateFormatter */
	_df = new DatePickerFormatter([ "yyyy", "mm", "dd" ], "-" );

	/* fromData validieren */
	var from_date 	= _df.match($F('date_from'));			
	var _fromDate	= new Date(Number(from_date[0]), Number(from_date[1]) - 1, Number(from_date[2]));

	/* toData validieren */
	var to_date 	= _df.match($F('date_to'));
	var _toDate		= new Date(Number(to_date[0]), Number(to_date[1]) - 1, Number(to_date[2]));
	
	/* minData validieren */
	var min_date 	= _df.match(date_min);
	var _minDate	= new Date(Number(min_date[0]), Number(min_date[1]) - 1, Number(min_date[2]));
		
	if( _minDate > _fromDate ){
		
		if(set){
			// fromData updaten
			var new_from_date = new Date(Number(min_date[0]), Number(min_date[1]) - 1, Number(min_date[2]));
			Form.Element.setValue("date_from", this._df.date_to_string(new_from_date.getFullYear(), (new_from_date.getMonth()+1), new_from_date.getDate(), "-"));
			
			// toData updaten
			var new_to_date = new Date(Number(min_date[0]), Number(min_date[1]) - 1, Number(min_date[2]));
			/* maxData = minData + 30Tage */
			new_to_date.setTime(new_to_date.getTime() + 30 * 24 * 60 * 60 * 1000);
			Form.Element.setValue("date_to", this._df.date_to_string(new_to_date.getFullYear(), (new_to_date.getMonth()+1), new_to_date.getDate(), "-"));
		}
		
		return false;
	}
	
	return true;
}

//Prueft Datum [date_to <= date_max],
//setzt sonst To-Datum auf Max-Datum
//
//@autor: kuehnj
//@date: 28.05.2009
function checkDateMax(date_max, set){
				
	/* Create the DateFormatter */
	_df = new DatePickerFormatter([ "yyyy", "mm", "dd" ], "-" );

	/* toData validieren */
	var to_date 	= _df.match($F('date_to'));
	var _toDate		= new Date(Number(to_date[0]), Number(to_date[1]) - 1, Number(to_date[2]));
		
	/* minData validieren */
	var max_date 	= _df.match(date_max);
	var _maxDate	= new Date(Number(max_date[0]), Number(max_date[1]) - 1, Number(max_date[2]));
	
	if( _maxDate < _toDate ){
		
		if(set){
			// toData updaten
			var new_to_date = new Date(Number(max_date[0]), Number(max_date[1]) - 1, Number(max_date[2]));
			Form.Element.setValue("date_to", this._df.date_to_string(new_to_date.getFullYear(), (new_to_date.getMonth()+1), new_to_date.getDate(), "-"));
		}
		
		return false;
	}
	
	return true;
}

// Prueft Formularinhalt, ob es ein richtiges Datum ist
//
// @autor: kuehnj
// @date: 19.03.2009
function checkIsDate(date_string){
	
	var regex = /^(\d{4})-(\d{2})-(\d{2})$/;
	if(!regex.test(date_string)){
		return false;
	}
	y = RegExp.$1;
	m = RegExp.$2;
	d = RegExp.$3;
	
	/* Create the DateFormatter */
	_df = new DatePickerFormatter([ "yyyy", "mm", "dd" ], "-" );

	/* fromData validieren */
	var _date 	= _df.match(date_string);	
	var date = new Date(Number(_date[0]), Number(_date[1]) - 1, Number(_date[2]));	
	
	return ( parseInt(m, 10) == (1+date.getMonth()) ) && (parseInt(d, 10) == date.getDate()) && (parseInt(y, 10) == date.getFullYear() );
}

// Prueft Formularinhalt, ob es im exakten Format vorliegt
//
// @autor: kuehnj
// @date: 19.03.2009
function checkFormatDate(date_string){
	
	var regex = /^(\d{4})-(\d{2})-(\d{2})$/;
	if(!regex.test(date_string)){
		return false;
	}
	return true;
}


function checkAllDate(date_min, date_max){
	
	// Flags fuer Formularelemente
	f_from		= true;
	f_from_er	= '';
	f_to		= true;
	f_to_er		= '';
	
	// Error Messages
	error = new Array();
	error[0] = 'Error: Please use this date format: yyyy-mm-dd. For example 2009-03-17 for the 17th of March, 2009.';
	error[1] = 'Error: Please enter a valid date. For example: 2009-03-07';
	error[2] = 'Error: The starting date must be earlier than '+date_min+'.';
	error[3] = 'Error: The starting date must be earlier than the ending date.';
	error[4] = 'Error: The latest ending date possible is '+date_max+'.';
	
	// richtiges Format?
	if(!checkFormatDate($F('date_from'))){
		f_from_er = error[0];
		f_from = false;
	}
	if(!checkFormatDate($F('date_to'))){
		f_to_er = error[0];
		f_to = false;
	}	
	
	// reales Datum?
	if(!checkIsDate($F('date_from'))){
		f_from_er = error[1];
		f_from = false;
	}
	if(!checkIsDate($F('date_to'))){
		f_to_er =  error[1];
		f_to = false;
	}

	// richtige Periode?
	if(!checkDateMin(date_min, false)){
		f_from_er = error[2];
		f_from = false;
	}
	// Time_to <= Max?
	if(!checkDateMax(date_max, false)){
		f_to_er = error[4];
		f_to = false;
	}
	
	
	// Form < To?
	if(!checkFromTo('from', false)){
		f_from_er = error[3];
		f_from = false;
	}
	if(!checkFromTo('to', false)){
		f_to_er = error[3];
		f_to = false;
	}
	
	// From Input
	if(!f_from){
		setSwitchStyle($('date_from'),'error','');
		setSwitchStyle($$('label.date_from')[0],'error','');
		setDeleteStyle($$('form a.error img')[0],'hidden');
		$$('form a.error img')[0].setAttribute('title', f_from_er);
		$$('form a.error img')[0].setAttribute('alt', f_from_er);
	}else{
		setDeleteStyle($('date_from'),'error');
		setDeleteStyle($$('label.date_from')[0],'error');
		setSwitchStyle($$('form a.error img')[0],'hidden','');
	}
	
	// To Input
	if(!f_to){
		setSwitchStyle($('date_to'),'error','');
		setSwitchStyle($$('label.date_to')[0],'error','');
		setDeleteStyle($$('form a.error img')[1],'hidden');
		$$('form a.error img')[1].setAttribute('title', f_to_er);
		$$('form a.error img')[1].setAttribute('alt', f_to_er);
	}else{
		setDeleteStyle($('date_to'),'error');
		setDeleteStyle($$('label.date_to')[0],'error');
		setSwitchStyle($$('form a.error img')[1],'hidden','');
	}
	
	if(!f_from || !f_to){
		return false;
	}
	return true;
}

function setSwitchStyle(element,start,end){

	if(!element.hasClassName(start)){
		element.toggleClassName(start, end);
	}
	
}
function setDeleteStyle(element,style){

	if(element.hasClassName(style)){
		element.toggleClassName(style, '');
	}
	
}

// Waehlt die jahresabhaengigen Zeilen aus InterruptionsTabelle aus
//
// @autor: kuehnj
// @date: 19.02.2009

function selectYear(year) {
	$$("tr").findAll( function(node) {
		return node.getAttribute('title');
	}).each( function(node) {
		if(year == node.getAttribute('title')){
			node.setAttribute('style', "");
			node.setStyle({display: ''});	
		}else{
			node.setAttribute('style', "display: none;");
			node.setStyle({display: 'none'});
		}
	});
}

// Soll richtige Sortierung ermoeglichen
//
// @autor: kuehnj
// @date: 17.07.2008
/*
TableKit.SortForm = Class.create();
	Object.extend(Object.extend(TableKit.SortForm, TableKit), {
	  getCellText : function(cell, refresh) {
		if(!cell) { return ""; }
		var data = TableKit.getCellData(cell);
		if(refresh || data.refresh || !data.textContent) {
			data.textContent = cell.textContent ? cell.textContent : cell.innerText;
			data.refresh = false;
		}
		
		alert (cell+": "+data.textContent);
		
		return data.textContent;
	  },
	  tach : function() {
	  	alert('tach');
	  }
	});
*/
// Erweitert die TableKit.Rows Klasse um einen Mouseover
// Effekt
//
// @autor: kuehnj
// @date: 07.08.2008
/*
Object.extend(TableKit.Rows, {
	stripe : function(table) {
		var rows = TableKit.getBodyRows(table);
		rows.each(function(r,i) {
			TableKit.Rows.addStripeClass(table,r,i);
			TableKit.Rows.highlight(table);
		});
	},
	highlight: function(table) {
		var rows = TableKit.getBodyRows(table);
		rows.each(function(r) {
			Event.observe(r, 'mouseover', TableKit.Rows.toggleHighlight);
			Event.observe(r, 'mouseout', TableKit.Rows.toggleHighlight);
		});
	},
	toggleHighlight : function(e) {
		e = TableKit.e(e);
		var r = Event.element(e);
		r = r.up('tr');
		if (e.type == 'mouseover')
			r.addClassName('highlight');
		else
			r.removeClassName('highlight');
	}
}); 
*/



//document.observe("dom:loaded", TableKit.SortForm.load);

// Erweitert die Effect-Highlight Klasse um den Effekt nach
// 0.5 sec verzoegert darzustellen
//
// ToDo: vllt einen verzoegerten Farbverlauf -> siehe Wordpress
//
// @autor: kuehnj
// @date: 17.07.2008
Effect.TimeHighlight = Class.create();
	Object.extend(Object.extend(Effect.TimeHighlight.prototype, Effect.Highlight.prototype), {
	  update: function(position) {
		var html_element = this;
	  	setTimeout( function() {
         				html_element.element.setStyle({
         					backgroundColor: $R(0,2).inject('#',function(m,v,i){
	      						return m+((html_element._base[i]+(html_element._delta[i]*position)).round().toColorPart()); 
         					}.bind(html_element)) 
         				});
						},
						500  // 0.5sec warten
				   );
	  }
	});


// Erweitert die Ajax-Autocompleter Klasse um Daten aus 
// dem Browsercache, nach dem entfernen einiger eingegebenen Zeichen im Eingabefeld, zu laden
// @autor: kuehnj
// @date: 04.07.2008

//Quelle: http://tetlaw.id.au/view/blog/adding-a-local-cache-to-ajaxautocompleter/
Ajax.CachedAutocompleter = Class.create();
    Object.extend(Object.extend(Ajax.CachedAutocompleter.prototype, Autocompleter.Base.prototype), {
    
    //=========================================================================
	initialize: function(element, update, url, options) {
        
        this.baseInitialize(element, update, options);
	    this.options.asynchronous  = true;
	    this.options.onComplete    = this.onComplete.bind(this);
	    this.options.defaultParams = this.options.parameters || null;
	    this.options.onErrorHandler = this.options.onErrorHandler || null;
	    this.url                   = url;
	    
	    this.RequestFlag		   = false;
	
	    this.showedResult		   = null;
	    this.storedRequest         = null;
	    this.storedResult          = null;
	    this.ajaxRequestStack      = $A([]);
        this.Requestcache          = {};
        
    },
   	
    //=========================================================================
	selectEntry: function() {
	    var index = this.index;
	    try {
	      this.ajaxRequestStack.each(function(r) {
	        try { r.options.onComplete = null; } catch(e) {}
	      });
	    } catch(ex) {}
	    this.ajaxRequestStack = $A([]);
	
	    this.index = index;
	
	    this.active = false;
	    this.updateElement(this.getCurrentEntry());
	},
    
    //=========================================================================
    onHover: function(event) {
	    var element = Event.findElement(event, 'dd');
	    if(((typeof element != 'undefined')) && (this.index != element.autocompleteIndex)) 
	    {
	        this.index = element.autocompleteIndex;
	        this.render();
	    }
	    Event.stop(event);
	},

	//=========================================================================
	onClick: function(event) {
	    var element = Event.findElement(event, 'dd');
	    if(typeof element != 'undefined'){
		    this.index = element.autocompleteIndex;
		    this.selectEntry();
		    this.hide();
	    }
	    Event.stop(event);
	},
    
	//=========================================================================
	buildShowedResults: function(resultString, maxEntries) {
	    var node = Tag.Node("div");
	    var maxEntries = maxEntries || 0;
	
	    document.getElementsByTagName("body")[0].appendChild(node);
	    $(node).hide();
	    node.innerHTML = resultString;
	    var ul = node.getElementsByTagName("dl")[0];
	    if( ul ) {
	      var lis = ul.getElementsByTagName("dd");
	
	      if( maxEntries > 0 &&  lis.length > maxEntries ) {
	        for ( var i = lis.length; i > maxEntries; --i ) {
	          ul.removeChild(lis[i-1]);
	        }
	      }
	    }
	    return node;
	},
	
	//=========================================================================  
	onKeyPress: function(event) {
	    if(this.active)
	      switch(event.keyCode) {
	       case Event.KEY_TAB:
	       case Event.KEY_RETURN:
	         this.selectEntry();
	         Event.stop(event);
	       case Event.KEY_ESC:
	         this.hide();
	         this.active = false;
	         Event.stop(event);
	         return;
	       case Event.KEY_LEFT:
	       case Event.KEY_RIGHT:
	         return;
	       case Event.KEY_UP:
	         this.markPrevious();
	         this.render();
	         Event.stop(event);
	         return;
	       case Event.KEY_DOWN:
	         this.markNext();
	         this.render();
	         Event.stop(event);
	         return;
	      }
	     else {
	       	if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
	         	(Prototype.Browser.WebKit > 0 && event.keyCode == 0)){
	         	return;
	        }else{
	        	switch(event.keyCode) {
	        	 case 16:	//Shift
	        	 case 17:	//Str
	        	 case 18:	//Alt/Alt Gr
	        	 case 19:	//Pause
	        	 case 20:	//Shift halten
	       		 case 32:	//Leertaste
	       		 case 33:	//Bild hoch	       		 
	       		 case 34:	//Bild runter
	       		 case 35:	//Ende
	       		 case 36:	//Pos 1
	       		 case 37:	//Pfeil links
	       		 case 38:	//Pfeil oben
	       		 case 39:	//Pfeil rechts
	       		 case 40:	//Pfeil unten
	       		 case 91:	//Windowstaste links
	       		 case 92:	//Windowstaste rechts
	       		 case 93:	//rechte Maustaste auf Tastatur simulieren
	       		 case 112:	//F1
	       		 case 113:	//F2
	       		 case 114:	//F3
	       		 case 115:	//F4
	       		 case 116:	//F5
	       		 case 117:	//F6
	       		 case 118:	//F7
	       		 case 119:	//F8
	       		 case 120:	//F9
	       		 case 121:	//F10
	       		 case 122:	//F11
	       		 case 123:	//F12
	       		 case 144:	//Num
	       		 case 145:	//Rollen
	         		return;
	        	}	         
	     	}
	     }
	
	    this.changed = true;
	    this.hasFocus = true;
	
	    if(this.observer) clearTimeout(this.observer);
	      this.observer = 
	        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
	},

	//=========================================================================
	updateChoices: function(choices) {
	    if(!this.changed && this.hasFocus) {
//	      this.update.innerHTML = choices;
		  this.update.innerHTML = markText(this.getToken(), choices);
	      Element.cleanWhitespace(this.update);
	      Element.cleanWhitespace(this.update.down());
	
	      if(this.update.firstChild && this.update.down().childNodes) {
	        this.entryCount = 
	          this.update.down().childNodes.length;
	        for (var i = 0; i < this.entryCount; i++) {
	          var entry = this.getEntry(i);
	          entry.autocompleteIndex = i;
	          this.addObservers(entry);
	        }
	      } else { 
	        this.entryCount = 0;
	      }
	
	      this.stopIndicator();
	      this.index = 0;
	      
	      if(this.entryCount==1 && this.options.autoSelect) {
	        this.selectEntry();
	        this.hide();
	      } else {
	        this.render();
	      }
	    }
	},
	
	//=========================================================================
	getUpdatedChoices:  function()  {
	    // If we've already send a request for one of these matches then there's
	    // no need to send another.
	
	    this.startIndicator();
	       
	    if( this.storedResult )  {
	      var token = this.getToken();
  
	      // Prueft ob Searchstring == Eingabe
	      if( this.storedRequest == token )  {
	        var node = this.buildShowedResults(this.storedResult, 10);
	        this.updateChoices( node.innerHTML );
	        try {
	          node.parentNode.removeChild(node);
	        } catch(e) {}
	        this.stopIndicator();
	        return;
	      }
	      // Prueft ob Searchstring schon im Cache liegt
	      else if(this.Requestcache[token.toLowerCase()]) {
        	if(this.Requestcache[token.toLowerCase()].replace (/^\s+/, '').replace (/\s+$/, '') != ''){
            	
        		var node = this.buildShowedResults(this.Requestcache[token.toLowerCase()], 10);
        		
        		this.updateChoices(node.innerHTML);
				
			   	try {
	          		node.parentNode.removeChild(node);
	        	} catch(e) {}
        	}
            this.stopIndicator();
            return;
          }          
          // Prueft ob Searchstring mit letzten angefragten String uebereinstimmt am Anfang
	      else if( token.indexOf(this.storedRequest) != -1 )  {
	        
	      	var tott = token.toLowerCase();
	      	var toct = this.Requestcache[token.toLowerCase()];
	      	var ct = token.indexOf(this.Requestcache[token.toLowerCase()]);
      	
	      	var node = this.buildShowedResults(this.storedResult, 0);
	      	
	        var list = node.getElementsByTagName("dl")[0];
	        var lis = list ? list.getElementsByTagName("dd") : [];
	
	        for(var ii=lis.length; ii>0; --ii) {
	          var item = lis[ (ii-1) ];
	          if(item.innerHTML.stripTags().toLowerCase().indexOf(
	              token.toLowerCase()) == -1) {
	            list.removeChild(item);
	          }
	        }			
	      		      	
	        //ablegen des gesamten TrefferStrings in Cache
	      	this.Requestcache[this.getToken().toLowerCase()] = node.innerHTML;
	        
	        lis = list.getElementsByTagName("dd");
	        if( lis.length > 10 ) {
	          for ( var i = lis.length; i > 10; --i ) {
	            list.removeChild(lis[i-1]);
	          }
	        }
	
	        this.updateChoices(node.innerHTML);
	        try {
	          node.parentNode.removeChild(node);
	        } catch(e) {}
	
	        // stop, i.e. return, only if the list is not empty.
	        if(lis.length > 0) {
	          	this.stopIndicator();
	        	return;
	        }
	      }
	    }
	
	    if(this.RequestFlag == false){
		    
	    	entry  =  encodeURIComponent(this.options.paramName)  +  '='  +
		              encodeURIComponent(this.getToken());
		
		    this.options.parameters  =  this.options.callback  ?
		     this.options.callback(this.element,  entry)  :  entry;
		
		    if(this.options.defaultParams)
		      this.options.parameters  +=  '&'  +  this.options.defaultParams;
		
		    //Parameter in lowerCase
	        this.options.parameters = this.options.parameters.toLowerCase();
		      
		    this.storedRequest  =  this.getToken();
		
		    var request = new Ajax.Request(this.url, this.options);
			
		    // setzt Flag da ein Request abgesendet wurde
		    this.RequestFlag = true;
		    
		    this.ajaxRequestStack.push(request);
	    }
	},
	
	//=========================================================================
	// simuliert verzoegertes Ausblenden der Trefferliste im Autocompleter
//	onBlur: function(event) {
//	    if( this.update.firstChild ) {
//	      try {
//	        this.selectEntry();
//	        this.update.innerHTML = "";
//	      } catch(e){}
//	      setTimeout(this.hide.bind(this), 250);
//	    }
//	    this.hasFocus = false;
//	    this.active = false;
//	},
	
	//=========================================================================
	onComplete: function(request)  {
		if( request.status == "200" ) {
			if(request.responseText.replace(/^\s+/, '').replace(/\s+$/, '') != ''){
	      		this.storedResult  =  request.responseText;
				
	      		//ablegen des gesamten Request in Cache
	      		this.Requestcache[this.storedRequest.toLowerCase()] = this.storedResult;
				
	      		var token = this.getToken();
			        
		      	var tott = token.toLowerCase();
		      	var toct = this.Requestcache[token.toLowerCase()];
		      	var ct = token.indexOf(this.Requestcache[token.toLowerCase()]);
		      	
		      	var node = this.buildShowedResults(this.storedResult, 0);
			      		      	
		        var list = node.getElementsByTagName("dl")[0];
		        var lis = list ? list.getElementsByTagName("dd") : [];
			
		        for(var ii=lis.length; ii>0; --ii) {
		          var item = lis[ (ii-1) ];
		          if(item.innerHTML.stripTags().toLowerCase().indexOf(
		              token.toLowerCase()) == -1) {
		            list.removeChild(item);
		          }
		        }			
			        
		        //ablegen des gesamten TrefferStrings in Cache
		      	this.Requestcache[this.getToken().toLowerCase()] = node.innerHTML;
			        
		        lis = list.getElementsByTagName("dd");
		        if( lis.length > 10 ) {
		          for ( var i = lis.length; i > 10; --i ) {
		            list.removeChild(lis[i-1]);
		          }
		        }
			
		        this.updateChoices(node.innerHTML);
			
		        try {
	          		node.parentNode.removeChild(node);
	        	} catch(e) {}

	        	// stop, i.e. return, only if the list is not empty.
			    if(lis.length > 0) {
			      	this.stopIndicator();
			    }	        	
			   	
			}else{
		    	this.storedResult = null;
				this.stopIndicator();
		    }
		    	
			// setzt Flag das Request beendet wurde
			this.RequestFlag = false;
			
		}
	}
});


// Erweitert den HTML-Code um ein Element
// @autor: kuehnj
// @date: 24.07.2008
var Tag={isIE:navigator.appVersion.match(/\bMSIE\b/),factoryDiv:null}

Tag.Node=function(){
	return Builder.node.apply(Builder,arguments);
}
Tag.Base=function(name,options){
	return $(Builder.node(name,options));
}
Tag.Content=function(name,content,options){
	var tag;
	tag=Tag.Base(name,options);
	if(content!=null){
		if(content instanceof Array){
			content.each(function(v){tag.appendChild(v);});
		}else{ 
			if(typeof content=="object"){
				tag.appendChild(content);
			}
		}
	}else{
		tag.innerHTML=content;
	}
	return tag;
}

function markText(q, searchString){
//	q = searchString.substring(searchString.indexOf('q=')+2, searchString.indexOf('&')).split('+');
	
	var rxi = new RegExp(q, 'gi');
	var matchedString = searchString.match(rxi);
	
	if(matchedString != null){
	
		matchedString = matchedString.array_unique();
		
		for(i=0;i<matchedString.length;i++){
			
			var rx = new RegExp(matchedString[i], 'g');
			searchString = searchString.replace(rx, '<b>'+matchedString[i]+'</b>');
		}
	}
	
	return searchString;
}

// Diese Methode loescht alle gleichen Werte aus einem Array.
// @autor: kuehnj
// @date: 24.07.2008
Array.prototype.array_unique = function () {

	var value = index = [];

	for (var x = 0; x < this.length; ++x) {

		if (index[this[x]] == null) {

			value[value.length] = this[x];

		} index[this[x]] = this[x];

	} return value;
};

/*
 * Fabtabulous! Simple tabs using Prototype
 * http://tetlaw.id.au/view/blog/fabtabulous-simple-tabs-using-prototype/
 * Andrew Tetlaw
 * version 1.1 2006-05-06
 * http://creativecommons.org/licenses/by-sa/2.5/
 */
var Fabtabs = Class.create();

Fabtabs.prototype = {
	initialize : function(element) {
		this.element = $(element);
		var options = Object.extend({}, arguments[1] || {});
		this.menu = $A(this.element.getElementsByTagName('a'));
		this.menu_li = $A(this.element.getElementsByTagName('li'));
		
		this.show(this.getInitialTab());
		
		this.menu.each(this.setupTab.bind(this));
	},
	setupTab : function(elm) {
		Event.observe(elm,'click',this.activate.bindAsEventListener(this),false)
	},
	activate :  function(ev) {
		var elm = Event.findElement(ev, "a");
		Event.stop(ev);
		this.show(elm);
		this.menu.without(elm).each(this.hide.bind(this));
	},
	hide : function(elm) {
		$(elm).removeClassName('selected');
		//$(this.tabID(elm)).removeClassName('active-tab-body');
	},
	show : function(elm) {
		// <li class="selected"><b>Route 1</b></li>
		// LinkTag holen
		var linktag = $(elm).firstChild.textContent;
		$(elm).addClassName('selected');
		$(elm).firstChild.remove;
		$(elm).firstChild.childElements('b');
		$(elm).firstChild.textContent = linktag;
		//$(this.tabID(elm)).addClassName('active-tab-body');

	},
	tabID : function(elm) {
		//elm.getElementsByTageName('a');
		
		return elm.href.match(/#(\w.+)/)[1];
	},
	getInitialTab : function() {
		// Trennt den Anker aus der URL heraus
		if(document.location.href.match(/#(\w.+)/)) {
			var loc = RegExp.$1;
			var elm = this.menu.find(function(value) { return value.href.match(/#(\w.+)/)[1] == loc; });
			return elm || this.menu.first();
		} else {
			return this.menu_li.first();
		}
	}
}

//Event.observe(window,'load',function(){ new Fabtabs('tab_routes'); },false);

//onSuccess: function(t) { t.responseText.evalScripts(); }