function calendar(callback, frame, formelements, date, apply, config)
{
	this.lang = {
		date: {
			days: {
				1: {fullname:'Montag',shortname:'Mo'},
				2: {fullname:'Dienstag',shortname:'Di'},
				3: {fullname:'Mittwoch',shortname:'Mi'},
				4: {fullname:'Donnerstag',shortname:'Do'},
				5: {fullname:'Freitag',shortname:'Fr'},
				6: {fullname:'Samstag',shortname:'Sa'},
				0: {fullname:'Sonntag',shortname:'So'}
			},
			months: {
				0: 'Januar',
				1: 'Februar',
				2: 'März',
				3: 'April',
				4: 'Mai',
				5: 'Juni',
				6: 'Juli',
				7: 'August',
				8: 'September',
				9: 'Oktober',
				10: 'November',
				11: 'Dezember'
			}
		}
	};
	
	this.config = {
		range: {},
		disallowthisdate: false
	};

	this.calc;
	this.renderer;
	
	this.htmlElement;
	
	this.callback;
	this.frame;
	
	this.year;
	this.month;
	
	this.value = {};
	
	this.formelements;
	
	
	
	this.construct = function(callback, frame, formelements, date, apply, config)
	{
		var rangeto, x;
		
		apply = (apply === true) ? true : false;
		config = config || {};
		
		
		this.calc = new calendar_calc();
		this.renderer = new calendar_renderer(this);
		
		this.callback = callback;
		this.frame = frame;
		this.formelements = formelements;
		
		for (x in config) {
			this.config[x] = config[x];
		}
		
		this.curdate = this.calc.curdate();
		
		date = (date != undefined) ? date : (formelements.year.value != '') ? new Date(formelements.year.value, formelements.month.value, formelements.day.value) : new Date();
		
		this.year = date.getFullYear();
		this.month = date.getMonth();
		
		this.config.range.from = {
			year: this.curdate.getFullYear(),
			month: this.curdate.getMonth(),
			day: 1
		};
		
		rangeto = this.calc.addmonth(this.config.range.from.year, this.config.range.from.month, this.config.range.from.day, 14);
		this.config.range.to = {
			year: rangeto.getFullYear(),
			month: rangeto.getMonth(),
			day: rangeto.getDate()
		}
		
		this.loadItems();
		
		this.render();
		
		
		if (apply) {
			this.setValue(this.year, this.month, date.getDate());
		}
	}

	this.next = function()
	{
		this.unsetValue();
		
		var nextmonth = this.calc.nextmonth(this.year, this.month);

		this.year = nextmonth.getFullYear();
		this.month = nextmonth.getMonth();

		this.callback(this, 3);

		this.loadItems();
		this.render();
	}

	this.prev = function()
	{
		this.unsetValue();
		
		var prevmonth = this.calc.prevmonth(this.year, this.month);
		
		this.year = prevmonth.getFullYear();
		this.month = prevmonth.getMonth();
		
		this.callback(this, 2);

		this.loadItems();
		this.render();
	}

	this.unsetValue = function()
	{
		this.value = {};
		
		this.formelements['year'].value = '';
		this.formelements['month'].value = '';
		this.formelements['day'].value = '';
		
		elements = this.htmlElement.getElementsByTagName('tbody')[0].getElementsByTagName('a');
		for (i = 0; i < elements.length; i++) {
			elements[i].className = '';
		}
	}
	
	this.setValue = function(year, month, day, event)
	{
		var element, elements;
		
		this.value = {
			year:year,
			month:month,
			day:day
		};
		// alert("setValue:"+day+":"+month+":"+year)
		
		this.formelements['year'].value = this.value.year;
		this.formelements['month'].value = this.value.month;
		this.formelements['day'].value = this.value.day;
		
		this.year = this.value.year;
		this.month = this.value.month;
		
		elements = this.htmlElement.getElementsByTagName('tbody')[0].getElementsByTagName('a');
		element = document.getElementById(this.frame.id + '-' + year + '-' + month + '-' + day);
		
		if (!element || value.month != this.month) {
			this.loadItems();
			this.render();
			
			element = document.getElementById(this.frame.id + '-' + year + '-' + month + '-' + day);
		}

		for (i = 0; i < elements.length; i++) {
			if (element && elements[i].id != element.id) {
				elements[i].className = '';
			}
		}
		if (element) {
			element.className = 'active';
			//alert("setValue:"+day+":"+month+":"+year+" -> "+element.id);			
		}
		
		if (event) {
			this.callback(this, 1, this.value);
		}
	}
	
	this.loadItems = function()
	{
		var firstdate = this.calc.firstdate(this.year, this.month);
		var lastdate = this.calc.lastdate(this.year, this.month);
		
		var xtp = (firstdate.getDay() == 0) ? 1 : (8 - firstdate.getDay());
		var rows = Math.ceil((this.calc.days(this.year,this.month) + (7 - xtp)) / 7);

		var daycnt = xtp - 6;
		
		this.items = new Array();
		
		for (i = 0; i < rows; i++) {
			for (j = 0; j < 7; j++, daycnt++) {
				this.items.push(new Date(this.year, this.month, daycnt));
			}
		}
	}
	
	this.render = function()
	{
		this.htmlElement = this.renderer.render(this.items);
	}
	
	this.construct(callback, frame, formelements, date, apply, config);

	
}