var dmsDatePicker = new Class({
	
	debug:function(value){
		// console.debug(value);
	},
	
	init: function(datepicker){
		this.currentTS = 0;
		
		this.debug(['init',datepicker]);
		
		this.datepicker = datepicker;
		this.id = datepicker.getProperty('id');
				
			// load relations
		this.minField       = false;
		this.maxField       = false;
		if ( node = this.datepicker.getProperty('dms:datepicker_max_field'   ) ) this.maxField = $(node);
		if ( node = this.datepicker.getProperty('dms:datepicker_min_field'   ) ) this.minField = $(node);
		
			// more relations
		this.dayField   = false;
		this.monthField = false;
		this.yearField  = false;
		this.durationField  = false;
		if ( node = this.datepicker.getProperty('dms:datepicker_day_field'    ) ) this.dayField    = $(node);
		if ( node = this.datepicker.getProperty('dms:datepicker_month_field'  ) ) this.monthField  = $(node);
		if ( node = this.datepicker.getProperty('dms:datepicker_year_field'   ) ) this.yearField   = $(node);
		if ( node = this.datepicker.getProperty('dms:datepicker_dur_field'    ) ) this.durationField  = $(node);
		
			// getDuration Values from select field
		this.minDuration = 1;
		this.maxDuration = 15;
		if ( val  = this.datepicker.getProperty('dms:datepicker_min_duration') ) this.minDuration = parseInt(val);
		if ( val  = this.datepicker.getProperty('dms:datepicker_max_duration') ) this.maxDuration = parseInt(val);
			
		this.durationValues = false;	
		if (this.durationField && this.durationField.getTag() == "select")	{
			 this.durationValues = new Array();
			 var options = $ES( 'option' , this.durationField );
			 for (var i= 0;i<options.length; i++ ){
			 	var option = new Element(options[i]);
			 	if (option.getProperty('value')){
					this.durationValues.push( parseInt( option.getProperty('value') ) );
				} else {
					this.durationValues.push( parseInt( option.getText() )  );
				}
			 }
			 this.minDuration = this.durationValues[0];
			 this.maxDuration = this.durationValues[ this.durationValues.length -1 ];
		}
		
			// find buttons and bind methods for open and closing
		var open_buttons = $$('.dms_datepicker_open');		
		for (var i=0 ; i<open_buttons.length; i++){
			if (open_buttons[i].getProperty('dms:datepicker_input') == this.id){
				var icon_open = new Element(open_buttons[i]);
				icon_open.addEvent('click', this.open.bindWithEvent( this ) );
			}
		}
			// add focus and blur events
		this.datepicker.addEvent('focus', this.focus.bindWithEvent( this ) );
		this.datepicker.addEvent('blur',  this.blur.bindWithEvent( this ) )		
		
		var clear_buttons = $$('.dms_datepicker_clear');
		for (var i=0 ; i<clear_buttons.length; i++){
			if (clear_buttons[i].getProperty('dms:datepicker_input') == this.id){
				var icon_clear = new Element(clear_buttons[i]);
				icon_clear.addEvent('click', this.clear.bindWithEvent( this ) );
			}
		}
		
			// add duration dhange Events
		if (this.minField && this.durationField ){
			this.durationField.addEvent('change', this.set_duration.bindWithEvent(this) );
		} 
					
			// set default options
		this.options = {
			'format':'mm/dd/yyyy'
		};
		
			// load language defaults
		var lang = false;	
		if ( html_lang = $$('html').getProperty('lang') )   	lang = html_lang;
		if ( local_lang = this.datepicker.getProperty('lang') ) lang = local_lang;

		this.debug(lang);

		if (lang){
			switch (lang){
				case 'de-DE':
					this.options['format']= 'dd.mm.yyyy';
					this.options['lang']  = 'de-DE';
					break;
				case 'en-UK':
					this.options['format']= 'mm/dd/yyyy';
					this.options['lang']  = 'en-UK';
					break;
			}
		}
			
			// load options from alt tag
		if(this.datepicker.alt) {
			var alt_options = Json.evaluate(this.datepicker.alt);
			for (option in alt_options){
				this.options[option] = alt_options[option];
			}
		} 
	},
		
	set_duration:function(){
		var duration = parseInt( this.durationField.getValue() );
		var minStr=  this.minField.getValue();
		if (minStr && duration){
			var minTS  = this.date2ts (minStr, this.options.format);
			var newTS  = minTS + 86400000 * duration + 7200000; // last value is 2 h in ms for save day identification
			this.setDate(newTS);
		}
	},
	
	clear:function(){
		this.debug(['clear']);
		this.datepicker.value = '';
	},
	
	repair:function(force){
		var value = this.datepicker.getValue();
		if (value){
			var date_shall    = this.repairDate(value, this.options.format);
			var date_shall_ts = date_shall.getTime();
			if ( date_shall_ts != this.currentTS || force == true ){
				this.setDate(date_shall_ts ); 
			}
		}
	},
	
	focus:function(){
		this.repair(false);
	},
	
	blur:function(){
		this.repair(true);
	},
	
	open:function(){
		
		this.debug(['open']);
		
			// find the entered date, or use the current date
		var value = this.datepicker.getValue();
		
			// current date
		var today = new Date();
		today.setMilliseconds(0);
		today.setSeconds(0);
		today.setMinutes(0);
		today.setHours(0);
		
		if( value != '') {
			var ts = this.date2ts(value, this.options.format);
			var selected_date  = new Date();
			selected_date.setTime(ts);
		} else {
			var selected_date = today;
		}
		
			//save date objects		
		this.options['selected_date'] =  selected_date;
		this.debug([	this.options['selected_date'], this.options.format ]);
		
			// close already running pickers
		if (dmsActiveDatePicker){
			dmsActiveDatePicker.remove();
		}
				
			// create picker iframe and inject into page
		this.iframe = new Element( 'iframe', {
			'class'       : 'dms_datepicker_iframe',
			'name'        : 'dms_iframe_' + this.id,
			'scrolling'   : 'no',
			'frameborder' : '0',
			'src'         : '/irs/TPortal/typo3/hv2/popup/DatePicker.htm' 
		});
		
		this.iframe.injectBefore(this.datepicker);
		
			// add close events on click outside
		document.body.addEvent( 'mousedown', function(){
			this.remove();
			document.body.removeEvents('mousedown');
			
		}.bind(this) );
		
			// save global configuration 
		dmsActiveDatePicker = this;
		
		return; 
	},
	
	setDate:function( dateTS ){

		this.debug(['setDate',dateTS, this.datepicker]);
		
			// handle this.minField this.minDuration this.maxDuration
		var duration = false;		
		if ( $(this.minField)  ){
			var minStr =  $(this.minField).getValue();
			if (minStr){
				var minTS  = this.date2ts (minStr, this.options.format );
				duration   = this.validateDuration( Math.round( (dateTS - minTS )/86400000 ) )
			} else {
				duration   = this.validateDuration( 0 );
			}
			this.minField.dms_datepicker.set( dateTS - (duration * 86400000 ) + (7200000) ); // last value is 2 h in ms for save day identification
		}
		
			// handle max field
		if ( $(this.maxField)  ){
			if (this.durationField.getValue() ){
				duration = parseInt( this.durationField.getValue() );
			} else {
				var maxStr     = $(this.maxField).getValue();
				var lastString = this.datepicker.getValue();
				if (maxStr){
					var maxTS  = this.date2ts ( maxStr,     this.options.format);
					var lastTS = this.date2ts ( lastString, this.options.format);
					duration   = this.validateDuration( Math.round( (maxTS - lastTS)/86400000 ) )
				} else {
					duration   = this.validateDuration( 0 );
				}
			}
			this.maxField.dms_datepicker.set( dateTS + (duration * 86400000 ) + (7200000) ); // last value is 2 h in ms for save day identification
		}	
		
			// update duration field
		if (this.durationField && duration ){
			if (this.durationField.getValue() != duration){
				this.durationField.value = duration;
				this.durationField.fireEvent( 'change', { target:this.durationField, type:'change' } , 0 );
			}
		}
		 
			// save Data
		this.set(dateTS);
			
			/* trigger callback */
		if ( this.options.callback ){
			var cb = eval( this.options.callback ) ;
			if (cb){
				cb(dp);
			} 
		}
		
			// remove picker
		this.remove();	
	},
	
	validateDuration:function(duration){
			// handle min and max
		if (duration < this.minDuration){
			return this.minDuration;
		}
		if (duration > this.maxDuration){
			return  this.maxDuration;
		}
			// get next from duration values if optins array is present
		if (this.durationValues.length>1){
			return duration;
		} else {
			return duration;
		}
	},
	
	set:function (dateTS){

			// format and update value
		if (this.currentTS != dateTS){
				// save local TS
			this.currentTS = dateTS;
			var formated_date = this.ts2date( dateTS , this.options.format );
			this.datepicker.value  = formated_date;
			this.datepicker.fireEvent( 'change', { target:this.datepicker, type:'change' } , 0 );
		}
		

		
			// set day_field month and year fields
		var date = new Date();
		date.setTime(dateTS);	
		
		if (this.dayField){
			var val = date.getDate();
			if (this.dayField.getValue() != val){
				this.dayField.value = val;
			}
		}
		
		if (this.monthField){
			var val = 1+date.getMonth();
			if (this.monthField.getValue() != val){
				this.monthField.value = val;
			}
		}
		
		if (this.yearField){
			var val = date.getFullYear();
			if (this.yearField.getValue() != val){
				this.yearField.value = val;
			}
		}
		
	},
	
	getTS:function(){
		return this.currentTS;
	},
	
	remove:function(){
			// remove iframe
		if (this.iframe){
			this.iframe.remove();
			this.iframe = false;
		}
			// remove global reference
		if ( dmsActiveDatePicker == this){
			dmsActiveDatePicker = false;
		}
	},
	
		/* 
		 * the following methods are date helper methods 
		 * copied from the hht:date_helper.js class
		 */
		
	
	repairDate:function(value, format ){

		/* replace splitting chars in format and date string */
		var v = value.replace (/[\D]+/g, ":"); //all non numbers are delimiters
		var f = format.replace(/[\W]+/g, ":"); //all non alphanum  chats are delimiters 
		
		/* split format and value */
		var v_parts = v.split(':');
		var f_parts = f.split(':');

		/* default = now */
		var now   = new Date();
		now.setMilliseconds(0);
		now.setSeconds(0);
		now.setMinutes(0);
		now.setHours(0);
		
		/* empty values */
		var year  = Number.NaN;
		var month = Number.NaN;
		var day   = Number.NaN;
				
		for ( var key = 0; key< f_parts.length ; key ++){
			
			var p_value  = "" + v_parts[key];
			var p_format = "" + f_parts[key];
				
			if ( p_value ){
				
					// remove leading zeros
				p_value = p_value.replace (/^[0]+/g, '' );
	
				switch (p_format ){
					case 'yyyy':
						year  = parseInt(p_value);
						break;
					case 'mm':
						month = parseInt(p_value);
						break;
					case 'dd':
						day   = parseInt(p_value);
						break;
				}
			}
		}
		
		/* fix date value */
		if ( isNaN(day) || day > 31 ){
			day = now.getDate();
		}
		
		/* fix month value */
		if ( isNaN(month) || month > 12 ) {
			if (day >= now.getDate() ) {
				month = 1 + now.getMonth(); // this month
			} else {
				month = 2 + now.getMonth(); // next month
			}		
		}
		
		/* fix present year values */
		if ( !isNaN(year) ) {
			if (year < 100 ) year = 2000 + year;
			if  ( year < now.getFullYear() || year > now.getFullYear() + 5 ) {
				if ( (month > now.getMonth() + 1) || ( month == now.getMonth() + 1 && day > now.getDate() ) ){
					year = now.getFullYear();				
				} else {
					year = now.getFullYear() + 1;
				}
			}
		}
		
		/* guess empty year values */
		if  ( isNaN(year) ) {
			if ( (month > now.getMonth() + 1 || ( month == now.getMonth() +1 && day >= now.getDate() ) ) ) {
				year = now.getFullYear();
			} else {
				year = now.getFullYear() + 1 ;
			} 
		}
		
		/* format value */
		var corrected_date = new Date(year, ( month-1 ), day);
		
		if (corrected_date < now){
			return now;
		} else {
			return corrected_date;
		}
	},
		
		/* Convert Date-Str to JS-Timestamp */
		
	date2ts:function(dateStr,format){

			// default value
		var now = new Date();  
		var year   = now.getFullYear()  ;
		var month  = now.getMonth() ;
		var day    = now.getDate();

			// extract y m d from date-str
		var dd = this.extractDatePart(format, dateStr, 'dd');
		while (dd.substr(0,1) == '0') dd = dd.substr(1);			
		if (dd)	 day = parseInt(dd);

		var mm = this.extractDatePart(format, dateStr, 'mm' );
		while (mm.substr(0,1) == '0') mm = mm.substr(1);	
		if (mm)	 month =  parseInt(mm) -1;

		var yyyy = this.extractDatePart(format, dateStr, 'yyyy' );
		while (yyyy.substr(0,1) == '0') yyyy = yyyy.substr(1);	
		if (yyyy)  year =  parseInt(yyyy);
		
			// convert values
		var date = new Date( year, month, day);
		
		return ( date.getTime() );
	},
	
	ts2date:function(ts,format){
	
		var date = new Date();
		date.setTime(ts);
		
		var year   = date.getFullYear()  ;
		var month  = date.getMonth() + 1 ;
		var day    = date.getDate() ;
		
		if (day < 10) day = '0' + day;
		if (month < 10) month = '0' + month;
		var dateStr = format.replace( /dd/i, day ).replace( /mm/i, month ).replace( /yyyy/i, year );
		
		return dateStr;
	},
	
	extractDatePart:function(format, string, pattern){
		var result = "";
		var start = format.indexOf(pattern);
		var len   = pattern.length; 
		if (start > -1 && len > 0 ){
			result = string.substr(start, len);
		}
		return result;
	}
	
	
});

window.addEvent('domready', function()	{
	dmsActiveDatePicker = false;
	$$('input.dms_datepicker_input').each(function(datepicker){
		datepicker.dms_datepicker = new dmsDatePicker();
		datepicker.dms_datepicker.init(datepicker);
	});
});

