var TiCal = 
{
	opts: {
		minDate: new Date(),
		maxDate: new Date((new Date()).getTime() + 3600 * 24 * 1000 * 365 * 5),
		disableWeekends: true,
		lang: "en"
	},
	
	langs: {
		en: {
			months: "January,February,March,April,May,June,July,August,September,October,November,December",
			days:   "Mo,Tu,We,Th,Fr,Sa,Su",
			format: "mm/dd/yyyy",
			titlePrev:  "previous month",
			titleNext:  "next month",
			titleToday: "today",
			titleClose: "close"
			
		},
		de: {
			months: "Januar,Februar,März,April,Mai,Juni,Juli,August,September,Oktober,November,Dezember",
			days:   "Mo,Di,Mi,Do,Fr,Sa,So",
			format: "d.m.yy",
			titlePrev:  "Monat zurück",
			titleNext:  "Monat weiter",
			titleToday: "Heute",
			titleClose: "schließen"
			
		}
	},
	
	onSelect: function(date) {
		if(TiCal.inputBox)
			TiCal.inputBox.value = TiCal.formatDate(date);	
		TiCal.close();
	},
	
	open: function(inputBox, opts) {
		for(var p in (opts || {}))
			TiCal.opts[p] = opts[p];
		if(typeof(TiCal.opts.lang) == "string" && TiCal.langs[TiCal.opts.lang])
			TiCal.opts.lang = TiCal.langs[TiCal.opts.lang];
		TiCal.inputBox = inputBox;
		if(!TiCal.inited)
			TiCal.init();
		var now = new Date;
		TiCal.setDate(inputBox ? (TiCal.parseDate(inputBox.value) || now) : now);
		setTimeout(TiCal.update, 2);
	},
	
	close: function() {
		document.getElementById("TiCal").style.display = "none"
	},
	
	//

	date: new Date,
	inited: false,
	
	ds: function(date) {
		var q = { d: date.getDate(), m: date.getMonth() + 1, y: date.getFullYear()};
		q.dd = (q.d + 100).toString().substr(1);
		q.mm = (q.m + 100).toString().substr(1);
		q.sy = (q.y).toString().substr(2);
		q.val = [q.y, q.mm, q.dd].join("-");
		return q;
	},
	dval: function(date) {
		return TiCal.ds(date).val;
	},
	init: function() {
		var html = 
			'<table id="TiCalHead"><tr>'
			+ '<td align="left" id="TiCalMonth"></td>'
			+ '<td align="right">'
			+ '<button title="@titlePrev" onclick="TiCal.goMonth(-1);return false">&#171;</button>'
			+ '<button title="@titleNext" onclick="TiCal.goMonth(+1);return false">&#187;</button>'
			+ '<button title="@titleToday" onclick="TiCal.goDate();return false">&#164;</button>'
			+ '<button title="@titleClose" onclick="TiCal.close();return false">&#215;</button>'
			+ '</td></tr></table>'
			+ '<div id="TiCalBody" onmouseover="TiCal.me(event, 1)" onmouseout="TiCal.me(event, 2)" onclick="TiCal.me(event, 3)"></div>';

		html = html.replace(/@(\w+)/g, function($0, $1) {
			return TiCal.opts.lang[$1] || "";
		});
		
		var div = document.getElementById("TiCal");
		if(!div) {
			div = document.createElement("DIV");
			div.id = "TiCal";
			document.body.appendChild(div);
		}
		div.innerHTML = html;

		TiCal.tabHead = "<tr>";
		var t = TiCal.opts.lang.days.split(",");
		for(var i = 0; i < t.length; i++)
			TiCal.tabHead += ((i > 4) ? "<th class='we'>" : "<th>") + t[i] + "</th>";
		TiCal.tabHead += "</tr>";

		TiCal.inited = 1;
	},
	formatDate: function(date) {
		var f = TiCal.opts.lang.format, q = TiCal.ds(date);
		f = f.replace(/dd/, q.dd);
		f = f.replace(/d+/, q.d);
		f = f.replace(/mm/, q.mm);
		f = f.replace(/m+/, q.m);
		f = f.replace(/yyyy/,  q.y);
		f = f.replace(/y+/, q.sy);
		return f;
	},
	parseDate: function(s) {
		var s = s.split("");
		var f = TiCal.opts.lang.format.replace(/([dmy])+/g, "$1").split("");
		var r = { d: 0, m: 0, y: 0 };
		var b = []
		while(f.length) {
			var q = f.shift();
			b.push(q + "=" + s.join(","))
			if(q == 'd' || q == 'm' || q == 'y') {
				while(s[0] >= "0" && s[0] <= "9")
					r[q] = (r[q] * 10) + parseInt(s.shift());
			} else if(q != s.shift())
				break;
		}
		
		var q = TiCal.ds(new Date);
		for(var p in r)
			r[p] = r[p] || q[p];
		if(r.y < 70) r.y += 2000;
		return new Date(r.y, r.m - 1, r.d)
	},
	setDate: function(date) {
		var dd = TiCal.dval(date);
		if(dd < TiCal.dval(TiCal.opts.minDate))
			date = TiCal.opts.minDate;
		if(dd > TiCal.dval(TiCal.opts.maxDate))
			date = TiCal.opts.maxDate;
		TiCal.date = date;
	},
	update: function() {
		TiCal.draw();
		document.getElementById("TiCal").style.display = "block";
		document.getElementById("TiCalMonth").innerHTML = TiCal.opts.lang.months.split(",")[TiCal.date.getMonth()] + 
			" " + TiCal.date.getFullYear();
		TiCal.setPos(TiCal.inputBox);
	},
	draw: function() {
		var dnow = TiCal.dval(new Date);
		var dmin = TiCal.dval(TiCal.opts.minDate);
		var dmax = TiCal.dval(TiCal.opts.maxDate);
		var dcur = TiCal.dval(TiCal.date);
		
		var d = new Date(TiCal.date), dow = 0;
		var e = "<td> </td>", row = 0, tab = [];

		for(var day = 1; day < 32; day++) {
			d.setDate(day);
			if(d.getMonth() != TiCal.date.getMonth())
				break;
			dow = (d.getDay() || 7) - 1;
			if(!dow || !tab.length)
				tab[++row] = [e, e, e, e, e, e, e];
			var cls = 'day', dd = TiCal.dval(d);
			if(dd < dmin ||  dd > dmax || (TiCal.opts.disableWeekends && dow > 4))
				cls = 'dis';
			else if(dd == dnow)
				cls = 'now';
			else if(dd == dcur)
				cls = 'sel';
			tab[row][dow] = "<td class='" + cls + "'>" + day + "</td>";
		}

		var table = [TiCal.tabHead];
		for(var row = 1; row < tab.length; row++) {
			table.push("<tr>");
			table.push(tab[row].join("\n"));
			table.push("</tr>");
		}
		
		document.getElementById("TiCalBody").innerHTML = "<table>" + table.join("\n") + "</table>";
	},
	setPos: function(obj) {
		var div = document.getElementById("TiCal");
		var x = 0, y = obj.offsetHeight + 1;
		while(obj && obj != div.offsetParent) {
			x += obj.offsetLeft;
			y += obj.offsetTop;
			obj = obj.offsetParent;
		}
		div.style.left = x + "px";
		div.style.top = y + "px";
	},
	goMonth: function(n) {
		var d = new Date(TiCal.date);
		d.setMonth(d.getMonth() + n);
		TiCal.setDate(d);
		TiCal.update();
	},
	goDate: function(date) {
		if(!date)
			date = new Date();
		TiCal.setDate(date);
		TiCal.update();
	},
	me: function(event, type) {
		var e = window.event || event;
		var o = e.srcElement || e.target;
		if(o && !o.tagName) 
			o = o.parentNode;
		if(!o || o.tagName.toLowerCase() != "td")
			return;
		var day = Number(o.innerHTML);
		if(!day)
			return;
		if(!o.className.match(/\b(day|now)\b/))
			return;
		o.className = (o.className + "").replace(/\s+hover/, "");
		if(type == 1 || type == 3)
			o.className += " hover";
		if(type == 3) {
			var d = new Date(TiCal.date);
			d.setDate(day);
			TiCal.onSelect(d);
		}
	}
	
}
