// Customizable variables
if (CalendarBaseUrl == undefined) {
	var CalendarBaseUrl = '';
}



//---------BEGIN KLASSE brainCalendar --------------------------------------------------------------------


/**
 *  Konstruktor
 *  @param string instanceName
 *  @param string datePreSelect
 *  @param string dspDateMask
 */
function CBrainCalendar(instanceName, datePreSelect, dspDateMask){
	
	//debug mode ja/nein
	this.debug 		    = false;
	this.imgPath		= CalendarBaseUrl+'/common/icons/';
	this.orginalName	= instanceName;
	this.instanceName   = correctInstanceName(instanceName);
	this.date           = new Date();

	this.baseDateMask   = 'yyyy-mm-dd';
	this.dspDateMask    = 'dd.mm.yyyy';
	this.zIndex	        = 101;
	this.prependNull	= true;
	this.textAttribs    = '';
	this.markColor		= '#ddd';
	this.todayStyle		= 'border: 1px solid darkred;';
	this.weekdayNames	= new Array('Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.', 'So.');
	this.monthNames		= new Array('Januar', 'Februar', 'März', 'April', 'Mai',
									'Juni', 'Juli', 'August', 'September', 'Oktober',
									'November', 'Dezember');
	this.closeText      = 'schlie&szlig;en';
	this.preSelected    = (String(datePreSelect)=="undefined")? '' : datePreSelect;
	
	//seperator bestimmen
	var sep = String(this.dspDateMask);
	sep = sep.replace( /yyyy/, '');
	sep = sep.replace( /mm/, '');
	sep = sep.replace( /dd/, '');
	this.allowedSep		= sep.charAt(0); //nur ein seperator wird berücksichtigt
	
	//maske
	this.dspMask        = (String(dspDateMask)=="undefined")? '':dspDateMask;
	if(this.dspMask.length>0){
		this.dspMask = String(dspDateMask).toLowerCase;
	}
	
	//erweiterung fuer url-calendar, default setzen
	this.withTextField  = true;
	this.urlRedirectTo	= "";
	this.skinName		= "";
	
	//scroller erweiterung
	this.scroller = {
		step 		: 5,			//anzahl vor und nach aktuellem Jahr
		speed 		: 125,			//scroll-geschwindigkeit
		timerFunc	: null,
		value		: this.date.getFullYear()-5,
		id			: "DIMID_"+this.instanceName+"_directSelect",
		outId		: "DIMID_"+this.instanceName+"_directSelect_content",
		type		: null,
		imgDim		: {w:9, h:5}
	};
}
/**
 *  verkuerzte "document.getElementById(...)" variante 
 */
CBrainCalendar.prototype.$ = function(element){
	if(typeof element == "string"){
		return document.getElementById(element);
	}
	else if(typeof element == "object" ){
		return element;
	}
	return false;
}
/**
 * set parameter
 */
CBrainCalendar.prototype.setParameter = function(name, value)
{
	eval("this['"+name+"'] = '"+value+"'");
}
/**
 *	interne Datumsvariable updaten
 */
CBrainCalendar.prototype.setDate = function(jahr, monat, tag){
	this.date = new Date(jahr, monat, tag);
}
/**
 *  einen tag auswählen
 */
CBrainCalendar.prototype.pickDay = function(day){
	this.setDate(this.date.getFullYear(), this.date.getMonth(), day);
	if(this.urlRedirectTo==""){
		this.notifyControls(1);
		this.hideCalendar();
	}
	else{
		this.notifyControls(3);
	}
}
/**
 *  einen monat vor
 */
CBrainCalendar.prototype.nextMonth = function(){
	var dspToday= new Date();
	var day = 1;
	//heute als preselect
	if(dspToday.getMonth()==(this.date.getMonth()+1) && dspToday.getFullYear()==this.date.getFullYear()){
		day = dspToday.getDate();
	}
	this.setDate(this.date.getFullYear(), (this.date.getMonth()+1), day);
	this.updateCalendar();
}
/**
 *  einen monat zurück
 */
CBrainCalendar.prototype.prevMonth = function(){
	var dspToday= new Date();
	var day = 1;
	//heute als preselect
	if(dspToday.getMonth()==(this.date.getMonth()-1) && dspToday.getFullYear()==this.date.getFullYear()){
		day = dspToday.getDate();
	}
	this.setDate(this.date.getFullYear(), (this.date.getMonth()-1), day);
	this.updateCalendar();
}
/**
 *  ein jahr vor
 */
CBrainCalendar.prototype.nextYear = function(){
	var dspToday= new Date();
	var day = 1;
	//heute als preselect
	if(dspToday.getMonth()==this.date.getMonth() && dspToday.getFullYear()==(this.date.getFullYear()+1)){
		day = dspToday.getDate();
	}
	this.setDate((this.date.getFullYear()+1), this.date.getMonth(), day);
	this.updateCalendar();
}
/**
 *  ein jahr zurück
 */
CBrainCalendar.prototype.prevYear = function(){
	var dspToday= new Date();
	var day = 1;
	//heute als preselect
	if(dspToday.getMonth()==this.date.getMonth() && dspToday.getFullYear()==(this.date.getFullYear()-1)){
		day = dspToday.getDate();
	}
	this.setDate((this.date.getFullYear()-1), this.date.getMonth(), day);
	this.updateCalendar();	
}
/**
 * document write darf nur 1x vorgenommen werden
 */
CBrainCalendar.prototype.create = function(){
	document.write( this.createHtml() ) ;
	if(this.urlRedirectTo!=""){
		this.updateCalendar();
	}
}
/**
 *	html code des controls
 */
CBrainCalendar.prototype.createHtml = function(){
	//Check for errors
	if ( !this.instanceName || this.instanceName.length == 0 ){
		this.msg("createHtml", "no instance name is given!");
		return '' ;
	}
	//bei vorauswahl des datums
	var value_base = "";
	var value_dsp = "";
	if(this.preSelected.length>0){
		var dateArray = this.preSelected.split(this.allowedSep);
		var parsedMask= this.parseMask(this.dspDateMask);
		this.setDate(dateArray[parsedMask.y], dateArray[parsedMask.m]-1, dateArray[parsedMask.d]);
		value_base = this.buildBaseDate();
		value_dsp  = this.buildDisplayDate();
	}
	//save handling of thext attribute
	this.textAttribs = String(this.textAttribs);
	if(this.textAttribs=="undefined"){ 
		this.textAttribs="";
	}
	//genieriere html code des controls
	var html = "";
	var ext = ".png";
	if (typeof document.body.style.maxHeight == "undefined" && this.urlRedirectTo==""){
		ext = ".gif";
	} 
	html+="<input type=\"hidden\" name=\"baseDate_"+this.orginalName+"\" id=\"DOMID_"+this.instanceName+"_baseDate\" value=\""+value_base+"\"/>\n";
	//textfeld wenn gewuenscht
	if(this.withTextField==true){
		html +="<input type=\"text\" name=\""+this.orginalName+"\" id=\"DOMID_"+this.instanceName+"\" value=\""+value_dsp+"\""
			+" onkeyup=\""+this.instanceName+"_Object.cutInput(this);\" "
			+this.textAttribs
			+" />\n";
	}
	//claendar icon
	if(this.urlRedirectTo == ""){
		html+="<img src=\""+this.imgPath+"calendar_icon.jpg\" width=\"16\" height=\"15\" "
			+"border=\"0\" id=\"DOMID_calImg_"+this.instanceName+"\" "
			+"onclick=\""+this.instanceName+"_Object.updateCalendar(this, event);\" "
			+"style=\"cursor:pointer;\" />";
	}
	//direct select jahr/monat  
	html+="<div id=\""+this.scroller.id+"\" class=\""+this.skinName+"bainCalendar_directSelect\" style=\"display:none;z-index:"+(this.zIndex+1)+";\" onmouseout=\"javascript:"+this.instanceName+"_Object.hideDirectSelect(event,this);\" onmouseover=\"javascript:"+this.instanceName+"_Object.keepOpenDirectSelect();\"></div>";
	//outer calendar div
	html+="<div id=\"DOMID_"+this.instanceName+"_cal\" class=\""+this.skinName+"divBox_cal\" "
			+"style=\"display:"
			+ ((this.urlRedirectTo=="")? "none" : "block")
			+";z-index:"+this.zIndex+";\">"
	html+="<div id=\"DOMID_"+this.instanceName+"_calHeader\" class=\""+this.skinName+"brainCalendar_skin_top\" style=\"background:url("+this.imgPath+"calendar_head"+ext+") no-repeat;\"></div>";
	html+="<div id=\"DOMID_"+this.instanceName+"_calMiddle\" class=\""+this.skinName+"brainCalendar_skin_middle\" style=\"background:url("+this.imgPath+"calendar_middle"+ext+") repeat-y;\"></div>";
	html+="<div id=\"DOMID_"+this.instanceName+"_calFooter\" class=\""+this.skinName+"brainCalendar_skin_footer\" style=\"background:url("+this.imgPath+"calendar_foot"+ext+") no-repeat;\">&nbsp;</div>";
	html+= "</div>\n";
	if(this.debug==true){
		html+="<textarea id=\"DOMID_"+this.instanceName+"_debug\" style=\"width:100%;height:300px;\"></textarea>";
	}
	return html;
}
/**
 *	generiere Calendar-htmlcode zum gegebenen Datum
 */
CBrainCalendar.prototype.buildCalendar = function()
{
	//internes datum
	var monat = this.date.getMonth();
	var jahr  = this.date.getFullYear();
	var tag   = this.date.getDate();
	
	//display
	var dspDate = new Date(jahr, monat, 1);
	var maxtage = this.daysInMonth(monat, jahr);
	var erster  = dspDate.getDay();
	
	//js-weekday startet bei 1 (Mo.) und endet auf 0 (So.)
	if(erster==0){  //So. nach js notation
		erster=7;	//So. nach brainCalendar Notation
	}
	var rows  = 5;	//normalerweise reichen  5 zeilen
	//wenn monat 31 tage und 1. des monats bei Sa. oder So. beginnt
	//wenn monat 30 tage und 1. des monats bei So. beginnt
	//6 zeilen
	if( (maxtage==31 && erster>5) || (maxtage==30 && erster==7) ){
		rows = 6;
	}
	var dspToday= new Date();
	var todayD  = dspToday.getDate();
	var todayM  = dspToday.getMonth();
	var todayY  = dspToday.getFullYear();
	
	//ie6 und pngs :-(
	var ext = ".png";
	if (typeof document.body.style.maxHeight == "undefined" && this.urlRedirectTo==""){
		ext = ".gif";
	} 
	var header = "";
	var middle = "";
	
	//wenn modul, kein close button
	if(this.urlRedirectTo==""){
	   header+="<div class=\""+this.skinName+"brainCalendar_close\">"
	   	 +"<a href=\"javascript:"+this.instanceName+"_Object.hideCalendar();\" rel=\"nofollow\">"
	     +"<img src=\""+this.imgPath+"calendar_close"+ext+"\" width=\"12\" height=\"10\" border=\"0\" alt=\""+this.closeText+"\"/></a>"
	     +"</div>"
	}
	header+="<table class=\""+this.skinName+"brainCalendar "+this.skinName+"tablehead\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n"
	  +"<tr>\n"
	  +"<td align=\"right\" class=\""+this.skinName+"scroller\" onmousedown=\"javascript:"+this.instanceName+"_Object.prevMonth();\" rel=\"nofollow\">"
	  +"<img src=\""+this.imgPath+"calendar_prev.gif\" width=\"5\" height=\"9\" border=\"0\"/>"
	  +"</td>\n"
	  +"<td align=\"center\" class=\""+this.skinName+"heading\" onmousedown=\"javascript:"+this.instanceName+"_Object.openDirectSelect(event, 'month');\" rel=\"nofollow\">"+this.monthNames[monat]+"</td>\n"
	  +"<td  align=\"left\" class=\""+this.skinName+"scroller\" onmousedown=\"javascript:"+this.instanceName+"_Object.nextMonth();\" rel=\"nofollow\">"
	  +"<img src=\""+this.imgPath+"calendar_next.gif\" width=\"5\" height=\"9\" border=\"0\"/>"
	  +"</td>\n"
	  +"</tr>\n"
	  +"<tr>\n"
	  +"<td align=\"right\" class=\""+this.skinName+"scroller\" onmousedown=\"javascript:"+this.instanceName+"_Object.prevYear();\" rel=\"nofollow\">"
	  +"<img src=\""+this.imgPath+"calendar_prev_fb.gif\" width=\"10\" height=\"9\" border=\"0\"/>"
	  +"</td>\n"
	  +"<td align=\"center\" class=\""+this.skinName+"heading\" onmousedown=\"javascript:"+this.instanceName+"_Object.openDirectSelect(event, 'year');\" rel=\"nofollow\">"+jahr+"</td>\n"
	  +"<td align=\"left\" class=\""+this.skinName+"scroller\" onmousedown=\"javascript:"+this.instanceName+"_Object.nextYear();\"  rel=\"nofollow\">"
	  +"<img src=\""+this.imgPath+"calendar_next_ff.gif\" width=\"10\" height=\"9\" border=\"0\"/>"
	  +"</td>"
	  +"</tr>"
	  +"</table>";

	//replace header content	 
	document.getElementById("DOMID_"+this.instanceName+"_calHeader").innerHTML = header;
	 
	//mittlerer part
	middle="<table class=\""+this.skinName+"brainCalendar\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">\n"
	  +"<tr>\n";
	//wochentage
	for(i=0; i<this.weekdayNames.length; i++){
		middle+="<td class=\""+this.skinName+"weekdayNames\">"+this.weekdayNames[i]+"</td>\n"
	}
	middle+="</tr>\n";
	//alle monatstage
	var dayCounter = 1;
	for(i=1; i<=rows; i++){
		middle+="<tr>\n";
		for(j=1; j<=7; j++){
			if( (i==1 && j<erster) || dayCounter>maxtage){	//leere zellen
				middle+="<td>&nbsp;</td>\n";	
			}
			else{ 
				var css_class = "weekday";
				var mouseevents = " onmouseover=\"beforCol = this.style.backgroundColor;this.style.backgroundColor='"+this.markColor+"';\" ";
					mouseevents+= " onmouseout=\"this.style.backgroundColor=beforCol;\"";
					mouseevents+= " onclick=\"javascript:"+this.instanceName+"_Object.pickDay('"+dayCounter+"');\" rel=\"nofollow\"";
			
				if(dayCounter == tag){
					css_class = "weekday_current";
				}
				if(todayD==dayCounter && todayM==monat && todayY==jahr){
					css_class = "weekday_today";
				}
				middle+="<td class=\""+this.skinName+css_class+"\""+mouseevents+">"+dayCounter+"</td>\n";
				dayCounter++;
			}
		}
		middle+="</tr>\n";
	}
	middle+="</table>";
	document.getElementById("DOMID_"+this.instanceName+"_calMiddle").innerHTML = middle;
}

/**
 * generiere calendar control content neu
 *
 * @param [optional] image pointer = update durch klick auf das calendar icon
 * @param [optional] event router
 */
CBrainCalendar.prototype.updateCalendar = function(img, evnt){
	//finde calendar obj im dom baum
	var divElem = document.getElementById("DOMID_"+this.instanceName+"_cal");
	if(!divElem){
		this.msg("openCalendar", "calendar output div not found!");
		return false;
	}
	//erzeuge neuen content
	this.buildCalendar();
	if(img && evnt){
		this.openAtMousePos(evnt, divElem);
	}
	this.showCalendar();	
}		
/**
 *	pruefe ob calender div angezeigt wird oder nicht
 */
CBrainCalendar.prototype.isCalendarOpen = function(){
	var divElem = document.getElementById("DOMID_"+this.instanceName+"_cal");
	if( !divElem )
		return false;
	if(divElem.style.display=='none')
		return false;
	if(divElem.style.display=='block')
		return true;
}
/**
 *	verstecke calender div
 */
CBrainCalendar.prototype.hideCalendar = function(){
	if(this.isCalendarOpen()==true){
		document.getElementById("DOMID_"+this.instanceName+"_cal").style.display="none";
		this.killDirectSelect();
	}	
}
/**
 *	zeige calender div
 */
CBrainCalendar.prototype.showCalendar = function(){
	if(this.isCalendarOpen()==false){
		var calDiv = document.getElementById("DOMID_"+this.instanceName+"_cal");
		if(calDiv){
			calDiv.style.display="block";
		}
	}	
}
/**
 *	update alle verbundenen controls in abhaengigkeit des senders
 *  @param int notifier = sender 1=cal, 2=text input
 */
CBrainCalendar.prototype.notifyControls = function( notifier ){
	switch(notifier)
	{
		case 1: //calendar wird geschlossen
			if(this.withTextField==true){
				document.getElementById("DOMID_"+this.instanceName).value = this.buildDisplayDate();
				document.getElementById("DOMID_"+this.instanceName+"_baseDate").value = this.buildBaseDate();
			}
			break;
		case 2:	//calendar soll geoeffnet bleiben
			if(this.withTextField==true){
				document.getElementById("DOMID_"+this.instanceName).value = this.buildDisplayDate();
				document.getElementById("DOMID_"+this.instanceName+"_baseDate").value = this.buildBaseDate();
			}
			if( this.isCalendarOpen() ) {
				this.updateCalendar();
			}
			break;
		case 3: //url-redirect
			if(this.urlRedirectTo!=""){
				window.location.href = this.urlRedirectTo+this.buildBaseDate();
			}
			break;
	}
}
/**
 * oeffnet ein element an der aktuellen mausposition
 *
 * @param object evnt, window.event objekt
 * @param object obj, DOM-element
 * @param integer offsetLeft, Verschiebung nach Links
 * @param integer offsetTop, Verschiebung nach Oben
 */
CBrainCalendar.prototype.openAtMousePos = function (evnt, obj, offsetLeft, offsetTop){

	offsetLeft = ((offsetLeft)? offsetLeft+0 : 0);
	offsetTop  = ((offsetTop)?  offsetTop+0  : 0);
	
	var pos = this.getCurrentMousePos(evnt);
	obj.style.position = "absolute";
	obj.style.left = pos.x + offsetLeft + "px";
	obj.style.top  = pos.y + offsetTop + "px";
	obj.style.display="block";
}
/**
 * mouseposition handler 
 */
CBrainCalendar.prototype.getCurrentMousePos = function(evnt){
  	var pos = {x: evnt.clientX, y: evnt.clientY};
	var body =(window.document.compatMode && window.document.compatMode=="CSS1Compat")? window.document.documentElement : window.document.body||null;
	if (body){
        pos.x+=body.scrollLeft;
        pos.y+=body.scrollTop;
    }
	return pos;
}
/**
 *  bereinigen eines elements
 */
CBrainCalendar.prototype._removeAll = function(element){
	if(element){
		element.innerHTML = "";
	}
}
/**
 * entfernen aller leerzeichen
 */
CBrainCalendar.prototype.deleteWhitespaces = function(s){
	var z = "";
	for(i=0; i<s.length;i++){
		var c = s.charAt(i);
		if( c != " " )
			z += c;
	}
	return z;
}
/**
 *  eingaben beschneiden
 */
CBrainCalendar.prototype.cutInput = function(inputfield){
	var dateStr = "";
	var pos = this.parseMask(this.dspDateMask);
	var y = "";
	var m = "";
	var d = "";
	var sepcount = 0;	
	for(i=0;i<inputfield.value.length;i++){
		var c = inputfield.value.charAt(i);
		if( c == this.allowedSep ){
			if(sepcount<2 && inputfield.value.charAt(i-1)!=this.allowedSep){
				sepcount++;
				dateStr+=c;
			}
		}
		else if( pos.d == sepcount ){
			if( d.length<2 ){
				d+=c;
				dateStr+=c;
			}		
		}
		else if( pos.m == sepcount ){
			if( m.length<2){
				m+=c;
				dateStr+=c;
			}
		}
		else if( pos.y == sepcount ){
			if(y.length<4){
				y+=c;
				dateStr+=c;
			}
		}
	}
	inputfield.value = dateStr;
	if( (d.length>0 && d.length<=2) && (m.length>0 && m.length<=2) && y.length==4 ){
		this.setDate(Number(y), (Number(m)-1), Number(d));
		this.notifyControls(2);
	}
	else{
		this.date = new Date();
		document.getElementById("DOMID_"+this.instanceName+"_baseDate").value = "";
	}
}
/**
 *  Reihenfolge anhand der Datumsmaske bestimmen
 */
CBrainCalendar.prototype.parseMask = function(maskStr){
	var pos = new Object();
	if( maskStr.indexOf('y')==0 ){ //führendes jahr
		pos.y = 0;
		m = maskStr.indexOf('m');
		d = maskStr.indexOf('d');
		if( m<d ){	//dann monat, danach tag
			pos.m = 1;
			pos.d = 2;
		}			
		else{		//dann tag, danach monat
			pos.m = 2;
			pos.d = 1;
		}
	}
	if( maskStr.indexOf('m')==0 ){ //führender monat
		pos.m = 0;
		y = maskStr.indexOf('y');
		d = maskStr.indexOf('d');
		if( y<d ){	//dann jahr, danach tag
			pos.y = 1;
			pos.d = 2;
		}			
		else{		//dann tag, danach jahr
			pos.y = 2;
			pos.d = 1;
		}
	}
	if( maskStr.indexOf('d')==0 ){ //führender tag
		pos.d = 0;
		y = maskStr.indexOf('y');
		m = maskStr.indexOf('m');
		if( y<m ){	//dann jahr, danach monat
			pos.y = 1;
			pos.m = 2;
		}			
		else{		//dann monat, danach jahr
			pos.y = 2;
			pos.m = 1;
		}
	}
	return pos;
}
/**
 *	gibt die anzahl der tage im gegebenen monat/jahr zurück
 *	erwartet monat js-typisch 0-11!
 */
CBrainCalendar.prototype.daysInMonth = function(monat, jahr){
	var feb = 28;
	if( monat==1 && (jahr%400==0 || jahr%4==0) ){
		feb = 29;
	}
	var daysInMonth = new Array(31, feb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	return daysInMonth[monat];
}
/**
 *	baut Zeichenkette anhand der gegebenen FormatMaske
 */
CBrainCalendar.prototype.buildDateFromMask = function(mask){
	var dateString = mask;
	var tag   = ((this.prependNull==true && this.date.getDate()<10)? "0"+this.date.getDate() : this.date.getDate());
	var monat = (((this.prependNull==true && this.date.getMonth()+1)<10)? "0"+(this.date.getMonth()+1) : (this.date.getMonth()+1));
	var jahr  = this.date.getFullYear();
	
	//benutze regular expression um die maske durch die datumsbestandteile zu ersetzen 
	dateString = dateString.replace(/yyyy/, jahr);
	dateString = dateString.replace(/mm/, monat);
	dateString = dateString.replace(/dd/, tag);
	return dateString;	
}
/**
 *	baut Zeichenkette des Anzeige Datums
 */
CBrainCalendar.prototype.buildDisplayDate = function(){
	return this.buildDateFromMask(this.dspDateMask);
}
/**
 *	baut Zeichenkette des Base Datums
 */
CBrainCalendar.prototype.buildBaseDate = function(){
	return this.buildDateFromMask(this.baseDateMask);
}
/**
 *  oeffnen des scrollers
 *  @param object e, event
 *  @param string what, "year" oder "month"
 */
CBrainCalendar.prototype.openDirectSelect= function(e, what){
	var s = this.$(this.scroller.id);
	if(s){
		this.scroller.type = what;
		this._removeAll(s);
		if(this.scroller.type=="year"){
			this.scroller.value = this.date.getFullYear()-this.scroller.step;
			this.appendDirectSelectScroller(s, 'up');
		}
		var div = document.createElement("div");
		div.id = this.scroller.outId;
		s.appendChild(div);
		if(this.scroller.type=="year"){
			this.appendDirectSelectScroller(s, 'down');
		}
		this.updateDirectSelectScroller('current');
		s.style.display="block";
		if(this.scroller.type=="year")
			this.openAtMousePos(e,s,10,10);
		else
			this.openAtMousePos(e,s,10,10);
	}	
}
/**
 *  offen halten des scrollers
 */
CBrainCalendar.prototype.keepOpenDirectSelect= function(){
	var s = this.$(this.scroller.id);
	if(s){
		s.style.display="block";
	}
}
/**
 *	bereinigen und schliessen des scrollers
 */
CBrainCalendar.prototype.killDirectSelect= function(){
	this.stopScrollingDirectSelect();
	this._removeAll(this.$(this.scroller.outId));
	var s = this.$(this.scroller.id);
	if(s){
		s.style.display="none";
		this._removeAll(s);
	}
}
/**
 *  intelligente methode zum schliessen des scroller divs
 */
CBrainCalendar.prototype.hideDirectSelect = function(event_){
	if(!this.inEventBubble(event_, this.$(this.scroller.id))){
		this.killDirectSelect();
	}
}
/**
 *  scroll up, startet timer function
 */
CBrainCalendar.prototype.scrollUpDirectSelect = function(){
	this.scroller.value--;
	this.updateDirectSelectScroller('up');	
	this.scroller.timerFunc = window.setTimeout(this.instanceName+"_Object.scrollUpDirectSelect();", this.scroller.speed);
}
/**
 *  scroll down, startet timer function
 */
CBrainCalendar.prototype.scrollDownDirectSelect = function(){
	this.scroller.value++;
	this.updateDirectSelectScroller('down');
	this.scroller.timerFunc = window.setTimeout(this.instanceName+"_Object.scrollDownDirectSelect();", this.scroller.speed);
}
/**
 *  reset des scrolling events  
 */
CBrainCalendar.prototype.stopScrollingDirectSelect = function(){
	window.clearTimeout(this.scroller.timerFunc);
}
/**
 *  update des scroller-contents
 *  @param string dir, scrolling-richtung
 */
CBrainCalendar.prototype.updateDirectSelectScroller = function(dir){
	var o = this.$(this.scroller.outId);
	if(o){
		this._removeAll(o);
		var options = this.getOptionsForSelect(dir);
		for(i=0;i<options.length;i++){
			var css_class = "bainCalendar_directSelect_item";
			var js = "javascript:"+this.instanceName+"_Object.handleSelect(";
			if(this.scroller.type=='year'){
				js += options[i] +","+(this.date.getMonth())+","+this.date.getDate();
				if(options[i]==this.date.getFullYear()){
					css_class = "bainCalendar_directSelect_itemCurrent";
				}
			}
			else if(this.scroller.type=='month'){
				js += this.date.getFullYear()+","+i+","+this.date.getDate();
				if(i==this.date.getMonth()){
					css_class = "bainCalendar_directSelect_itemCurrent";
				}
			}
			else{
				js += this.date.getFullYear()+","+(this.date.getMonth()+1)+","+this.date.getDate();
			}
			js += ");"
			var a = document.createElement("a");
			a.className = this.skinName+css_class;
			a.href = js;
			a.id = "link"+options[j];
			a.rel = "nofollow";	
			var t = document.createTextNode(options[i]);
			a.appendChild(t);
			o.appendChild(a);
		}
	}
	else{
		this.killDirectSelect();
	}
}
/**
 *  erzeugt ein options array fuer direct select
 *  @param string dir, direction (up || down|| current)
 */
CBrainCalendar.prototype.getOptionsForSelect = function(dir){
	//---fill select with wanted data
	var options = new Array();
	if(this.scroller.type == 'month'){
		options = this.monthNames;
	}
	else if(this.scroller.type == 'year'){
		if(dir == 'down'){
			for(var i=this.scroller.value; i<(this.scroller.step*2+1+this.scroller.value); i++){
				options.push( i );
			}
		}
		else if( dir=='up'){
			for(var i=this.scroller.value; i<(this.scroller.step*2+1+this.scroller.value); i++){
				options.push( i );
			}
		}
		else if( dir == 'current' ){
			for(var i=this.scroller.value; i<(this.scroller.step*2+1+this.scroller.value); i++){
				options.push( i );
			}
		}
	}
	return options;
}
/**
 *  erzeugt ein options array fuer direct select
 *
 *  @param string what, jahr, monat...
 *  @param string dir, direction (up || down)
 */
CBrainCalendar.prototype.appendDirectSelectScroller = function(elem, dir){
	if(!elem) return;
	var img = document.createElement("img");
		img.width  = this.scroller.imgDim.w;
		img.height = this.scroller.imgDim.h;
		img.border = 0;
		img.alt    = "";
	var a = document.createElement("a");
		a.className= this.skinName+"bainCalendar_directSelect_scroller";
		a.href = "#";
		a.rel  = "nofollow";
		a.onmouseout = new Function(this.instanceName+"_Object.stopScrollingDirectSelect()");
	if(dir == 'up'){
		a.id = "DOMID_"+this.instanceName+"_scrollerUp";
		img.src = this.imgPath+"calendar_up.gif";
		a.onmouseover = new Function(this.instanceName+"_Object.scrollUpDirectSelect()");
	}
	else if(dir == 'down'){
		a.id = "DOMID_"+this.instanceName+"_scrollerDown";
		img.src = this.imgPath+"calendar_down.gif";
		a.onmouseover = new Function(this.instanceName+"_Object.scrollDownDirectSelect()");
	}
	a.appendChild(img);
	elem.appendChild(a);
}
/**
 * direkte Auswahlliste der naechsten/vorherigen Jahre bzw. Monate 
 */
CBrainCalendar.prototype.handleSelect = function(y,m,d){
	var divElem = this.$(this.scroller.id);
	if(divElem){
		divElem.innerHTML ="";
		divElem.style.display="none";;
		this.setDate(y,m,d)
		this.updateCalendar();
	}
}
/**
 *	hilfsfunktion fuer event bubbling
 *
 *  prueft ob event auf ein bestimmtes element wirkt oder nicht
 *  @param object event_
 *	@param object elem
 *
 */
CBrainCalendar.prototype.inEventBubble = function(event_, elem){
	try{
		if (!event_) var event_ = window.event;
		var reltg = (event_.relatedTarget) ? event_.relatedTarget : event_.toElement;
		while (reltg && reltg != elem && reltg.nodeName != 'BODY'){
			reltg=reltg.parentNode;
		}
		if(elem==reltg) return true; 
		else return false;
	}
	catch(ex){
	}
	return false;
}
/**
 *	Meldungstexte nur ueber definierte Schnittstelle senden
 */
CBrainCalendar.prototype.msg = function(where, text){
	if(this.debug){
		var msg = "";
		msg +="-------------------------------------------------\n"
			+ "Class::CBrainCalendar\n"
			+ "-------------------------------------------------\n"
			+ "Instance: "+this.instanceName+"\n"
			+ "Method: "+where+"\n"
			+ "Meldung: "+text+"\n";
		document.getElementById("DOMID_"+this.instanceName+"_debug").value+=msg;
	}
}
//---------ENDE KLASSE brainCalendar --------------------------------------------------------------------


/**
 *  Korrektur des instanznamens, brain Vereinbarung:
 *	ersetze alle "[" bzw. "]" im dem InstanzNamen durch "_" ,
 *	schließendes "]" wird ersatzlos entfernt
 */
function correctInstanceName(instanceName)
{
	var name = String(instanceName);
	if(name.length<=0){
		alert("correctInstanceName::no valid instanceName given!");
		return "";
	}
	//array handling ist leichter als string handling 
	var newName = new Array();
	for(i=0; i<name.length; i++){
		var c = name.charAt(i);
		//ersetzungen
		if(c == "["){
			newName.push("_");
		}
		else{
			if(c != "]"){
				newName.push(c);
			}
		}
	}
	return String(newName.join(""));
}


/**
 * main-Funktion zum Aufbau des DateControls, Nutzung der Klassen brainCalendar
 *
 * @param string instanceName = eineindeutiger Name der brainCalendar Instanz
 * @param [optional] string preSelectedDate = Datumsvorauswahl
 * @param [optional] string dateFormatMask = Format Maske für das Anzeigedatum, Bsp: "dd.mm.yyyy"
 * @param [optional] string htmlAttr = html Attribute des eingabe-text-feldes
 */
function DateInput(instanceName, preSelectedDate, dateFormatMask, htmlAttr)
{
	var instanceNameObj = correctInstanceName(instanceName);
	eval(instanceNameObj + '_Object=new CBrainCalendar(\''+instanceName+'\',\''+preSelectedDate+'\',\''+dateFormatMask+'\');');
	eval(instanceNameObj + '_Object.setParameter(\'textAttribs\', \''+htmlAttr+'\');');
	eval(instanceNameObj + '_Object.create();');
}

/**
 * main-Funktion zum Aufbau des DateControls fuer das Modul Calendar, Nutzung der Klassen brainCalendar
 *
 * @param string instanceName = eineindeutiger Name der brainCalendar Instanz
 * @param string url = aufzurufende URL
 * @param [optional] string preSelectedDate = Datumsvorauswahl
 * @param [optional] string dateFormatMask = Format Maske für das Anzeigedatum, Bsp: "dd.mm.yyyy"
 * @param [optional] string htmlAttr = html Attribute
 * @param [optional] string imgPath = modulspezifischer imgPath fuer anderes Aussehen des Calendars via Skins
 * @param [optional] string skinName = modulspezifischer Skin-Name fuer anderes Aussehen
 */
function DateInputUrl(instanceName, url, preSelectedDate, dateFormatMask, htmlAttr, imgPath, skinName)
{
	var instanceNameObj = correctInstanceName(instanceName);
	eval(instanceNameObj + '_Object=new CBrainCalendar(\''+instanceName+'\',\''+preSelectedDate+'\',\''+dateFormatMask+'\');');
	
	//parameter setzen
	eval(instanceNameObj + '_Object.setParameter(\'textAttribs\', \''+htmlAttr+'\');');
	eval(instanceNameObj + '_Object.setParameter(\'urlRedirectTo\', \''+url+'\');');
	eval(instanceNameObj + '_Object.setParameter(\'withTextField\', \'false\');');
	
	//ggf anderer skinpath
	if(imgPath){
		eval(instanceNameObj + '_Object.setParameter(\'imgPath\', \''+imgPath+'\');');
	}
		
	if(skinName){
		eval(instanceNameObj + '_Object.setParameter(\'skinName\', \''+skinName+'\');');
	}
	eval(instanceNameObj + '_Object.create();');
}

/**
 * hilfsfunktion um einen parameter am brainCalendar Objekt zu setzen 
 *
 */
function setParameter(instanceName, ParaName, ParaValue){
	var instanceNameObj = correctInstanceName(instanceName);
	eval(instanceNameObj + '_Object.setParameter(\''+ParaName+'\', \''+ParaValue+'\');');
}
