function mDate(){



	// ----------------------------------------------------------------------------------------------------------------
	// MEMBER VARIABLES
	// ----------------------------------------------------------------------------------------------------------------
	this.serial = 0;	// 1600-01-01



	// ----------------------------------------------------------------------------------------------------------------
	// MEMBER FUNCTIONS
	// ----------------------------------------------------------------------------------------------------------------
	this.copy		= function(){var r = new mDate(this.serial); return r;}
	// ----------------------------------------------------------------------------------------------------------------
	this.getWeekday	= function(){return ((this.serial + 5) % 7);}
	this.getMonday	= function(){var r = new mDate(this.serial); r.dec(this.getWeekday()); return r;} 
	this.getYear	= function(){return deserialize(this.serial)[0];}
	this.getMonth	= function(){return deserialize(this.serial)[1];}
	this.getDay		= function(){return deserialize(this.serial)[2];}
	// ----------------------------------------------------------------------------------------------------------------
	this.eq			= function(d){return this.serial == d.serial;}
	this.lt			= function(d){return this.serial <  d.serial;}
	this.le			= function(d){return this.serial <= d.serial;}
	this.gt			= function(d){return this.serial >  d.serial;}
	this.ge			= function(d){return this.serial >= d.serial;}
	this.ne			= function(d){return this.serial != d.serial;}
	// ----------------------------------------------------------------------------------------------------------------
	this.plus		= function(n){	var r = new mDate(this.serial); r.inc(n); return r;}
	this.minus		= function(n){	var r = new mDate(this.serial); r.dec(n);	return r;}
	// ----------------------------------------------------------------------------------------------------------------
	this.inc		= function(n){	this.serial += n;}
	this.dec		= function(n){	if((this.serial - n) >= 0) this.serial -= n;}		
	// ----------------------------------------------------------------------------------------------------------------
	this.getYMD = function(){
		var d = deserialize(this.serial);
		return fYMD(d[0], d[1], d[2]);
	}
	// ----------------------------------------------------------------------------------------------------------------
	this.getSerial = function(){
		return this.serial;
	}
	// ----------------------------------------------------------------------------------------------------------------
	this.set = function(){
		var nArgs = mDate.arguments.length;
		if		(nArgs == 0){
			var d = new Date();
			this.serial = serialize(d.getFullYear(), d.getMonth() + 1, d.getDate());
		}
		else if	(nArgs == 1){
			if(isNaN(mDate.arguments[0])){
				if(/^(\d{4})-(\d\d)-(\d\d)$/.exec(mDate.arguments[0])){
					this.serial = serialize(RegExp.$1, RegExp.$2, RegExp.$3);
				}
				else{
					alert('mDate.set: Parameter \'' + mDate.arguments[0] + '\' is invalid.');
				}
			}
			else{
				this.serial = Math.abs(Math.floor(mDate.arguments[0]));
			}
		}
		else if	(nArgs == 3){
			this.serial = serialize(convertToInt(mDate.arguments[0]), convertToInt(mDate.arguments[1]), convertToInt(mDate.arguments[2]));
		}
		else{
			alert('mDate.set: Invalid number of parameters: \'' + mDate.arguments.length + '.');
		}
	}





	// ----------------------------------------------------------------------------------------------------------------
	// CONSTRUCTION
	// ----------------------------------------------------------------------------------------------------------------
	this.set.arguments = mDate.arguments;
	this.set();




	// ----------------------------------------------------------------------------------------------------------------
	// INTERNAL HELPERS
	// ----------------------------------------------------------------------------------------------------------------
	function leapYear(year){
		if(year % 400 == 0) return true;
		if(year % 100 == 0) return false;
		if(year %   4 == 0) return true;
		return false;
	}
	// ----------------------------------------------------------------------------------------------------------------
	function validateYMD(year, month, day){

		if(year	 != Math.floor(year))	return false;
		if(month != Math.floor(month))	return false;
		if(day	 != Math.floor(day))	return false;

		if((year	< 1600) || (year  > 9999)) return false;
		if((month	<    1) || (month >   12))	return false;
		if((day		<    1))					return false;

		var maxdays = new Array(31, (leapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		if(day > maxdays[month - 1]) return false;

		return true;
	}
	// ----------------------------------------------------------------------------------------------------------------
	function fMD(arg){
		return ((arg < 10) ? '0' + arg : arg);
	}
	// ----------------------------------------------------------------------------------------------------------------
	function convertToInt(arg){
		return (isNaN(arg) ? parseInt(arg) : Math.floor(arg));
	}
	// ----------------------------------------------------------------------------------------------------------------
	function fYMD(year, month, day){
		year	= convertToInt(year);
		month	= convertToInt(month);
		day		= convertToInt(day);

		return year + '-' + fMD(month) + '-' + fMD(day);
	}
	// ----------------------------------------------------------------------------------------------------------------	
	function serialize(year, month, day){
		if(validateYMD(year, month, day)){
			var s = 0;
			for(var y = 1600; y < year; y++)  s += (leapYear(y) ? 366 : 365);
			var monthdays = new Array(31, (leapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
			for(var i = 0; i < month - 1; i++)  s += monthdays[i];
			return (s + day - 1);
		}
		else alert('mDate.serialize: Parameter ' + fYMD(year, month, day) + ' is invalid.');
	}
	// ----------------------------------------------------------------------------------------------------------------	
	function deserialize(n){
		var s = 0;
		var adddays;
		var year;
		for(year = 1600; s + (adddays = (leapYear(year) ? 366 : 365)) <= n; year++) s += adddays;
		n -= s;

		s = 0;
		var monthdays = new Array(31, (leapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		var month;
		for(month = 0; s + (adddays = monthdays[month]) <= n; month++) s += adddays;
		month++;
		var day = n - s + 1;
	
		return new Array(year, month, day);
	}

}
// ---------------------------------------------------------------------------
var apos = new Array(
	'Obere Apotheke',			"10. Oktober-Staße 4",		"24128",
	'Leonhard-Apotheke',		"Ernst Pliwa-Gasse 4",		"42137",
	'Wulfenia-Apotheke',		"Italienerstraße 4",		"24903",
	'Lind-Apotheke',			"Genotteallee 24",			"25654",
	'Engel-Apotheke',			"Bahnhofstraße 15",			"24472",
	'Völkendorf-Apotheke',		"Völkendorfer Straße 23",	"55966",	
	'Drau-Apotheke',			"Ossiacher Zeile 45",		"28464",
	'Apotheke Landskron',		"Ossiacher Straße 34",		"41988",
	'Paracelsus-Apootheke',		"St. Martiner Straße 44",	"59512",
	'Marien-Apotheke',			"Maria Gailer Straße 36",	"31393",
	'Sonnen Apotheke',			"Kärntner Strasse 11",		"59512",
	'Kreis-Apotheke',			"Hauptplatz 9",				"24118",
	'Perau-Apotheke',			"Ossiacher Zeile 11",		"23529",
	'Flora-Apotheke',			"Badstubenweg 93",			"56130"
);
var weekdays = new Array('Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So');
// ---------------------------------------------------------------------------
var today			= new mDate();
var actStart		= today.getMonday();		// here starts our calendar
var origin			= new mDate(2008, 1, 11);	// the first day our calender is valid
// ---------------------------------------------------------------------------
function apo(day){
	if(day.lt(origin)) return -1;
	var n = day.getSerial() - origin.getSerial();
	var numapos = apos.length / 3;
	n %= ((numapos - 1) * numapos + numapos);
	var f;
	if(n < 14){
		return n;
	}
	else{
		n -= 14;
		f = n / (numapos);
		n %= (numapos - 1);
		return (n < f ? n : n + 1 );
	}
}
// ---------------------------------------------------------------------------
function getApoName(n){
	if(n < 0) return 'nicht verfügbar';
	return apos[n * 3];
}
// ---------------------------------------------------------------------------
function getApoAddress(n){
	if(n < 0) return 'nicht verfügbar';
	return apos[n * 3 + 1];
}
// ---------------------------------------------------------------------------
function getApoPhone(n){
	if(n < 0) return 'nicht verfügbar';
	return apos[n * 3 + 2];
}
// ---------------------------------------------------------------------------
function updateCalendar(){
	var TBODY = document.getElementById('calendar');
	while(TBODY.hasChildNodes()) TBODY.removeChild(TBODY.firstChild);
	
	var numdays = 21;

	var actDate = actStart.copy();
	var attrCLASS = null;
	for(var i = 0; i < numdays; i++){
	
		var TR = document.createElement('TR');
		var classTitle = null;
		if(actDate.getWeekday() == 5)	classTitle = 'sa';
		if(actDate.getWeekday() == 6)	classTitle = 'so';
		if(actDate.eq(today))			classTitle = 'today';
		if(classTitle){
			attrCLASS = document.createAttribute('class');
			attrCLASS.nodeValue = classTitle;
			TR.setAttributeNode(attrCLASS);
		}
		
		var TD = document.createElement('TD');
		TD.innerHTML = weekdays[actDate.getWeekday()];
		attrCLASS = document.createAttribute('class');
		attrCLASS.nodeValue = "c";
		TD.setAttributeNode(attrCLASS);
		TR.appendChild(TD);

		TD = document.createElement('TD');
		TD.innerHTML = actDate.getYMD();
		TR.appendChild(TD);

		//TD = document.createElement('TD');
		//TD.innerHTML = apo(actDate) + 1;
		//attrCLASS = document.createAttribute('class');
		//attrCLASS.nodeValue = "r";
		//TD.setAttributeNode(attrCLASS);
		//TR.appendChild(TD);

		TD = document.createElement('TD');
		TD.innerHTML = getApoName(apo(actDate));
		TR.appendChild(TD);

		TD = document.createElement('TD');
		TD.innerHTML = getApoAddress(apo(actDate));
		TR.appendChild(TD);

		TD = document.createElement('TD');
		TD.innerHTML = getApoPhone(apo(actDate));
		TR.appendChild(TD);




		actDate.inc(1);
		TBODY.appendChild(TR);
	}
	
}
// ---------------------------------------------------------------------------
function setToday(){
	actStart = today.copy().getMonday();
	updateCalendar();
}
// ---------------------------------------------------------------------------
function offset(n){
	actStart.inc(n);
	updateCalendar();
}


















