/**
 * @author Daniel Pisanec
 * @copyright 2009 by Daniel Pisanec
 * @version 1.0
 */
var GetEl = new Class({
	_elements: [],

	initialize: function() {},

	/**
	 * get Element Array
	 * @param {Mixed} arg
	 */
	getEls: function(arg)
	{
		this._elements = [];
		
		// Element
		if($type(arg) == 'element') {
			this._elements.include(arg);
		}
		// Collection of Elements
		else if($type(arg) == 'collection') {
			this._elements = arg;
		}
		// String
		else if($type(arg) == 'string') {
			this._GetElHandleString(arg);
		}
		// Array
		else if($type(arg) == 'array') {
			arg.each(function(item) {
				this.getEls(item);
			}.bind(this));
		}
		// Object
		else if($type(arg) == 'object') {
			this._GetElHandleObject(arg);
		}
		else {
			return false;
		}
		
		return this._elements;
	},
	
	_GetElHandleString: function(string)
	{
		// simple ID
		if($(string)) {
			this._elements.include($(string));
		}
		// class
		else if($$('.' + string).lenght >= 1) {
			this._elements.combine($$('.' + string));
		}
		// Selector
		else {
			this._elements.combine(document.getElements(string));
		}
	},
	
	_GetElHandleObject: function(obj)
	{
		for(var key in obj)
		{
			switch(key) {
				// ELEMENT
				case 'element':
					this._elements.include(obj[key]);
					break;
				
				case 'elements':
					this._elements.combine(obj[key]);
					break;
					
					
				// ID
				case 'id':
					this._elements.include($(obj[key]));
					break;
				
				case 'ids':
					if($type(obj[key]) == 'array') {
						obj[key].each(function(id) {
							this._elements.include($(id));
						}.bind(this));
					}
					break;
				
				
				// CLASS
				case 'class':
					this._elements.combine($$('.' + obj[key]));
					break;
				
				case 'classes':
					if($type(obj[key]) == 'array') {
						obj[key].each(function(class_str) {
							this._elements.combine($$('.' + class_str));
						}.bind(this));
					}
					break;
				
				// SELECTORS
				case 'selector':
					this._elements.combine(document.getElements(obj[key]));
					break;
				
				case 'selectors':
					if($type(obj[key]) == 'array') {
						obj[key].each(function(selectors) {
							this._elements.combine(document.getElements(selectors));
						}.bind(this));
					}
					break;
				
				// COLLECTION
				case 'collection':
					this._elements.combine(obj[key]);
					break;
					
					
				default: 
					break;
			}
		}
	}
});
/**
 * @author Daniel Pisanec
 * @copyright 2009 Daniel Pisanec
 * @version 0
 */
var DaxtEdit = new Class({
	Implements: [GetEl, Options],
	options: {
		id_prefix: 'daxtEdit',
		class_name: 'daxtEdit',
		select_text: true
	},
	
	initialize: function(elements, options)
	{
		this.getEls(elements);
		
		this.setOptions(options);
		
		this._elements.each(function(el, key) {
			el.addEvent('click', function(e) {
				var text_el	= e.target;
				var text	= e.target.get('html');
				var id		= e.target.getProperty('id');
				var styles	= this.getStyles(e.target);

				// if no background is defined, set to white
				if(styles['background-color'] == 'transparent' && styles['background-image'] == 'none') {
					styles['background-color'] = '#ffffff';
				}
				
				// mootools opera bug, if no font-style is given for element, nothing is returned
				if(styles['font-size'].toInt() == 0) {
					styles['font-size'] = '1.5em';
				}
				
				var size	= e.target.getComputedSize();
				
				
				if (text.length <= 100) {
					var field = new Element('input', {
						id: this.options.id_prefix + '_' + id,
						'class': this.options.class_name,
						value: text,
						style: 'width: ' + size.totalWidth + 'px; height:' + size.totalHeight + 'px;',
						styles: styles
						
					});
				}
				else {
					var field = new Element('textarea', {
						id: this.options.id_prefix + '_' + id,
						'class': this.options.class_name,
						style: 'width: ' + size.totalWidth + 'px; height:' + size.totalHeight + 'px;',
						styles: styles,
						html: text
					});
				}
				
				var is_triggered = false;
				
				field.addEvents({
					'keyup': function(e)
					{
						e.stop();

						if (e.key == 'enter' && is_triggered !== true) {
							is_triggered = true;
							
							if (e.target.get('tag') == 'input') {
								var new_text = e.target.getProperty('value');
							}
							else {
								var new_text = e.target.get('html');
							}
							
							this._elements[key].set('html', new_text);
							
							if (new_text == text) {
								text_el.fireEvent('textBlur');
							}
							else {
								text_el.fireEvent('textChange');
							}
							
							e.target.destroy();
						}
					}.bind(this),
									

					'blur': function(e)
					{
						e.stop();
 
						if (is_triggered !== true) {
							is_triggered = true;
							
							if (e.target.get('tag') == 'input') {
								var new_text = e.target.getProperty('value');
							}
							else {
								var new_text = e.target.get('html');
							}
							
							this._elements[key].set('html', new_text);
							
							if (new_text == text) {
								text_el.fireEvent('textBlur');
							}
							else {
								text_el.fireEvent('textChange');
							}
							
							e.target.destroy();
							
						}
					}.bind(this)
				});

					
				
				var parent = e.target.getParent();
				
				if (parent.getStyle('position') == 'relative' || parent.getStyle('position') == 'absolute') {
					var pos = e.target.getPosition(e.target.getParent());
					
					field.setStyles({
						top: pos.y - 1,
						left: pos.x - 1,
						position: 'absolute'
					});
				}
				else {
					field.position({
						relativeTo: e.target,
						position: 'upperLeft'
					});
				}
								
				field.inject(e.target, 'after');
				
				if (this.options.select_text) {
					field.focus();
					field.select();
				}
			}.bind(this));
		}.bind(this));
	},
	
	getStyles: function(el)
	{
		return {
			'font-family':			el.getStyle('font-family'),
			'font-size':			el.getStyle('font-size'),
			'line-height':			el.getStyle('line-height'),
			'line-spacing':			el.getStyle('line-spacing'),
			'letter-spacing':		el.getStyle('letter-spacing'),
			'font-weight':			el.getStyle('font-weight'),
			'text-align':			el.getStyle('text-align'),
//			'margin':				el.getStyle('margin'),
//			'padding':				el.getStyle('padding'),
			'border-top':			el.getStyle('border-top'),
			'border-right':			el.getStyle('border-right'),
			'border-bottom':		el.getStyle('border-bottom'),
			'border-left':			el.getStyle('border-left'),
			'background-color':		el.getStyle('background-color'),
			'background-image':		el.getStyle('background-image'),
			'background-position':	el.getStyle('background-position'),
			'background-repeat':	el.getStyle('background-repeat'),
			'background-attchment':	el.getStyle('background-attchment')			
		};
	}
});
/**
 * @author Daniel Pisanec
 * @copyright 2009 Daniel Pisanec
 * @builtOn HtmlTable
 */
var FastTable = new Class({
	Implements: Options,
	options: {
		properties: {
			cellspacing: 0,
			cellpadding: 0,
			border: 0
		},
		rows: [],
		cellsAs: 'td',
		
		head: {
			isset: false,
			type: 'head',
			rows: [],
			cellsAs: 'th',
			fixed: false
		},
		
		foot: {
			isset: false,
			type: 'foot',
			rows: [],
			cellsAs: 'th',
			fixed: false
		}
	},
	
	initialize: function(options)
	{
		this.setOptions(options);
		
		this.table = new Element('table').setProperties(this.options.properties);
		
		this.table.store('HtmlTable', this);
		
		// Table Body
		this.tbody = new Element('tbody').inject(this.table);
		this.options.rows.each(function(row) {
			this.push(row);
		}.bind(this));
		
		// Table Head
		if(this.options.head.isset) {
			this.thead = new Element('thead').inject(this.table, 'top');
			this.options.head.rows.each(function(row) {
				this.push(row, this.options.head);
			}.bind(this));
		}
		
		// Table Foot
		if(this.options.foot.isset) {
			this.tfoot = new Element('tfoot').inject(this.table, 'bottom');
			this.options.foot.rows.each(function(row) {
				this.push(row, this.options.foot);
			}.bind(this));
		}
		
		
		["adopt", "inject", "wraps", "grab", "replaces", "empty", "dispose"].each(function(method){
			this[method] = this.table[method].bind(this.table);
		}, this);
	},
	
	toElement: function()
	{
		return this.table;
	},
	
	push: function(row, part_options)
	{
		var cell_tag	= 'td';
		
		// Table Head/Foot
		if ($type(part_options) == 'object') {
			
			// Cell-Tag
			if ($type(part_options.type) == 'string') {
				cell_tag = part_options.cellsAs;
			}
			
			// Table Head
			if ($type(part_options.type) == 'string' && part_options.type == 'head') {
				var tr = new Element('tr').inject(this.thead);
			}
			// Table Foot
			else if ($type(part_options.type) == 'string' && part_options.type == 'foot') {
				var tr = new Element('tr').inject(this.tfoot);
			}
		}
		// Table Body
		else {
			var tr = new Element('tr').inject(this.tbody);
		}
		
		var tds = row.map(function (tdata) {
			tdata = tdata || '';
		
			var td = new Element(cell_tag).inject(tr);
		
			if (tdata.properties) td.setProperties(tdata.properties);
		
			function setContent(content){
				if (document.id(content)) td.adopt(document.id(content));
				else td.set('html', content);
			};
		
			if ($defined(tdata.content)) setContent(tdata.content);
			else setContent(tdata);
		
			return td;
		}, this);
		return {tr: tr, tds: tds};
	}
});
/**
 * @author Daniel Pisanec
 * @copyright 2009 Daniel Pisanec
 * @version 1.0
 * @projectDescription
 * @extends GetEl, Options, Events
 * @uses FastTable, DaxtEdit
 * 
 */

/**
 * Dalendar Class
 */
var Dalendar = new Class({
	Implements: [GetEl, Options, Events],
	
	date_selection_directions: {
		up:		['up',   '+', 'after'],
		down:	['down', '-', 'before'],
		all:	['all',  '*']
	},
	
	options: {
		date_format: 'Y-m-d',
		
		days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
		days_full: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
		week_start: 0,
		weekdays: [1,2,3,4,5],
		
		months: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
		months_full: ['January', 'February', 'March', 'April', 'Mai', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
		
		start_date: 'today',	// used if no day was selected
		
		browse: {
			month: true,
			month_elements: {
				forward: {
					element_type: 'a',
					params: {
						'class': 'forward',
						html: '+'
					}
				},
				backward: {
					element_type: 'a',
					params: {
						'class': 'backward',
						html: '-'
					}
				}
			},
			year: true,
			year_elements: {
				forward: {
					element_type: 'a',
					params: {
						'class': 'forward',
						html: 'next'
					}
				},
				backward: {
					element_type: 'a',
					params: {
						'class': 'backward',
						html: 'prev'
					}
				}
			}
		},
		
		date_selection: {

			direction: '*',
			
			include_start_date: true,
		
			info_dates: {
				days_of_year: [],
				days_of_week: [],
				dates: [],
				periods: []
			},
			
			exclude_dates: {
				days_of_year: [],
				days_of_week: [],
				dates: [],
				periods: []
			}
		},
		
		year_two_digit: {
			switch_year: 30,
			// change_year or greater
			smaller_year_prefix: 19,
			// smaller than chang_year
			bigger_year_prefix: 20
		},
		
		year_range: [1900,2100],
		
		dragable: true,
		allow_input: false,
		events_onDateSelect: ['click', 'change', 'blur'],
		close_other_calendar: true,
		
		day_title: '${day_full}, ${d}. ${month_full} ${Y} ::: ${translation.calendar_week}: ${calendar_week}',
		
		show: {
			this_month: 'full',	// false, true
			this_year: 'full',	// false, true
			days_last_month: true,
			days_next_month: true,
			calendar_week: true,
			calendar_on_form_field_focus: true,
			calendar_directly: false,
			calendar_permanent: false
		},
		
		insert_calendar_into: '',
		
		word_translation: {
			day: 'Day',
			week: 'Week',
			month: 'Month',
			year: 'Year',
			calendar_week: 'Calendar week',
			today: ['today'],
			yesterday: ['yesterday'],
			tomorrow: ['tomorrow']
		},
		
/*		ico: {
			element_type: 'a',
			id_prefix_param: 'name',
			params: {
				src:		'',
				'class':	'dalendar_ico',
				alt:		'calendar',
				title:		'click for calendar',
				style:		''
			}
		},*/
		ico: false,
		
		ie6: {
			forbid: false,
			forbid_message: 'Sorry, your browser is about ${years} years to old!',
			useIframeShim: true
		},
		
		useSimpleIeFadeFix: [true, '#ffffff'],
		
		onStart: $empty,		// 1. arg: all found form elements
		onShow: $empty,			// 1. arg: form element, 2. arg: calendar element, 3. arg: date as date, 4.arg: date as string
		onMonthChange: $empty,	// 1. arg: form_element, 2. arg: new month, 3. arg year
		onYearChange: $empty,	// 1. arg: form_element, 2. arg: new year
		onDaySelect: $empty,	// 1. arg: form_element, 2. arg: new date as date, 3.arg: new date as string
		onHide: $empty,			// 1. arg: form_element, 2. arg: calendar element
		
		addElement: {
			top: null,
			year_after: null,
			month_after: null,
			bottom: null
		},
		
		dependencies: {
			lt: [],				// lower than these elements
			gt: [],				// greater than these elements
			let: [],			// lower or equal to these elements
			get: [],			// greater or equal to these elements
			et: [],				// equal to these elements (update in calendar updates all these form fields to)
			out_of_range_name: 'out of range',
			out_of_range_class: 'out_of_range'
		}
	},
	
	initialize: function(elements, options)
	{
		if(Browser.Engine.trident4 && this.options.ie6.forbid) {
			if(this.options.ie6.forbid_message != '') {
				
				var years = new Date().getFullYear().toInt() - 2001;
				
				this.options.ie6.forbid_message = this.options.ie6.forbid_message.replace('${years}', years);
				
				alert(this.options.ie6.forbid_message);
			}
			return;
		}
		
		
		if($type(elements) == undefined) {
			elements = [$$('.dalendar')];
		}
		
		this.getEls(elements);
		
		this.setOptions(options);
		
		// fire onStart event with all found form elements
		this.fireEvent('start', this._elements);
		
		this._setMootoolsDateFormat();
		
		this._elements.each(function(element) {
			
			// retrieve unique element identifier
			if(element.getProperty('id') != null && element.getProperty('id') != '') {
				var element_identifier_arr = ['id', element.getProperty('id')];
			}
//			else if(element.getProperty('name') != null && element.getProperty('name') != '') {
//				var element_identifier_arr = ['name', element.getProperty('name')];
//			}
			else {
				throw new Error('Dalendar: Give your calendar element an unique id!');
			}
			
			// allow_input
			if(this.options.allow_input === false) {
				element.setProperty('readonly', true);
			}
			else {
				element.setProperty('readonly', false);
			}
			
			
			
			
			
			// show calendar directly
			if (this.options.show.calendar_directly) {
				if(this.options.insert_calendar_into == '') {
					throw new Error('Dalendar: No Element to show Calendar into given! Check options.insert_calendar_into!');
				}
				
				var father_el = this.getEls(this.options.insert_calendar_into);

				if(father_el.length != 1) {
					throw new Error('Dalendar: Element to place Calendar inside has to be unique! Check options.insert_calendar_into!');
				}
				
				
				var element = document.getElement('[' + element_identifier_arr[0] + '*=' + element_identifier_arr[1] + ']');
						
				this.date = this._getDateFromFormattedDate(element.getProperty('value'), this.options.date_format);
				
				var corrected_date = new Date(this.date['year'], this.date['month'], this.date['day']);
				
				document.getElement('[' + element_identifier_arr[0] + '*=' + element_identifier_arr[1] + ']').setProperty('value', corrected_date.format(this.options.mootools_date_format));
				
				// create calendar
				if (cal = this.getCalendar(element_identifier_arr[1])) {
					
					// fire onShow event with form element and calendar element
					this.fireEvent('show', [$(element_identifier_arr[1]), cal]);
					
					// include calendar
					cal.inject(father_el[0], 'top');
					
					if(Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
						new IframeShim(cal, {display: true});
					}
					
					if(Browser.Engine.trident) {
						cal.setStyle('opacity', 1);
					}
				}
			}
			
			
			
			
			
			
			
			if (this.options.ico !== false) {
				// options defined icon image
				if ($type(this.options.ico) == 'object') {
					var ico = new Element(this.options.ico.element_type);
					
					// add user parameter
					for (var param_name in this.options.ico.params) {
						ico.setProperty(param_name, this.options.ico.params[param_name]);
					}
				}
				// user icon element
				else if ($type(this.options.ico) == 'element') {
					var ico = this.options.ico;
				}
				// no valid icon
				else {
					throw new Error('Dalendar: No valid icon given! Check given options.ico!');
				}
				
				// give id to icon
				ico.setProperty('id', element_identifier_arr[1] + '_ico');
				
				// add click event
				ico = this._showCalendar(ico, 'click', element_identifier_arr);
				
				ico.inject(element, 'after');
			}
			
			
			// onFormFieldFocus
			if(this.options.show.calendar_on_form_field_focus) {
				var element = document.getElement('[' + element_identifier_arr[0] + '*=' + element_identifier_arr[1] + ']');
				// add onFocus show
				this._showCalendar(element, 'focus', element_identifier_arr);
				
				// add onBlur hide
//				this._hideCalendar(element, 'blur', element_identifier_arr);
			}
		}.bind(this));
	},
	
	showCalendarForFormfield: function(id)
	{
		if(!id) {
			throw new Error("Dalendar.showCalendarForFormfield: No form field id given!");
			return false;
		}
		
		if($(id)) {
			var el = $(id);
			
			this.date = this._getDateFromFormattedDate(el.getProperty('value'), this.options.date_format);
			
			// create calendar
			if (cal = this.getCalendar(id)) {
			
				// fire onShow event with form element and calendar element
				this.fireEvent('show', [el, cal]);
				
				// include calendar
				cal.inject(el, 'after');
			}
		}
		else {
			throw new Error("Dalendar.showCalendarForFormfield: Form field id not found!");
			return false;
		}
	},
	
	_showCalendar: function(event_el, event, element_identifier_arr)
	{
		event_el.addEvent(event, function(e)
		{
			var element = document.getElement('[' + element_identifier_arr[0] + '*=' + element_identifier_arr[1] + ']');
			var cs = document.getElements('div[id^=dalendar_]');
			
			// remove existing calendars
			if (this.options.close_other_calendar && cs.length >= 1) {
				cs.each(function(c) {
					this._destroy(c);
				}.bind(this));
			}

			// remove existing calendar
			if ($('dalendar_' + element_identifier_arr[1])) {
				this._destroy($('dalendar_' + element_identifier_arr[1]));
			}
			// show calendar
			else {

				this.date = this._getDateFromFormattedDate(element.getProperty('value'), this.options.date_format);
				
				var corrected_date = new Date(this.date['year'], this.date['month'], this.date['day']);
				
				element.setProperty('value', corrected_date.format(this.options.mootools_date_format));
				
				// create calendar
				if (cal = this.getCalendar(element_identifier_arr[1])) {
				
					// fire onShow event with form element and calendar element
					this.fireEvent('show', [$(element_identifier_arr[1]), cal]);
										
					
					// include calendar
					cal.inject(element, 'after');
					
					
					if(Browser.Engine.trident) {
						cal.setStyles({ opacity: 1, 'z-index': 10000});
						
//						if (Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
//							var ifs = new IframeShim($('dalendar_' + element_identifier_arr[1]), {display: true, onInject: function() {alert('huihu')}}).shim.setStyle('border','1px solid black');;
//							ifs.show();
//							$$('.iframeShim').setStyle('border', '2px solid #333');
//						}
					}
				}
			}
		}.bind(this));
		
		return event_el;
	},
	
	_hideCalendar: function(event_el, event, element_identifier_arr)
	{
		event_el.addEvent(event, function(e)
		{
			this._destroy($('dalendar_' + element_identifier_arr[1]));
		}.bind(this));
		
		return event_el;
	},
	
	_getDateFromFormattedDate: function(formatted_date, format, get_undefined_year)
	{
		if($type(get_undefined_year) === false || get_undefined_year != true) {
			get_undefined_year = false;
		}
		
		var date = [];
		var format_arr = format.split('');
		
		var formatted_date_index = 0;
		
		format_arr.each(function(character, index) {
			var modificator = 0;
			
			switch(character) {
				
				// 1-2 digit day
				case 'j':
					modificator = 2
					var day_dumb = formatted_date.slice(formatted_date_index, formatted_date_index + modificator);
					if(day_dumb.toInt() >= 12) {
						modificator = 1;
						day_dumb = formatted_date.slice(formatted_date_index, formatted_date_index + modificator);
					}
					date['day'] = day_dumb.toInt();
					break;
				
				// 2 digit day
				case 'd':
					modificator = 2;
					date['day'] = formatted_date.slice(formatted_date_index, formatted_date_index + modificator).toInt();
					break;
				
				// 1-2 digit month
				case 'n':
					modificator = 2;
					var month_dumb = formatted_date.slice(formatted_date_index, formatted_date_index + modificator);
					if(month_dumb.toInt() >= 12) {
						modificator = 1;
						var month_dumb = formatted_date.slice(formatted_date_index, formatted_date_index + modificator);
					}
					date['month'] = month_dumb.toInt() - 1;
					break;
				
				// 2-digit month
				case 'm':
					modificator = 2;
					date['month'] = formatted_date.slice(formatted_date_index, formatted_date_index + modificator).toInt() - 1;
					break;
				
				// 2-digit year
				case 'y':
					modificator = 2;
					var year_dumb = formatted_date.slice(formatted_date_index, formatted_date_index + modificator);
					
					if (year_dumb >= this.options.year_two_digit.switch_year) {
						date['year'] = (this.options.year_two_digit.smaller_year_prefix + '' + year_dumb).toInt();
					}
					else {
						date['year'] = (this.options.year_two_digit.bigger_year_prefix + '' + year_dumb).toInt();
					}
					break;
				
				// 4-digit year
				case 'Y':
					modificator = 4;
					date['year'] = formatted_date.slice(formatted_date_index, formatted_date_index + modificator).toInt();
					break;
					
				default:
					modificator = 1;
					break;
			}
			formatted_date_index += modificator;
		});
		
		
		
		
		//======================================
		// if no date given set to 'start_date'
		//======================================
		var day, month, year;
		
//		var start_date = this._getStartDate();
			
		// validate day
		if($type(date['day']) != 'number' || date['day'] <= 0 || date['day'] >= 32) {
			var start_date = this._getStartDate();
			date['day'] = start_date.getDate();
		}
		
		// validate month
		if($type(date['month']) != 'number' || date['month'] < 0 || date['month'] > 11) {
			var start_date = this._getStartDate();
			date['month'] = start_date.getMonth();
		}
		
		if (get_undefined_year === false) {
			// validate year
			if ($type(date['year']) != 'number' || date['year'] <= 0) {
				var start_date = this._getStartDate();
				date['year'] = start_date.getFullYear();
			}
		}
		//======================================
		
		
		
		// check year range
		if (get_undefined_year === false && $type(this.options.year_range) == 'array') {
			if (date['year'] < this.options.year_range[0]) {
				date['year'] = this.options.year_range[0];
			}
			else if (date['year'] > this.options.year_range[1]) {
				date['year'] = this.options.year_range[1];
			}
		}
		
		if($type(date['year']) === false) {
			date['year'] = false;
		}
		
		return date;
	},
	
	_getStartDate: function()
	{
		if($type(this.options.start_date) == 'object') {
			var start_date = new Date(this.options.start_date.year.toInt(), this.options.start_date.month.toInt(), this.options.start_date.day.toInt());
		}
		else {
			var start_date = new Date();
			
			// 'today'
			if (this.options.word_translation.today.contains(this.options.start_date)) {
				//
			}
			// 'yesterday'
			else if (this.options.word_translation.yesterday.contains(this.options.start_date)) {
				start_date.decrement();
			}
			// 'tomorrow'
			else if (this.options.word_translation.tomorrow.contains(this.options.start_date)) {
				start_date.increment();
			}
			// date
			else {
				var date = this._getDateFromFormattedDate(this.options.start_date, this.options.date_format);
				start_date = new Date(date.year.toInt(), date.month.toInt(), date.day.toInt());
			}
		}
		
		return start_date;
	},
	
	getCalendar: function(element_identifier)
	{
		if (this.options.ico) {
			var ico_pos = $(element_identifier + '_ico').getPosition(document.body);
			
			var cal_div = new Element('div', {
				id: 'dalendar_' + element_identifier,
				'class': 'dalendar',
				styles: {
					top: ico_pos.y + 'px',
					left: ico_pos.x + 'px'
				}
			});
		}
		else {
			var cal_div = new Element('div', {
				id: 'dalendar_' + element_identifier,
				'class': 'dalendar'
			});
		}
		
		this._checkDependencies(element_identifier);
		
		// if addElement top is set
		if($type(this.options.addElement.top) == 'element') {
			this.options.addElement.top.inject(cal_div);
		}
		
		
		// Insert Year
		if(this.options.show.this_year !== false) {
			
			var year = this.date['year'] + '';

			if(this.options.show.this_year === true) {
				year = year.slice(-2);
			}
			
			var year_el = new Element('h1', {
				'class': 'head_year',
				id: element_identifier + '_head_year',
				html: year
			});
			
			// Text-Change Event
			year_el.addEvent('textChange', function(e) {
				var prev_year = this.date.year;
				
				this.date['year'] =  $(element_identifier + '_head_year').get('html');
				
				// fire onYearChange event with new year
				this.fireEvent('onYearChange', [$(element_identifier), this.date.year, prev_year]);
				
				var new_cal = this.getCalendar(element_identifier);
				
				if(Browser.Engine.trident) {
					new_cal.setStyles({ opacity: 1, 'z-index': 10000});
					
//					if (Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
//						var ifs = new IframeShim($('dalendar_' + element_identifier_arr[1]), {display: true, onInject: function() {alert('huihu')}}).shim.setStyle('border','1px solid black');;
//						ifs.show();
//						$$('.iframeShim').setStyle('border', '2px solid #333');
//					}
				}
				
				new_cal.replaces($('dalendar_' + element_identifier));
				
				
			}.bind(this));
			
			
//			try {
//				new DaxtEdit(year_el);
//			}
//			catch(e) {
//				throw new Error("Dalendar: Problem using DaxtEdit on year-head-element!\n" + e);
//				return false;
//			}
			
			
			
			// Year Browse
			if (this.options.browse.year) {
				var back = this._getBrowseElement('year', 'backward', this.date.year, this.date.month, element_identifier);
				var fwd = this._getBrowseElement('year', 'forward', this.date.year, this.date.month, element_identifier);
				
				back.inject(cal_div);
				year_el.inject(cal_div);
				fwd.inject(cal_div);
			}
			else {
				year_el.inject(cal_div);
			}
		}
		
		// if addElement year_after is set
		if($type(this.options.addElement.year_after) == 'element') {
			this.options.addElement.year_after.inject(cal_div);
		}
		
		// Insert Month name
		if(this.options.show.this_month !== false) {
			
			var month_name = this.options.months[this.date['month']];

			if(this.options.show.this_month == 'full') {
				month_name = this.options.months_full[this.date['month']];
			}
			
			var month_el = new Element('h2', {
				'class': 'head_month',
				id: element_identifier + '_head_month',
				html: month_name 
			});
			
			
			// textChange-Event
			month_el.addEvent('textChange', function(e) {
				var prev_month = this.date.month;
								
				var new_month_str = $(element_identifier + '_head_month').get('html');
				var new_month = this.date['month'];
				
				// Month number given
				if(new_month_str.toInt() >= 1 && new_month_str.toInt() <= 12) {
					new_month = new_month_str.toInt() - 1;
				}
				// month as text given
				else {
					new_month =  this.options.months_full.indexOf(new_month_str);
					
					// check new month, if months and months_full fails, set value of before
					if(new_month == -1) {
						new_month = this.options.months.indexOf(new_month_str);
						
						if(new_month == -1) {
							new_month = this.date['month'];
						}
					}
				}
				
				if ($type(new_month) == 'number') {
					this.date['month'] = new_month;
					
					// fire onMonthChange event with new month
					this.fireEvent('onMonthChange', [$(element_identifier), this.date.month + 1, prev_month + 1]);
							
					var new_cal = this.getCalendar(element_identifier);
					
					if(Browser.Engine.trident) {
						new_cal.setStyles({ opacity: 1, 'z-index': 10000});
						
//						if (Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
//							var ifs = new IframeShim($('dalendar_' + element_identifier_arr[1]), {display: true, onInject: function() {alert('huihu')}}).shim.setStyle('border','1px solid black');;
//							ifs.show();
//							$$('.iframeShim').setStyle('border', '2px solid #333');
//						}
					}
					
					new_cal.replaces($('dalendar_' + element_identifier));
					
				}
			}.bind(this));
			
//			try {
//				new DaxtEdit(month_el);
//			}
//			catch(e) {
//				throw new Error("Dalendar: Problem using DaxtEdit on month-head-element!\n" + e);
//				return false;
//			}
			
			
			// Month browse
			if(this.options.browse.month) {
				var back = this._getBrowseElement('month', 'backward', this.date.year, this.date.month, element_identifier);
				var fwd = this._getBrowseElement('month', 'forward', this.date.year, this.date.month, element_identifier);
				
				back.inject(cal_div);
				month_el.inject(cal_div);
				fwd.inject(cal_div);
			}
			else {
				month_el.inject(cal_div);
			}
		}
		
		
		// if addElement month_after is set
		if($type(this.options.addElement.month_after) == 'element') {
			this.options.addElement.month_after.inject(cal_div);
		}
		
		
		// detected active date
		this.active_date = this._getDateFromFormattedDate($(element_identifier).getProperty('value'), this.options.date_format);
		
		this._getDaysArrayForDate(this.date, element_identifier);
		
		try {
			new FastTable();
		}
		catch(e) {
			throw new Error('Dalendar: Dalendar needs FastTable!');
			return false;
		}
		
		
		//======================
		// insert Table
		//======================
		var table_options = {
			properties: {
				cellspacing: 0,
				cellpadding: 0,
				border: 0
			},
			rows: this._months_days,
			cellsAs: 'td',
			
			head: {
				isset: true,
				type: 'head',
				rows: [this._getDaysHeadRow()],
				cellsAs: 'th',
				fixed: false
			},
			
			foot: {
				isset: false,
				type: 'foot',
				rows: [this._getDaysHeadRow()],
				cellsAs: 'th',
				fixed: false
			}
		}
		
		this.table = new FastTable(table_options);
		
		this.table.inject(cal_div)
		//======================
		
		// if addElement bottom is set
		if($type(this.options.addElement.bottom) == 'element') {
			this.options.addElement.bottom.inject(cal_div);
		}
		
		// add Events
		cal_div.getElements('td[id^=' + element_identifier + ']').each(function(td) {
			
			// only make days selectable, which does not have class 'no_select'
			if(td.hasClass('no_select') == false) {
				td.addEvent('click', function(e) {
					var date_str = e.target.getProperty('id').replace(element_identifier + '_', '');

					var year	= date_str.slice(0, 4);
					var month	= date_str.slice(4, 6); 
					var day		= date_str.slice(6, 8);
					
					var new_date = new Date(year, month.toInt() -1 , day).format(this.options.mootools_date_format);
					
					// set new value
					$(element_identifier).setProperty('value', new_date);
					
					// if dependencies is set to equal to
					if(this.options.dependencies.et.length >= 1) {
						this.options.dependencies.et.each(function(equal_field) {
							equal_field.setProperty('value', new_date);
						});
					}
					
					
					if (this.options.show.calendar_permanent === true) {
					
						this.date.year	= year;
						this.date.month	= month.toInt() - 1;
						this.date.day	= day;
						
						var new_cal = this.getCalendar(element_identifier);
						new_cal.replaces($('dalendar_' + element_identifier));
					}
					else {
						// remove Calendar
						this._destroy($('dalendar_' + element_identifier));
					}
					
					this.fireEvent('daySelect', [$(element_identifier), {day: day, month: month, year: year}, new Date(year, month.toInt() -1 , day)]);
					
					// trigger events
					this.options.events_onDateSelect.each(function(event_name) {
						$(element_identifier).fireEvent(event_name);
					});
				}.bind(this));
			}
		}.bind(this));
		
		
		if (this.options.show.calendar_permanent === false) {
			// dragable
			if(this.options.dragable === true) {
				this.makeDragable(cal_div);
			}
		
		
			document.removeEvents('click');
			// remove calendar onClick outside
			document.addEvent('click', function(e)
			{
				if (e.target == document || e.target == document.body) {
					// remove Calendar
					this._destroy($('dalendar_' + element_identifier));
					document.removeEvents('click');
				}
				else {
//					var parent = e.target.getParent('[id=dalendar_' + element_identifier + ']');
					try {
						var parent = e.target.getParent('[id^=dalendar_]');
					}
					catch(e) {
						var parent = null;
					}

					if (e.target != $('dalendar_' + element_identifier) && parent != $('dalendar_' + element_identifier) && e.target != $(element_identifier) && e.target != $(element_identifier + '_ico')) {
						// remove Calendar
						this._destroy($('dalendar_' + element_identifier));
						document.removeEvents('click');
					}
				}
			}.bind(this));
		}
		
		return cal_div;
	},
	
	_getDaysHeadRow: function()
	{
		var days_row = [];
		
		if (this.options.show.calendar_week) {
			days_row.include({
				properties: {
					'class': 'days calendar_week_head'
				},
				content: '&nbsp;'
			});
		}
		
		// go through the days
		for (var cnt = 0; cnt <= 6; cnt++)
		{
			if(this.options.week_start + cnt > 6) {
				var day = this.options.week_start + cnt - 7;
			}
			else {
				var day = this.options.week_start + cnt;
			}

			days_row.include({
				properties: {
					'class': 'days days_head'
				},
				content: this.options.days[day]
			});
		};
		
		return days_row;
	},
	
	_getDaysArrayForDate: function(date_obj, element_identifier)
	{
		if (this.options.show.calendar_week) {
			this._months_days = [[], [], [], [], [], [], [], []];
			var day_max = 8;
		}
		else {
			this._months_days = [[], [], [], [], [], [], []];
			var day_max = 7;
		}
		var week_cnt = 0;
		
		var first_day = new Date(date_obj.year, date_obj.month, 1);
		
		var days_before = first_day.getDay() - this.options.week_start;

		if (days_before > 0 || days_before < 0) {
			if (days_before < 0) {
				days_before = days_before + 7;
			}
		}
		
		// for all days
		for(var d = 1; d <= 42; d++)
		{
			var date = new Date(date_obj.year, date_obj.month, d);
			
			date.decrement('day', days_before);
			
			if(this.options.show.calendar_week && d === 1) {
				this._months_days[week_cnt].include({
					properties: {
						'class': 'calendar_week',
						title:  this.options.word_translation.calendar_week + ': ' + date.getWeek()
					},
					content: date.getWeek()
				});
			}
			
			// if week is full, increase week_cnt
			if(this._months_days[week_cnt].length >= day_max) {
				week_cnt++;
				if (this.options.show.calendar_week) {
					this._months_days[week_cnt].include({
						properties: {
							'class': 'calendar_week',
							title: this.options.word_translation.calendar_week + ': ' + date.getWeek()
						},
						content: date.getWeek()
					});
				}
			}
			
			
			

			
			var extra_classes	= '';
			var day_name 		= '';
			
			// detect weekday
			if(this.options.weekdays.contains(date.getDay())) {
				extra_classes += ' weekday';
			}
			else {
				extra_classes += ' weekend';
			}
			
			
			
			var today = new Date();
			// mark selected day
			if(date.getDate() == today.getDate() && date.getFullYear() == today.getFullYear() && date.getMonth() == today.getMonth()) {
				extra_classes += ' today';
			}
			
			// mark selected day
			if(date.getDate() == this.active_date.day && date.getFullYear() == this.active_date.year && date.getMonth() == this.active_date.month) {
				extra_classes += ' active';
			}
			
			
			
			//======================================
			// check against 'date_selection'
			//======================================			
			// date direction
			if(this.date_selection_directions.all.contains(this.options.date_selection.direction) == false) {
				var start_date = this._getStartDate();
				
				day		= start_date.getDate();
				month	= start_date.getMonth();
				year	= start_date.getFullYear();
				
				// downwards
				if (this.date_selection_directions.down.contains(this.options.date_selection.direction)) {
					
					// year is bigger
					if(date.getFullYear() > year) {
						extra_classes += ' no_select';
					}
					// year is equal -> check month
					else if(date.getFullYear() == year) {
						
						// month is bigger
						if(date.getMonth() > month) {
							extra_classes += ' no_select';
						}
						
						//month is equal -> check day
						else if(date.getMonth() == month) {
							
							// day is bigger
							if((this.options.date_selection.include_start_date == false && date.getDate() >= day)
								|| (this.options.date_selection.include_start_date && date.getDate() > day)) {
									
									extra_classes += ' no_select';
							}
						}
					}
				}
				
				// upwards
				else if (this.date_selection_directions.up.contains(this.options.date_selection.direction)) {

					// year is smaller
					if(date.getFullYear() < year) {
						extra_classes += ' no_select';
					}
					// year is equal -> check month
					else if(date.getFullYear() == year) {
						
						// month is smaller
						if(date.getMonth() < month) {
							extra_classes += ' no_select';
						}
						//month is equal -> check day
						else if(date.getMonth() == month) {
							
							// day is smaller
							if((this.options.date_selection.include_start_date == false && date.getDate() <= day)
								|| (this.options.date_selection.include_start_date && date.getDate() < day)) {
									
									extra_classes += ' no_select';
							}
						}
					}
				}
				
				// unknown
				else {
					throw new Error('Dalendar: Unknown date selection direction in: options.date_selection_direction!');
				}
			}
			
			var dummy		= this._getDataForSpecialDates('info_dates', date);
			day_name		+= dummy[0];
			extra_classes	+= dummy[1];
			
			var dummy		= this._getDataForSpecialDates('exclude_dates', date);
			day_name 		+= dummy[0];
			extra_classes	+= dummy[1];
			
			
			if(day_name != '') {
				day_name = ' (' + day_name.slice(1) + ')';
			}
			
			
			var month_diff = date.getMonth() - date_obj.month;
			
			// detect last and next month
			if(month_diff < 0) {
				extra_classes += ' last_month';
			}
			else if(month_diff > 0) {
				extra_classes += ' next_month';
			}
			
			var content = date.getDate();
			
			// set content for last and next month
			if ((month_diff < 0 && this.options.show.days_last_month === false) || (month_diff > 0 && this.options.show.days_next_month === false)) {
				content = '&nbsp;';
			}
			
			var day_obj = {
				properties: {
					'class': 'days ' + this.options.days[date.getDay()] + extra_classes,
					title:  this._getDayTitle(date) + day_name,
					id: element_identifier + '_' + date.format('%Y%m%d')						
				},
				content: content
			};
			
			this._months_days[week_cnt].include(day_obj);
		}
	},
	
	_getDayTitle: function(date)
	{
		var m = date.getMonth() + 1;
		var d = date.getDate();

		var tvars = {
			'${Y}':				date.getFullYear(),
			'${y}':				date.getYear(),
			'${m}':				(m <= 10) ? '0' + m : m,
			'${n}':				m,
			'${d}':				(d <= 10) ? '0' + d : d,
			'${j}':				d,
			'${day}':			this.options.days[date.getDay()],
			'${day_full}':		this.options.days_full[date.getDay()],
			'${month}':			this.options.months[date.getMonth()],
			'${month_full}':	this.options.months_full[date.getMonth()],
			'${day_of_year}':	date.getDayOfYear(),
			'${calendar_week}':	date.getWeek(),
			
			'${translation.day}':			this.options.word_translation.day,
			'${translation.week}':			this.options.word_translation.week,
			'${translation.month}':			this.options.word_translation.month,
			'${translation.year}':			this.options.word_translation.year,
			'${translation.calendar_week}':	this.options.word_translation.calendar_week
		};
		var day_title = this.options.day_title;
		
		for(var var_name in tvars)
		{
			
			day_title = day_title.replace(var_name, tvars[var_name]);
		}
		
		return day_title;
	},
	
	_getDataForSpecialDates: function(special_date_type, date)
	{
		if ($type(this.options.date_selection[special_date_type]) == 'object') {
			var day_name = '';
			var extra_classes = '';
			var extra_classes_std = '';
			
			switch(special_date_type) {
				case 'exclude_dates':
					extra_classes_std = ' no_select';
					break;
				
				case 'info_dates':
					extra_classes_std = ' info_date';
					break;
				
				default:
					return ['',''];
			}
			
			// 'days_of_year'
			if (this.options.date_selection[special_date_type].days_of_year.length >= 1) {
				
				this.options.date_selection[special_date_type].days_of_year.each(function(sp_doy) {
					if(sp_doy.day_no == date.getDayOfYear()) {
						// css_class
						if ($type(sp_doy.css_class) == 'string' && sp_doy.css_class != '') {
							extra_classes += ' ' + sp_doy.css_class;
						}
						
						if ($type(sp_doy.name) == 'string' && sp_doy.name != '') {
							day_name = sp_doy.name;
						}
					}
				});
			}
			
			// 'days_of_week'
			if (this.options.date_selection[special_date_type].days_of_week.length >= 1) {
				
				this.options.date_selection[special_date_type].days_of_week.each(function(sp_dow) {
					if(sp_dow.day_no == date.getDay()) {
						// css_class
						if ($type(sp_dow.css_class) == 'string' && sp_dow.css_class != '') {
							extra_classes += ' ' + sp_dow.css_class;
						}
						
						if ($type(sp_dow.name) == 'string' && sp_dow.name != '') {
							day_name = sp_dow.name;
						}
					}
				});
			}
			
			// 'dates'
			if (this.options.date_selection[special_date_type].dates.length >= 1) {
			
				this.options.date_selection[special_date_type].dates.each(function(sp_date)
				{
				
					// if format is NOT given take options.date_format
					if ($type(sp_date.format) === false || sp_date.format == '') {
						sp_date.format = this.options.date_format;
					}
					
					var exclude_date = this._getDateFromFormattedDate(sp_date.date, sp_date.format, true);
					
					// all years
					if (exclude_date.year === false) {
						if (exclude_date.month == date.getMonth() &&
						exclude_date.day == date.getDate()) {
						
							if (extra_classes.search('no_select') == -1) {
								extra_classes += extra_classes_std;
							}
							
							// day_name
							if ($type(sp_date.name) == 'string' && sp_date.name != '') {
								day_name += ' ' + sp_date.name;
							}
							
							// css_class
							if ($type(sp_date.css_class) == 'string' && sp_date.css_class != '') {
								extra_classes += ' ' + sp_date.css_class;
							}
						}
					}
					// specific dates
					else {
						if (exclude_date.year == date.getFullYear() &&
						exclude_date.month == date.getMonth() &&
						exclude_date.day == date.getDate()) {
						
							if (extra_classes.search('no_select') == -1) {
								extra_classes += extra_classes_std;
							}
							
							// day_name
							if ($type(sp_date.name) == 'string' && sp_date.name != '') {
								day_name += ' ' + sp_date.name;
							}
							
							// css_class
							if ($type(sp_date.css_class) == 'string' && sp_date.css_class != '') {
								extra_classes += ' ' + sp_date.css_class;
							}
						}
					}
				}.bind(this));
			}
			
			// 'period'
			if (this.options.date_selection[special_date_type].periods.length >= 1) {
			
				this.options.date_selection[special_date_type].periods.each(function(sp_period)
				{
				
					// if format is NOT given take options.date_format
					if ($type(sp_period.format) === false || sp_period.format == '') {
						sp_period.format = this.options.date_format;
					}
					
					if (!sp_period.from || sp_period.from == '') {
						var sp_date_from = false;
					}
					else {
						var sp_date_from = this._getDateFromFormattedDate(sp_period.from, sp_period.format, true);
					}
					
					if (!sp_period.to || sp_period.to == '') {
						var sp_date_to = false;
					}
					else {
						var sp_date_to = this._getDateFromFormattedDate(sp_period.to, sp_period.format, true);
					}
					
					
					var check_to = false;
					var is_excluded_date = false;

					// year is later than from.year
					if (sp_date_from.year !== false && date.getFullYear() > sp_date_from.year) {
						check_to = true;
					}
					// year is equal to from.year -> check month
					else if (date.getFullYear() == sp_date_from.year || sp_date_from.year === false) {

						// month is later than from.month
						if (date.getMonth() > sp_date_from.month) {

							check_to = true;
						}
						// year is equal to from.month -> check day
						else if (date.getMonth() == sp_date_from.month) {

							// day is later than from.day
							if (date.getDate() >= sp_date_from.day) {

								check_to = true;
							}
						}
					}
					
					
					// if date is >= FROM 
					if(check_to && sp_date_to === false) {
						is_excluded_date = true;
					}
					else if (check_to || sp_date_from === false) {
					
						// year is later than from.year
						if (sp_date_to.year !== false && date.getFullYear() < sp_date_to.year) {
							is_excluded_date = true;
						}
						// year is equal to from.year -> check month
						else if (date.getFullYear() == sp_date_to.year || sp_date_to.year === false) {
						
							// month is later than from.month
							if (date.getMonth() < sp_date_to.month) {
							
								is_excluded_date = true;
							}
							// year is equal to from.month -> check day
							else if (date.getMonth() == sp_date_to.month) {
							
								// day is later than from.day
								if (date.getDate() <= sp_date_to.day) {
								
									is_excluded_date = true;
								}
							}
						}
					}
					
					// if date is >= FROM and <= TO
					if (is_excluded_date) {
						if (extra_classes.search('no_select') == -1) {
							extra_classes += extra_classes_std;
						}
						
						// day_name
						if ($type(sp_period.name) == 'string' && sp_period.name != '') {
							day_name += ' ' + sp_period.name;
						}
						
						// css_class
						if ($type(sp_period.css_class) == 'string' && sp_period.css_class != '') {
							extra_classes += ' ' + sp_period.css_class;
						}
					}
					
				}.bind(this));
			}
		//======================================
		}
		return [day_name, extra_classes];
	},
	
	_destroy: function(element)
	{
		// if ie and ieFadeFix
		if(Browser.Engine.trident && this.options.useSimpleIeFadeFix[0]) {
			// detected if element has a png-background image
			var bg = element.getStyle('background-image');
			
			if(bg.search('.png') != -1) {
				element.setStyle('background-color', this.options.useSimpleIeFadeFix[1]);
			}
			// if no png-background image set zoom:1 to element
			else {
				element.setStyle('zoom', '1');
			}
		}
		
		// fire onHide event with form element and calendar element
		this.fireEvent('hide', [element]);
		
		var fx = new Fx.Morph(element, {duration: 500});
		
		fx.start({
			opacity: 0
		}).chain(function() {
			if(Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
				$$('.iframeShim').destroy();
			}
			element.destroy();
		}.bind(this));
	},
	
	_setMootoolsDateFormat: function()
	{
		if(this.options.date_format) {
			this.options.mootools_date_format = this.options.date_format.replace('d', '%d');
			this.options.mootools_date_format = this.options.mootools_date_format.replace('m', '%m');
			this.options.mootools_date_format = this.options.mootools_date_format.replace('y', '%y');
			this.options.mootools_date_format = this.options.mootools_date_format.replace('Y', '%Y');
		}
	},
	
	makeDragable: function(element)
	{
		var drag = new Drag.Move(element);
		
		drag.detach();
	 
		$(element).addEvents({
			'mousedown': function(e){
				
				if($(e.target) == this) {

					drag.attach();
					drag.start(e);
				}
			},
			'mouseup': function(){
				drag.detach();
			}
		});
	},
	
	
	_getBrowseElement: function(browse_type, browse_direction, year, month, element_identifier)
	{
		var browse_year = year.toInt();
		var browse_month = month.toInt();
		
		// year browse
		if(browse_type == 'year') {
			browse_year = (browse_direction == 'forward') ? browse_year = browse_year + 1 : browse_year = browse_year - 1;
			browse_month = '';
		}
		// month browse
		else {
			browse_month = (browse_direction == 'forward') ? browse_month = browse_month + 1 : browse_month = browse_month - 1;
			
			if(browse_month < 0) {
				browse_month	= 11;
				browse_year = browse_year - 1;
			}
			if(browse_month > 11) {
				browse_month = 0;
				browse_year = browse_year + 1;
			}
		}
		
		// options defined button
		if ($type(this.options.browse[browse_type + '_elements'][browse_direction]) == 'object') {
			var el = new Element(this.options.browse[browse_type + '_elements'][browse_direction].element_type);
			
			// add user parameter
			for (var param_name in this.options.browse[browse_type + '_elements'][browse_direction].params) {
				el.setProperty(param_name, this.options.browse[browse_type + '_elements'][browse_direction].params[param_name]);
			}
		}
		// user element
		else if ($type(this.options.browse[browse_type + '_elements'][browse_direction]) == 'element') {
			var el = this.options.browse[browse_type + '_elements'][browse_direction];
		}
		else {
			var default_content = (browse_direction == 'forward') ? '&lt;' : '&gt;';
			
			var el = new Element('a', {
				href: '#',
				'class': browse_type + '_browse_' + browse_direction,
				html: default_content
			});
		}

		el.setProperty('name', browse_type + '_' + browse_year + browse_month).addEvent('click', function(e)
		{
			e.stop();
//			var date_str = e.target.getProperty('name').replace(browse_type + '_', '');
//			var date_str = browse_year + browse_month;
			
//			this.date.year	= date_str.slice(0,4).toInt();
			this.date.year	= browse_year;
			
			if (this.date.year != year) {
				// fire onMonthChange event with new month
				this.fireEvent('onYearChange', [$(element_identifier), this.date.year, year]);
			}

			if ($type(browse_month) == 'number') {
//				this.date.month = date_str.slice(4).toInt();
				this.date.month = browse_month;

				// fire onMonthChange event with new month
				this.fireEvent('onMonthChange', [$(element_identifier), this.date.month + 1, month + 1]);
			}

			
			if(Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
				$('dalendar_' + element_identifier).retrieve('IframeShim').destroy();
			}
			
			var new_cal = this.getCalendar(element_identifier);
			new_cal.replaces($('dalendar_' + element_identifier));
			
			
			if(Browser.Engine.trident) {
				new_cal.setStyles({ opacity: 1, 'z-index': 10000});
				
				if(Browser.Engine.trident4 && this.options.ie6.useIframeShim) {
					new IframeShim(new_cal, {display: true});
				}
			}
						
		}.bind(this));
		
		
		return el;
	},
	
	_checkDependencies: function(element_identifier)
	{
		var new_periods = [];
		// remove old out_of_range types
		this.options.date_selection.exclude_dates.periods.each(function(p) {
			if(!$type(p.outOfRange)) {
				new_periods.include(p);
			}
		});
		this.options.date_selection.exclude_dates.periods = new_periods;
		
		var current_date = this._getDateFromFormattedDate($(element_identifier).getProperty('value'), this.options.date_format);
		var currendDate = new Date(current_date.year, current_date.month, current_date.day);
		
		// LOWER THAN
		if(this.options.dependencies.lt.length >= 1) {
			this._checkForDependencyType('lt', currendDate, element_identifier);
		}
		
		// LOWER THAN OR EQUAL
		if(this.options.dependencies.let.length >= 1) {
			this._checkForDependencyType('let', currendDate, element_identifier);
		}
		
		// GREATER THAN
		if(this.options.dependencies.gt.length >= 1) {
			this._checkForDependencyType('gt', currendDate, element_identifier);
		}
		
		// GREATER THAN OR EQUAL
		if(this.options.dependencies.get.length >= 1) {
			this._checkForDependencyType('get', currendDate, element_identifier);
		}
	},
	
	_checkForDependencyType: function(type, currendDate, element_identifier)
	{
		// create dates array
		var dates = [];
		this.options.dependencies[type].each(function(el) {
			dates.include(this._getDateFromFormattedDate(el.getProperty('value'), this.options.date_format));
		}.bind(this));
		
		// get lowest date
		var max_date = this._getMaximumDate(dates, type);
		
		var maxDate = new Date();
		maxDate.setTime(max_date);
		
		// check selected date against maximum date, if inside, current date in field is out of range, so it is set to max date
		if((type.slice(0,1) == 'l' && currendDate.getTime() >= max_date) || (type.slice(0,1) == 'g' && currendDate.getTime() <= max_date)) {
			
			// set date to maximum date
			this.date = {year: maxDate.getFullYear(), month: maxDate.getMonth(), day: maxDate.getDate()};
			
			// set form field to maximum date
			$(element_identifier).setProperty('value', maxDate.format(this.options.mootools_date_format));
		}
		
		var month = maxDate.getMonth() + 1;
		if(month < 10) {
			month = '0' + month;
		}
		
		if (type.slice(0, 1) == 'l') {
			// set exclude period for LOWER THAN
			this.options.date_selection.exclude_dates.periods.include({
				format: 'Y-m-d',
				from: maxDate.getFullYear() + '-' + month + '-' + maxDate.getDate(),
				to: '',
				name: this.options.dependencies.out_of_range_name,
				css_class: this.options.dependencies.out_of_range_class,
				outOfRange: true
			});
		}
		else {
			// set exclude period for GREATER THAN
			this.options.date_selection.exclude_dates.periods.include({
				format: 'Y-m-d',
				from: '',
				to: maxDate.getFullYear() + '-' + month + '-' + maxDate.getDate(),
				name: this.options.dependencies.out_of_range_name,
				css_class: this.options.dependencies.out_of_range_class,
				outOfRange: true
			});
		}
	},
	
	_getMaximumDate: function(dates, direction)
	{
		var maximum_date = null;
		
		if(direction == 'lt') {
			dates.each(function(date) {
				var date = new Date(date.year, date.month, date.day).getTime();
				
				if(maximum_date == null || maximum_date > date) {
					maximum_date = date;
				}
			});
		}
		else if(direction == 'gt') {
			dates.each(function(date) {
				var date = new Date(date.year, date.month, date.day).getTime();
				
				if(maximum_date == null || maximum_date < date) {
					maximum_date = date;
				}
			});
		}
		else if(direction == 'let') {
			dates.each(function(date) {
				var date = new Date(date.year, date.month, date.day).getTime() + (24 * 3600000);
				
				if(maximum_date == null || maximum_date > date) {
					maximum_date = date;
				}
			});
		}
		else if(direction == 'get') {
			dates.each(function(date) {
				var date = new Date(date.year, date.month, date.day).getTime() - (24 * 3600000);
				
				if(maximum_date == null || maximum_date < date) {
					maximum_date = date;
				}
			});
		}
		
		return maximum_date;
	}
});
/**
 * German Localization of Dalendar
 */
var DalendarDe = new Class({
	Extends: Dalendar,
	options: {
		date_format: 'd.m.Y',
		
		days: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
		days_full: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
		week_start: 1,	// Montag
		weekdays: [1,2,3,4,5],
		
		months: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
		months_full: ['Januar', 'Februar', 'M&auml;rz', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
		
		start_date: 'heute',
		
		word_translation: {
			day: 'Tag',
			week: 'Woche',
			month: 'Monat',
			year: 'Jahr',
			calendar_week: 'Kalenderwoche',
			today: ['today', 'heute'],
			yesterday: ['yesterday', 'gestern'],
			tomorrow: ['tomorrow', 'morgen']
		}
	}
});
