/**
 * DatePicker widget using Prototype and Scriptaculous.
 * (c) 2007 Mathieu Jondet <mathieu@eulerian.com>
 * Eulerian Technologies
 *
 * DatePicker is freely distributable under the same terms as Prototype.
 *
 */

/**
 * DatePickerFormatter class for matching and stringifying dates.
 *
 * By Arturas Slajus <x11@arturaz.net>.
 */
var DatePickerFormatter = Class.create();
DatePickerFormatter.prototype = {
    /**
     * Create a DatePickerFormatter.
     *
     * format: specify a format by passing 3 value array consisting of
     *   "yyyy", "mm", "dd". Default: ["yyyy", "mm", "dd"].
     *
     * separator: string for splitting the values. Default: "-".
     *
     * Use it like this:
     *   var df = new DatePickerFormatter(["dd", "mm", "yyyy"], "/");
     *   df.current_date();
     *   df.match("7/7/2007");
     */
    initialize: function(format, separator) {
        if (Object.isUndefined(format))
	 format = ["yyyy", "mm", "dd"];
        if (Object.isUndefined(separator))
	 separator = "-";

        this._format 	= format;
        this.separator	= separator;
                
        this._format_year_index	= format.indexOf("yyyy");
        this._format_month_index= format.indexOf("mm");
        this._format_day_index	= format.indexOf("dd");
                
        this._year_regexp	= /^\d{4}$/;
        this._month_regexp 	= /^0\d|1[012]|\d$/;
        this._day_regexp 	= /^0\d|[12]\d|3[01]|\d$/;
    },
    
    /**
     * Match a string against date format.
     * Returns: [year, month, day]
     */
    match: function(str) {
        var d = str.split(this.separator);
        
        if (d.length < 3)
	 return false;
        
        var year = d[this._format_year_index].match(this._year_regexp);
        if (year) { year = year[0] } else { return false }
        var month = d[this._format_month_index].match(this._month_regexp);
        if (month) { month = month[0] } else { return false }
        var day = d[this._format_day_index].match(this._day_regexp);
        if (day) { day = day[0] } else { return false }
        
        return [year, month, day];
    },
    
    /**
     * Return current date according to format.
     */
    current_date: function() {
        var d = new Date;
        return this.date_to_string(
            d.getFullYear(),
            d.getMonth() + 1,
            d.getDate()
       );
    },
    
    /**
     * Return a stringified date accordint to format.
     */
    date_to_string: function(year, month, day, separator) {
        if (Object.isUndefined(separator))
	 separator = this.separator;

        var a = [0, 0, 0];
        a[this._format_year_index]	= year;
        a[this._format_month_index] 	= month.toPaddedString(2);
        a[this._format_day_index] 	= day.toPaddedString(2);
        
        return a.join(separator);
    },
    // Willy Update
    timestamp_of_string: function(string){
    	var date = this.match(string);
    		date = new Date(date[0],date[1]-1,date[2]);
    	var milliseconds = Date.parse(date);
    	var seconds = milliseconds/1000;
    	return seconds;
    }
}; 


/**
 * DatePicker
 */

var DatePicker	= Class.create();

DatePicker.prototype	= {
 Version	: "2.0",
 _relative	: null,
 _range		: null,
 _div		: null,
 _zindex	: 1,
 _keepFieldEmpty: false,
 _daysInMonth	: [31,28,31,30,31,30,31,31,30,31,30,31],
 _dateFormat	: [ ["dd", "mm", "yyyy"], "." ],
 /* language */
 _language	: 'de',
 _language_month	: $H({
  'en'	: [ 'January', 'February', 'March', 'April', 'May',
   'June', 'July', 'August', 'September', 'October', 'November', 'December' ],
  'de'	: [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
   'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' ]
 }),
 _language_day	: $H({
  'en'	: [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ],
  'de'	: [ 'Mon', 'Die', 'Mit', 'Don', 'Fre', 'Sam', 'Son' ]
 }),
 _language_close	: $H({
  'en'	: 'close',
  'de'	: 'schließen'
 }),
 /* date manipulation */
 _todayDate			: new Date(),
 _current_date		: null,
 _setInWrap			: false,
 _clickCallback		: Prototype.emptyFunction,
 _cellCallback		: Prototype.emptyFunction,
 _id_datepicker		: null,
 _disablePastDate	: false,
 _disableFutureDate	: false,
 _enableYearBrowse	: false,
 _oneDayInMs		: 24 * 3600 * 1000,
 /* positionning */
 _topOffset		: 30,
 _leftOffset		: 0,
 _isPositionned		: false,
 _relativePosition 	: true,
 _setPositionTop 	: 0,
 _setPositionLeft	: 0,
 _bodyAppend		: false,
 _contentAppend		: "",
 _showEvent			: "click",
 /* Effects Adjustment */
 _showEffect		: "appear", 
 _showDuration		: 0.3,
 _enableShowEffect 	: true,
 _closeEffect		: "fade", 
 _closeEffectDuration	: 0.3,
 _enableCloseEffect 	: true,
 _closeTimer		: null,
 _enableCloseOnBlur	: false,
 /* afterClose : called when the close function is executed */
 _afterClose		: Prototype.emptyFunction,
 _getInputFnc		: "",
 /* return the name of current month in appropriate language */
 getMonthLocale	: function ( month ) {
  return	this._language_month.get(this._language)[month];
 },
 getLocaleClose	: function () {
  return	this._language_close.get(this._language);
 },
 _initCurrentDate : function () {
  /* Create the DateFormatter */
  this._df = new DatePickerFormatter(this._dateFormat[0], this._dateFormat[1]);
  /* check if value in field is proper, if not set to today */
  this._current_date = $F(this._relative);
  if (! this._df.match(this._current_date)) {
    this._current_date = this._df.current_date();
   /* set the field value ? */
   if (!this._keepFieldEmpty)
    $(this._relative).value = this._current_date;
  }
  var a_date = this._df.match(this._current_date);
  this._current_year 	= Number(a_date[0]);
  this._current_mon	= Number(a_date[1]) - 1;
  this._current_day	= Number(a_date[2]);
 },
 /* init */
initialize: function( h_p ){
	// arguments
	this._relative = h_p["relative"];
	this._zindex = ( h_p["zindex"] ) ? parseInt(Number(h_p["zindex"])) : 1;
	
	this._id_datepicker		= 'datepicker-'+this._relative;
	this._id_datepicker_prev	= this._id_datepicker+'-prev';
	this._id_datepicker_next	= this._id_datepicker+'-next';
	this._id_datepicker_prev_year	= this._id_datepicker_prev+'-year';
	this._id_datepicker_next_year	= this._id_datepicker_next+'-year';
	this._id_datepicker_hdr	= this._id_datepicker+'-header';
	this._id_datepicker_ftr	= this._id_datepicker+'-footer';
	
	this._setPositionTop = ( h_p["setPositionTop"] ) ? parseInt(Number(h_p["setPositionTop"])) : 0;
	this._setPositionLeft = ( h_p["setPositionLeft"] ) ? parseInt(Number(h_p["setPositionLeft"])) : 0;
	 
	if(h_p["range"]){
		if($(h_p["range"].id)){
			this._range = h_p["range"];
			if(Object.isUndefined(this._range.isActive)){
				this._range.isActive = true;
			}
		}
	}
	if(h_p["isLightview"]) this._isLightview = true;
	if(h_p["language"]) this._language = h_p["language"];
	 
	if(!Object.isUndefined(h_p["keepFieldEmpty"])) this._keepFieldEmpty = h_p["keepFieldEmpty"];
	if(!Object.isUndefined(h_p["relativeAppend"])) this._relativeAppend = h_p["relativeAppend"];
	if(Object.isFunction(h_p["clickCallback"])) this._clickCallback = h_p["clickCallback"];
	if(!Object.isUndefined(h_p["leftOffset"])) this._leftOffset = parseInt(h_p["leftOffset"]);
	if(!Object.isUndefined(h_p["topOffset"])) this._topOffset = parseInt(h_p["topOffset"]);
	if(!Object.isUndefined(h_p["relativePosition"])) this._relativePosition = h_p["relativePosition"];
	if(!Object.isUndefined(h_p["showEvent"])) this._showEvent = h_p["showEvent"];
	if(!Object.isUndefined(h_p["showEffect"])) this._showEffect = h_p["showEffect"];
	if(!Object.isUndefined(h_p["contentAppend"])) this._contentAppend = h_p["contentAppend"];
	if(!Object.isUndefined(h_p["enableShowEffect"])) this._enableShowEffect = h_p["enableShowEffect"];
	if(!Object.isUndefined(h_p["showDuration"])) this._showDuration = h_p["showDuration"];
	if(!Object.isUndefined(h_p["closeEffect"])) this._closeEffect = h_p["closeEffect"];
	if(!Object.isUndefined(h_p["enableCloseEffect"])) this._enableCloseEffect = h_p["enableCloseEffect"];
	if(!Object.isUndefined(h_p["closeEffectDuration"])) this._closeEffectDuration = h_p["closeEffectDuration"];
	if(Object.isFunction(h_p["afterClose"])) this._afterClose = h_p["afterClose"];
	if(!Object.isUndefined(h_p["getInputFnc"])) this._getInputFnc = h_p["getInputFnc"];
	if(!Object.isUndefined(h_p["externalControl"])) this._externalControl = h_p["externalControl"];
	if(!Object.isUndefined(h_p["dateFormat"])) this._dateFormat = h_p["dateFormat"];
	if(Object.isFunction(h_p["cellCallback"])) this._cellCallback = h_p["cellCallback"];
	if(!Object.isUndefined(h_p["enableCloseOnBlur"]) && h_p["enableCloseOnBlur"]) this._enableCloseOnBlur = true;
	if(!Object.isUndefined(h_p["disablePastDate"]) && h_p["disablePastDate"])this._disablePastDate = true;
	if(!Object.isUndefined(h_p["disableFutureDate"]) && !h_p["disableFutureDate"])this._disableFutureDate = false;
	if(!Object.isUndefined(h_p["enableYearBrowse"])) this._enableYearBrowse	= h_p["enableYearBrowse"];

///////////////////////////////////////////////////////////
//// Willy Update Kalender Skelett
	var headCol = (this._enableYearBrowse)?4:5;
	this._div = new Element('div',{id:this._id_datepicker,className:'datepicker',rel:(this._isLightview?"lightviewdpk":""),style:'display: none;z-index:'+this._zindex+';'});
	var html = '<table cellspacing="1" cellpadding="0"><thead>';
//		html+= ''+((this._enableYearBrowse) ? '<th id="'+this._id_datepicker_prev_year+'">&lt;</th>' : '');
		html+= '<tr><th id="'+this._id_datepicker_prev+'">&lt;&lt;</th>';
		html+= '<th id="'+this._id_datepicker_hdr+'" colspan="'+headCol+'" style="text-align:center;"></th>';
		html+= ((this._enableYearBrowse) ? '<th class="year_browser"><div id="'+this._id_datepicker_next_year+'">&and;</div><div id="'+this._id_datepicker_prev_year+'">&or;</div></th>':'');
		html+= '<th id="'+this._id_datepicker_next+'">&gt;&gt;</th></tr></thead>';
		html+= '<tbody id="'+this._id_datepicker+'-tbody"></tbody></table>';
//		html+= '<tfoot><td colspan="7" id="'+this._id_datepicker_ftr+'"></td></tfoot></table>';
		this._div.innerHTML = html;
	/* finally declare the event listener on input field */
	$(this._relative).observe(this._showEvent, this.click.bindAsEventListener(this),false);
	/* need to append on body when doc is loaded for IE */
	Event.observe(window,"load",this.load.bindAsEventListener(this), false);
	/* automatically close when blur event is triggered */

	document.observe("click",function(event){
		var input = (Event.element(event) == $(this._relative));
		var desc = Element.descendantOf(Event.element(event),this._div);
		if(!input && !desc && this._div.visible()){
			this._div.hide();
		}
	}.bindAsEventListener(this));
///////////////////////////////////////
//// Willy Update
	if(this._externalControl){
		$(this._externalControl).observe("click",function(){
			this.click();
		}.bindAsEventListener(this));
	}
///////////////////////////////////////
},
 /**
  * load	: called when document is fully-loaded to append datepicker to main object.
  */
load: function(){
	/* append to page */
	if(this._relativeAppend){
		/* append to parent node */
		if($(this._relative).parentNode){
			this._div.innerHTML = this._wrap_in_iframe(this._div.innerHTML);
			$(this._relative).parentNode.appendChild( this._div );
		}
	} else {
		/* append to body tag or to provided contentAppend id */
		var body = (this._contentAppend)?$(this._contentAppend):document.getElementsByTagName("body").item(0);
		if(body){
			this._div.innerHTML = this._wrap_in_iframe(this._div.innerHTML);
			body.appendChild(this._div);
		}
		if( this._relativePosition ){
			if($(this._relative).type!="hidden"){
				var a_pos = Element.cumulativeOffset($(this._relative));
			} else {
				var a_pos = Element.cumulativeOffset($(this._externalControl));
			}
			this.setPosition(a_pos[1], a_pos[0]);
		} else {
			if (this._setPositionTop || this._setPositionLeft)
				this.setPosition(this._setPositionTop, this._setPositionLeft);
		}
	}
	/* init the date in field if needed */
	this._initCurrentDate();
	/* set the close locale content */
	//$(this._id_datepicker_ftr).innerHTML = this.getLocaleClose();
	/* declare the observers for UI control */
	Event.observe($(this._id_datepicker_prev),'click', this.prevMonth.bindAsEventListener(this), false);
	Event.observe($(this._id_datepicker_hdr),'click', this.nextMonth.bindAsEventListener(this), false);
	Event.observe($(this._id_datepicker_next),'click', this.nextMonth.bindAsEventListener(this), false);
	if(this._enableYearBrowse ){
		Event.observe($(this._id_datepicker_prev_year),'click', this.prevYear.bindAsEventListener(this), false);
		Event.observe($(this._id_datepicker_next_year),'click', this.nextYear.bindAsEventListener(this), false);
	}
	//Event.observe($(this._id_datepicker_ftr),'click', this.close.bindAsEventListener(this), false);
},
/* hack for buggy form elements layering in IE */
_wrap_in_iframe: function( content ){
	var _iframe_src	= 'javascript:false';
return ( Prototype.Browser.IE )?"<div style='height:167px;width:185px;background-color:white;align:left'><iframe width='100%' height='100%' marginwidth='0' marginheight='0' frameborder='0' src='"+ _iframe_src +"' style='filter:alpha(Opacity=50);'></iframe><div style='position:absolute;background-color:white;top:2px;left:2px;width:180px'>"+content+"</div></div>":content;
},
 /**
  * visible	: return the visibility status of the datepicker.
  */
visible: function(){
return ($(this._id_datepicker))?$(this._id_datepicker).visible():false;
},
///////////////////////////////////////
////Willy Update
hide: function(){
	this._div.hide();
},
///////////////////////////////////////
/**
  * click	: called when input element is clicked
  */
click: function(){
	/* init the datepicker if it doesn't exists */
	if($(this._id_datepicker) == null)
		this.load();
	
//	if(!this._isPositionned && this._relativePosition){
		/* position the datepicker relatively to element */
		var a_lt = Element.positionedOffset($(this._relative));
		$(this._id_datepicker).setStyle({
			'left':Number(a_lt[0]+this._leftOffset)+'px',
			'top':Number(a_lt[1]+this._topOffset)+'px'
		});
		this._isPositioned	= true;
//	}
	if(this._isLightview){
		this.setNewPosition();
	}
	
	if(!this.visible()){
		this._initCurrentDate();
		this._redrawCalendar();
	}
	/* eval the clickCallback function */
	eval(this._clickCallback());
	/* Effect toggle to fade-in / fade-out the datepicker */
	if(this._enableShowEffect){
		new Effect.toggle(this._id_datepicker, this._showEffect, { duration: this._showDuration });
	} else {
		$(this._id_datepicker).show();
	}
	/* clean timer */
//	if(this._closeTimer){ 
//		window.clearTimeout(this._closeTimer); 
//		this._closeTimer = null; 
//	}
/////////////////////////////////////////////
//// Willy Update
	if(this._range != null && this._range.isActive && $("datepicker-"+this._range.id)){
		$("datepicker-"+this._range.id).hide();
	}
/////////////////////////////////////////////
},
_isLightview:false,
_position: {
	input:{},
	viewport:{}
},
setNewPosition: function(){	
	var input = $(this._relative).cumulativeOffset();
	var viewport = document.viewport.getScrollOffsets();

	if(viewport.top != this._position.viewport.top){
		var top = viewport.top+input.top+this._topOffset;
		$(this._id_datepicker).setStyle({
			"top":Number(top)+"px"
		});
		this._position = {};
		this._position.input = input;
		this._position.viewport = viewport;
	}
},
/////////////////////////////////////////////
////Willy Update
setActive: function(boolean,date){
	this._range.isActive = boolean;
	if(boolean)
		$(this._relative).value = date;
},
setRangeActive: function(boolean){
	$(this._range.id).dpk.setActive(boolean,$F(this._relative));
},
/////////////////////////////////////////////
 /**
  * close	: called when the datepicker is closed
  */
 close		: function () {
  if ( this._enableCloseEffect ) {
   switch(this._closeEffect) {
    case 'puff': 
     new Effect.Puff(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
    case 'blindUp': 
     new Effect.BlindUp(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
    case 'dropOut': 
     new Effect.DropOut(this._id_datepicker, { 
      duration : this._closeEffectDuration }); 
     break;
    case 'switchOff': 
     new Effect.SwitchOff(this._id_datepicker, { 
      duration : this._closeEffectDuration }); 
     break;
    case 'squish': 
     new Effect.Squish(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
    case 'fold': 
     new Effect.Fold(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
    case 'shrink': 
     new Effect.Shrink(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
    default: 
     new Effect.Fade(this._id_datepicker, { 
      duration : this._closeEffectDuration });
     break;
   };
  } else {
   $(this._id_datepicker).hide();
  }

	this._afterClose({date:$(this._relative).value,fieldname:this._relative});
 },
 /**
  * setDateFormat
  */
 setDateFormat	: function ( format, separator ) {
  if (Object.isUndefined(format))
   format	= this._dateFormat[0];
  if (Object.isUndefined(separator))
   separator	= this._dateFormat[1];
  this._dateFormat	= [ format, separator ];
 },
 /**
  * setPosition	: set the position of the datepicker.
  *  param : t=top | l=left
  */
 setPosition	: function ( t, l ) {
  var h_pos	= { 'top' : '0px', 'left' : '0px' };
  if (!Object.isUndefined(t))
   h_pos['top']	= Number(t)+this._topOffset+'px';
  if (!Object.isUndefined(l))
   h_pos['left']= Number(l)+this._leftOffset+'px';
  $(this._id_datepicker).setStyle(h_pos);
  this._isPositionned	= true;
 },
 /**
  * _getMonthDays : given the year and month find the number of days.
  */
 _getMonthDays	: function ( year, month ) {
  if (((0 == (year%4)) && 
   ( (0 != (year%100)) || (0 == (year%400)))) && (month == 1))
   return 29;
  return this._daysInMonth[month];
 },
 /**
  * _buildCalendar	: draw the days array for current date
  */
 _buildCalendar		: function () {
  var _self	= this;
  var tbody	= $(this._id_datepicker+'-tbody');
  try {
   while ( tbody.hasChildNodes() )
    tbody.removeChild(tbody.childNodes[0]);
  } catch ( e ) {};
  /* generate day headers */
  var trDay	= new Element('tr');
  this._language_day.get(this._language).each( function ( item ) {
   var td	= new Element('td',{className:"wday"});
   td.innerHTML	= item;
   trDay.appendChild(td);
  });
  tbody.appendChild(trDay);
  /* generate the content of days */
  
  /* build-up days matrix */
  var a_d	= [ [ 0, 0, 0, 0, 0, 0, 0 ] ,[ 0, 0, 0, 0, 0, 0, 0 ]
   ,[ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ]
   ,[ 0, 0, 0, 0, 0, 0, 0 ]
  ];
  /* set date at beginning of month to display */
  var d		= new Date(this._current_year, this._current_mon, 1, 12);
  /* start the day list on monday */
  var startIndex	= ( !d.getDay() ) ? 6 : d.getDay() - 1;
  var nbDaysInMonth	= this._getMonthDays(
    this._current_year, this._current_mon);
  var daysIndex		= 1;
  for ( var j = startIndex; j < 7; j++ ) {
   a_d[0][j]	= { 
     d : daysIndex
    ,m : this._current_mon
    ,y : this._current_year 
   };
   daysIndex++;
  }
  var a_prevMY	= this._prevMonthYear();
  var nbDaysInMonthPrev	= this._getMonthDays(a_prevMY[1], a_prevMY[0]);
  for ( var j = 0; j < startIndex; j++ ) {
   a_d[0][j]	= { 
     d : Number(nbDaysInMonthPrev - startIndex + j + 1) 
    ,m : Number(a_prevMY[0])
    ,y : a_prevMY[1]
    ,c : 'outbound'
   };
  }
  var switchNextMonth	= false;
  var currentMonth	= this._current_mon;
  var currentYear	= this._current_year;
    
  for ( var i = 1; i < 6; i++ ) {
   for ( var j = 0; j < 7; j++ ) {
    a_d[i][j]	= { 
      d : daysIndex
     ,m : currentMonth
     ,y : currentYear
     ,c : (switchNextMonth)?'outbound':(
    		 (
	    	 	(daysIndex == this._todayDate.getDate()) && 
	    	 	(this._current_mon == this._todayDate.getMonth()) &&
	    	 	(this._current_year == this._todayDate.getFullYear())
    		 )?'today':null)
    };
    daysIndex++;
    /* if at the end of the month : reset counter */
    if (daysIndex > nbDaysInMonth ) {
     daysIndex	= 1;
     switchNextMonth = true;
     if (this._current_mon + 1 > 11 ) {
      currentMonth = 0;
      currentYear += 1;
     } else {
      currentMonth += 1;
     }
    }
   }
  }
  /* generate days for current date */
  for ( var i = 0; i < 6; i++ ) {
   var tr	= new Element('tr');
   for ( var j = 0; j < 7; j++ ) {
    var h_ij	= a_d[i][j];
    var td	= new Element('td');
    /* id is : datepicker-day-mon-year or depending on language other way */
    /* don't forget to add 1 on month for proper formmatting */
    var id	= $A([
     this._relative,
     this._df.date_to_string(h_ij["y"], h_ij["m"]+1, h_ij["d"], '-')
    ]).join('-');
    /* set id and classname for cell if exists */
    td.setAttribute('id', id);
    if (h_ij["c"])
     td.className	= h_ij["c"];
//////////////////////////////
//// Willy Update
    if(h_ij["c"]=="today"){
    	td.title = "heute";
    }
//////////////////////////////
	    /* on onclick : rebuild date value from id of current cell */
		var _curDate = new Date();
			_curDate.setFullYear(h_ij["y"], h_ij["m"], h_ij["d"]);			
		if( this._disablePastDate || this._disableFutureDate ){
			if( this._disablePastDate ){
				var _res = ( _curDate >= this._todayDate ) ? true : false;
				this._bindCellOnClick( td, true, _res, h_ij["c"] );
			}
			if( this._disableFutureDate ){
				var _res = ( this._todayDate.getTime() + this._oneDayInMs > _curDate.getTime() ) ? true : false;
				this._bindCellOnClick( td, true, _res,  h_ij["c"] );
			}
		} else {
			this._bindCellOnClick( td, false );
		}
		td.innerHTML= h_ij["d"];
		tr.appendChild( td );
	}
tbody.appendChild( tr );
}
/////////////////////////////////////////////////////////////////////////
//// Willy Update # wenn ein range obj mit gegeben wird dann das range
//// den elementen zuweisen. start -> range -> end
  var search = eval("/\\"+this._dateFormat[1]+"/g");
if(this._range != null && this._range.isActive){
	if(this._range.index == 0){
		var dateStart = this._relative+"-"+this._current_date.replace(search, "-");
		var dateEnd = this._relative+"-"+$F(this._range.id).replace(search, "-");
	} else {
		var dateStart = this._relative+"-"+$F(this._range.id).replace(search, "-");
		var dateEnd = this._relative+"-"+this._current_date.replace(search, "-");
	}

	var rangeInputs = false;
	
	if(!$(dateStart) && $(dateEnd)){
		rangeInputs = true;
	} else if(!$(dateStart) && !$(dateEnd)){
		// gucken ob das range über mehrere monate geht...
		var dateStart2 = this._df.match((this._range.index==0)?$F(this._relative):$F(this._range.id));
			dateStart2 = new Date(dateStart2[0],(dateStart2[1]-1),dateStart2[2]);
			
		var dateEnd2 = this._df.match((this._range.index==1)?$F(this._relative):$F(this._range.id));
			dateEnd2 = new Date(dateEnd2[0],(dateEnd2[1]-1),dateEnd2[2]);
	
		var dateFirst = this._df.match(String(tbody.descendants()[9].readAttribute('id')).replace(this._relative+'-','').replace(/-/g, this._df.separator));
			dateFirst = new Date(dateFirst[0],(dateFirst[1]-1),dateFirst[2]);
		// ist das range noch innerhalb des monats dann auf true schalten
		if(dateStart2<dateFirst && dateFirst<dateEnd2){
			rangeInputs = true;
		}
	}
// nur den heutigen tag setzen
} else {
	var dateInput = this._relative+"-"+this._current_date.replace(search, "-");
}

tbody.descendants().each(function(e,i){
	if(!Object.isUndefined(dateStart) && !Object.isUndefined(dateEnd) && e.className != "wday"){		
		// Tage
		if(e.id == dateStart){
			e.addClassName("start");
			e.update(e.innerHTML+" &raquo;");
			e.title = "gewählter Starttag";
			if(dateStart != dateEnd)
				rangeInputs = true;
		}else if(e.id == dateEnd){
			e.addClassName("end");
			e.update("&laquo; "+e.innerHTML);
			e.title = "gewählter Endtag";
			rangeInputs = false;
		}else if(rangeInputs){
			if(e.hasClassName("outbound"))
				e.addClassName("lightrange");
			else
				e.addClassName("range");
		}
	} else if(!Object.isUndefined(dateInput) && e.id == dateInput){
		e.addClassName("active");
		e.title = "gewählter Tag";
	}
});
/////////////////////////////////////////////////////////////////////////////////////
return tbody;
},
/**
  * _bindCellOnClick	: bind the cell onclick depending on status.
  */
_bindCellOnClick : function( td, wcompare, compareresult, h_ij_c ){
	var doBind = false;
	if(wcompare){
		if(compareresult){
			doBind = true;
		} else {
			td.className =(h_ij_c)?'nclick_outbound':'nclick';
		}
	} else {
		doBind = true;
	}
/////////////////////////////////////
//// Willy Update
	if(this._range != null && this._range.isActive){
		doBind = this._checkDates(td);
	}
/////////////////////////////////////
	if(doBind){
		td.observe("click",function(){
			$(this._relative).value = String(td.readAttribute('id')).replace(this._relative+'-','').replace(/-/g,this._df.separator);
			/* if we have a cellCallback defined call it and pass it the cell */
			if(this._cellCallback)
				this._cellCallback(td);
			//////////////////////////////////////
			//// Willy Update
				this._handleClicks(td,$F(this._relative));
			//////////////////////////////////////
		}.bindAsEventListener(this));
//////////////////////////////////////
//// Willy Update
	} else if(this._range != null && this._range.isActive){
		td.observe("click",function(){
			var value = String(td.readAttribute('id')).replace(this._relative+'-','').replace(/-/g,this._df.separator);
			$(this._relative).value = value;
			$(this._range.id).value = value;
			this._handleClicks();
		}.bindAsEventListener(this));
	}
//////////////////////////////////////
},
_handleClicks: function(cell,click_date){
	cell.up("tbody",0).childElements().each(function(tr,i){
		tr.childElements().each(function(td){
			if(td == cell)td.addClassName("active");
			else td.removeClassName("active");
		})
	});
	this._initCurrentDate();
	this._setLocaleHdr();
},
//////////////////////////////////////
//// Willy Update
_checkDates: function(element){
	var bool = true;
	var selectedDate = String(element.readAttribute('id')).replace(this._relative+'-','').replace(/-/g, this._df.separator);
	
	var dateStart = this._df.match((this._range.index==0)?selectedDate:$F(this._range.id));
		dateStart = new Date(dateStart[0],(dateStart[1]-1),dateStart[2]);
	var dateEnd = this._df.match((this._range.index==1)?selectedDate:$F(this._range.id));
		dateEnd = new Date(dateEnd[0],(dateEnd[1]-1),dateEnd[2]);	
		
	if(dateStart>dateEnd || dateEnd<dateStart){
		bool = false;
	}
	return bool;
},
///////////////////////////////////////
 /**
  * nextMonth	: redraw the calendar content for next month.
  */
 _nextMonthYear	: function () {
  var c_mon	= this._current_mon;
  var c_year	= this._current_year;
  if (c_mon + 1 > 11) {
   c_mon	= 0;
   c_year	+= 1;
  } else {
   c_mon	+= 1;
  }
  return	[ c_mon, c_year ];
 },
 nextMonth	: function () {
  var a_next	= this._nextMonthYear();
  var _nextMon	= a_next[0];
  var _nextYear	= a_next[1];
  var _curDate	= new Date(); _curDate.setFullYear(_nextYear, _nextMon, 1);
  var _res	= ( this._todayDate.getTime() + this._oneDayInMs > _curDate.getTime() ) ? true : false;
  if ( this._disableFutureDate && !_res )
   return;
  this._current_mon	= _nextMon;
  this._current_year 	= _nextYear;
  this._redrawCalendar();
 },
 /**
  * prevMonth	: redraw the calendar content for previous month.
  */
 _prevMonthYear	: function () {
  var c_mon	= this._current_mon;
  var c_year	= this._current_year;
  if (c_mon - 1 < 0) {
   c_mon	= 11;
   c_year	-= 1;
  } else {
   c_mon	-= 1;
  }
  return	[ c_mon, c_year ];
 },
 prevMonth	: function () {
  var a_prev	= this._prevMonthYear();
  var _prevMon	= a_prev[0];
  var _prevYear	= a_prev[1];
  var _curDate	= new Date(); _curDate.setFullYear(_prevYear, _prevMon, 1);
  var _res	= ( _curDate >= this._todayDate ) ? true : false;
  if ( this._disablePastDate && !_res && (_prevMon!=this._todayDate.getMonth()))
   return;
  this._current_mon	= _prevMon;
  this._current_year	= _prevYear;
  this._redrawCalendar();
 },
 /**
  * prevYear	: redraw the calendar content for prev year.
  */
 _prevYear	: function () {
  var c_mon	= this._current_mon;
  var c_year	= (this._current_year - 1);
  
  return	[ c_mon, c_year ];
 },
 prevYear	: function () {
  var a_next	= this._prevYear();
  var _nextMon	= a_next[0];
  var _nextYear	= a_next[1];
  var _curDate	= new Date(); _curDate.setFullYear(_nextYear, _nextMon, 1);
  var _res	= ( this._todayDate.getTime() + this._oneDayInMs > _curDate.getTime() ) ? true : false;
  if ( this._disableFutureDate && !_res )
   return;
  this._current_mon	= _nextMon;
  this._current_year 	= _nextYear;
  this._redrawCalendar();
 },
 
 /**
  * nextYear	: redraw the calendar content for next year.
  */
 _nextYear	: function () {
  var c_mon	= this._current_mon;
  var c_year	= (this._current_year + 1);
  
  return	[ c_mon, c_year ];
 },
nextYear: function(){
  var a_next	= this._nextYear();
  var _nextMon	= a_next[0];
  var _nextYear	= a_next[1];
  var _curDate	= new Date(); _curDate.setFullYear(_nextYear, _nextMon, 1);
  var _res	= ( this._todayDate.getTime() + this._oneDayInMs > _curDate.getTime() ) ? true : false;
  if ( this._disableFutureDate && !_res )
   return;
  this._current_mon	= _nextMon;
  this._current_year 	= _nextYear;
  this._redrawCalendar();
},
_redrawCalendar: function(){
	 this._setLocaleHdr();
	 this._buildCalendar();
},
_setLocaleHdr: function(){
	/* next link */
	var a_next = this._nextMonthYear();
		$(this._id_datepicker_next).setAttribute('title',this.getMonthLocale(a_next[0])+' '+a_next[1]);
	/* prev link */
	var a_prev = this._prevMonthYear();
		$(this._id_datepicker_prev).setAttribute('title',this.getMonthLocale(a_prev[0])+' '+a_prev[1]);
	/* year browse */
	if(this._enableYearBrowse){
		var a_next_y = this._nextYear();
			$(this._id_datepicker_next_year).setAttribute('title',this.getMonthLocale(a_next_y[0])+' '+a_next_y[1]);
		var a_prev_y = this._prevYear();
			$(this._id_datepicker_prev_year).setAttribute('title',this.getMonthLocale(a_prev_y[0])+' '+a_prev_y[1]);
	}
	/* header */
	$(this._id_datepicker_hdr).update(this.getMonthLocale(this._current_mon));//+" ("+(this._current_mon+1)+")"
}
};

