
var Calendar = {
	
	inp1: null,
	inp2: null,
	biOrder: null,
	months: null,
	setFunc: null,
	limits: null,
	today: new Date,
	div: false,
	timer: null,
	langMonths: ["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],
	active: false,
	mouseOnCal: 0,
	onTop: 0,
	/*
	arr = [object] input || [array] [inp1, inp2]
	limits not implemented
	*/
	show: function(inp1, inp2, biOrder, months, setFunc, limits, onTop){
		if(Calendar.inp1){
			if(Calendar.inp1 != inp1){
				Calendar.blurExec();
			}else{
				return;
			}
		}
		
		Calendar.onTop = onTop != undefined ? onTop : 0;
		
		Calendar.active = true;
		Calendar.inp1 = inp1;
		Calendar.inp2 = inp2;
		Calendar.biOrder = biOrder;
		Calendar.months = months;
		Calendar.setFunc = setFunc;
		Calendar.limits = limits;
		
		Calendar.inp1.select();
		
		addEvent(Calendar.inp1, "onblur", Calendar.onBlur);
		addEvent(Calendar.inp1, "onkeydown", Calendar.onBeforeType);
		addEvent(Calendar.inp1, "onkeyup", Calendar.onType);

		addEvent(document, "onmousedown", Calendar.mouseDown);


		Calendar.checkValues();
		
		var arr = Calendar.getActiveRange();
		Calendar.render(arr);
	},
	
	mouseDown: function(e){
		var g = e.srcElement || e.target;
		var found = false;
		while(g){
			if(g == Calendar.inp1 || g == Calendar.div){
				Calendar.mouseOnCal = 1;
				found = true;
				break;
			}
			g = g.parentNode;
		}
		if(!found){
			Calendar.mouseOnCal = 0;
		}
		addEvent(document, "onmouseup", Calendar.mouseUp);
	},
	
	mouseUp: function(){
		removeEvent(document, "onmouseup", Calendar.mouseUp);
		setTimeout(function(){
			if(Calendar.mouseOnCal == 1){
				Calendar.refocus();
			}
		},10);
	},
	
	
	getActiveRange: function(){

		if(Calendar.inp1.value == ""){
			if(Calendar.inp2 && Calendar.inp2.value){
				var year = parseInt(Calendar.inp2.value.substring(0,4));
				var month = parseInt(Calendar.inp2.value.substring(5,6)) * 10 + parseInt(Calendar.inp2.value.substring(6,7)) - 1;
				if(!Calendar.biOrder){
					month -= (Calendar.months - 1);
					if(month < 0){
						year--;
						month += 12;
					}
				}
			}else{
				var year = Calendar.today.getFullYear();
				var month = Calendar.today.getMonth();
			}
		
		}else{ // Focused has date
			var year = parseInt(Calendar.inp1.value.substring(0,4));
			var month = parseInt(Calendar.inp1.value.substring(5,6)) * 10 + parseInt(Calendar.inp1.value.substring(6,7)) - 1;
			if(Calendar.biOrder){
				month -= (Calendar.months - 1);
				if(month < 0){
					year--;
					month += 12;
				}
				
				if(Calendar.inp2 && Calendar.inp1.value){
					var year2 = parseInt(Calendar.inp2.value.substring(0,4));
					var month2 = parseInt(Calendar.inp2.value.substring(5,6)) * 10 + parseInt(Calendar.inp2.value.substring(6,7)) - 1;
					if(year2*12 + month2 > year*12 + month){
						year = year2;
						month = month2;
					}
				}
			}
		
		}
		var arr = Calendar.getRange(year, month);
		return arr;	
	},
	
	onBeforeType: function(){
		Calendar.mouseOnCal = 0;
		Calendar.typeBuffer = Calendar.getValid(Calendar.inp1 ? Calendar.inp1.value : "");
	},
	
	onType: function(){
		var str = Calendar.getValid(Calendar.inp1 ? Calendar.inp1.value : "");
		if(Calendar.typeBuffer == str || !str){
			return;
		}
		Calendar.checkValues();
		var arr = Calendar.getActiveRange();
		Calendar.render(arr);
		
		// Check for new correct dates, if found, set that date in calendar focus
	},
	
	getRange: function(year,month){
		year = parseInt(year);
		month = parseInt(month);
		var arr = [];
		for(var x=0;x<Calendar.months;x++){
			arr[arr.length] = [year,month];
			month++;
			if(month == 12){
				month = 0;
				year++;
			}
		}
		return arr;
	},
	
	checkValues: function(){
		Calendar.checkValue(Calendar.inp1);
		if(Calendar.inp2){
			Calendar.checkValue(Calendar.inp2);
		}
	},
	
	checkValue: function(a){
		var b = Calendar.getValid(a.value);
		a.value = b;
	},
	
	getValid: function(a){
		var m = a.match(/^(19|20)(\d{2})\-?(\d{2})\-?(\d{2})$/);
		if(m){
			return m[1]+m[2]+"-"+m[3]+"-"+m[4];
		}else{
			return "";
		}
	
	},
	
	monthHTML: function(y,m){
		
		var d = new Date;
		d.setDate(1);
		d.setMonth(m);
		d.setYear(y);
		var week = d.getDay();
		
		// days
		switch(m){
			case 1: var days = y % 4 == 0 ? 29 : 28; break;
			case 0: case 2: case 4: case 6: case 7: case 9: case 11: var days = 31; break;
			default: var days = 30;
		}
		
		var h = "<table>"+
		"<tr class='calendar_title'><th colspan=8>"+Calendar.langMonths[m]+" "+y+"</th></tr>"+
		"<tr><th>&nbsp;</th><th>M</th><th>T</th><th>O</th><th>T</th><th>F</th><th>L</th><th>S</th></tr><tr>";
		
		// Pre-fill month
		week = week == 0 ? 7 : week;
		var fills = week - 1;
		d.setDate(0);
		var py = d.getFullYear();
		var pm = d.getMonth() + 1;
		pm = pm < 10 ? "0"+pm : pm;
		var pd = d.getDate();

		h += "<td class='week'>"+(d.getWeek()+(fills ? 0 : 1))+"</td>"; // fix when week starts with new date
		for(var i=0;i<fills;i++){
			var dag = pd - (fills - i - 1);
			var p = py+"-"+pm+"-"+dag;
			h += "<td class='fill'><a href='#' onclick='Calendar.set(\""+p+"\");return false;'>"+dag+"</a></td>";
		}
		var low = !Calendar.biOrder ? Calendar.inp1 : Calendar.inp2;
		low = low.value ? low : false;
		var high = Calendar.biOrder ? Calendar.inp1 : Calendar.inp2;
		high = high.value ? high : false;
		
		var todayDate = Calendar.today.getFullYear()+"-"+(Calendar.today.getMonth()+1 < 10 ? "0" : "")+(Calendar.today.getMonth()+1)+"-"+(Calendar.today.getDate() < 10 ? "0" : "")+Calendar.today.getDate();
		
		var dat = new Date;
		dat.setDate(1);
		dat.setMonth(0);
		dat.setFullYear(y);
		var x = 1;
		while(1){

			dat.setDate(1);
			dat.setMonth(m);
			dat.setDate(x);
			dat.setFullYear(y);

			if(week == 8){
				week = 1;
				
				h += "</tr><tr><td class='week'>"+dat.getWeek()+"</td>";
			}
			var dt = y+"-"+(m+1 < 10 ? "0"+(m+1) : m+1)+"-"+(x < 10 ? "0"+x : x);
			
			var c = '';
			if(dt == low.value || (high && dt == high.value)){
				var c = 'active';
			}else if(high && low && high && dt > low.value  && dt < high.value){
				var c = 'between';
			}else if(dt == todayDate){
				var c = 'today';
			}else if(dt < todayDate){
				var c = 'beforeToday';
			}
			
			h += "<td class='"+c+"'><a href='#' onclick='Calendar.set(\""+dt+"\");return false;'>"+x+"</a></td>";
			
			x++;
			week++;
			if(x > days){break;}
		}
		
		var fills = 7 - (days+fills) % 7;
		fills = fills == 7 ? 0 : fills;
		d.setDate(1); // next month
		var py = d.getFullYear();
		var pm = d.getMonth() + 3;
		if(pm > 12){
			pm -= 12;
			py++;
		}
		pm = pm < 10 ? "0"+pm : pm;
		for(var i=0;i<fills;i++){
			var p = py+"-"+pm+"-0"+(i+1);
			h += "<td class='fill'><a href='#' onclick='Calendar.set(\""+p+"\");return false;'>"+(i+1)+"</a></td>";
		}
		h += "</tr></table>";
		return h; 
	},
	
	set: function(a){
		Calendar.mouseOnCal = 0;
		Calendar.inp1.value = a;
		Calendar.blurExec();
	},
	
	nav: function(dir){
		Calendar.mouseOnCal = 0;
		var a = Calendar.monthArr;
		if(!dir){ // previous
			var b = a[0];
			if(b[1] == 0){
				var m = 11;
				var y = b[0] - 1;
			}else{
				var m = b[1] - 1;
				var y = b[0];
			}
		}else{ // next
			var b = a[0];
			if(b[1] == 11){
				var m = 0;
				var y = b[0] + 1;
			}else{
				var m = b[1] + 1;
				var y = b[0];
			}
			
		}
		var arr = Calendar.getRange(y,m);
		Calendar.render(arr);
	},
	
	refocus: function(){
		if(Calendar.timer){
			clearTimeout(Calendar.timer);
			Calendar.timer = null;
			Calendar.inp1.focus();
		}
	},
	
	render: function(arr){
		Calendar.refocus();
		
		Calendar.monthArr = arr;
		
		var html = [];
		
		for(var x=0;x<arr.length;x++){
			html[html.length] = Calendar.monthHTML(arr[x][0],arr[x][1]);
		}
		
		var pos = FindXYWH(Calendar.inp1);
		
		Calendar.hide();
		
		var scrollTop = parseInt(document.body.scrollTop > document.documentElement.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop);
		var t = pos.y + pos.h + scrollTop;
		var div = _ce("DIV");
		div.style.position = "absolute";
		div.style.top = t+"px";
		div.style.left = (pos.x)+"px";
		div.className = "calendar";
		div.style.zIndex = 10000000;
		div.innerHTML = "<div class='calendar_head'>"+
			"<span onclick='Calendar.nav(0);'>« Föregående månad</span>"+
			" &nbsp; &nbsp; "+
			"<span onclick='Calendar.nav(1);'>Nästa månad »</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "+
		"</div><div class='calendar_body'>"+
			html.join("")+
			"<div style='clear:both;'></div>"+
		"</div>";
		Calendar.div = div;
		document.getElementsByTagName("BODY")[0].appendChild(div);

		if(Calendar.onTop){
			t = pos.y + scrollTop - parseInt(div.offsetHeight);
			div.style.top = t+"px";
		}

		
		if(Calendar.inp2 && Calendar.biOrder){
			// div.style.left = (pos.x + pos.w - div.offsetWidth)+"px";
		}
		// div.style.left = (pos.x + pos.w / 2 - div.offsetWidth / 2 )+"px"; // Center
	},
	
	hide: function(){
		if(!Calendar.div){return;}
		Calendar.div.parentNode.removeChild(Calendar.div);
		Calendar.div = false;
		// Calendar.inp1 = false;
	},
	
	onBlur: function(){
		// should blur be triggered?
		if(Calendar.timer){
			clearTimeout(Calendar.timer);
			Calendar.timer = null;
		}
		Calendar.timer = setTimeout(Calendar.blurExec, 50);
	},
	
	blurExec: function(){
		
		if(Calendar.mouseOnCal){return;}
		
		removeEvent(document, "onmousedown", Calendar.mouseDown);
		
		if(Calendar.timer){
			clearTimeout(Calendar.timer);
			Calendar.timer = null;
		}
		
		if(!Calendar.inp1){Travel.debug("inp1 missing");return;} // Not needed

		Calendar.hide();

		removeEvent(Calendar.inp1, "onblur", Calendar.onBlur);
		removeEvent(Calendar.inp1, "onkeydown", Calendar.onBeforeType);
		removeEvent(Calendar.inp1, "onkeyup", Calendar.onType);

		Calendar.checkValues();
		
		Calendar.inp1.blur();
		
		var refocus = 0;
		if(!Calendar.setFunc && Calendar.inp2){
			var v1 = Calendar.inp1.value;
			var v2 = Calendar.inp2.value;
			if((Calendar.biOrder ? v1 : v2) < (!Calendar.biOrder ? v1 : v2)){
				refocus = !Calendar.biOrder ? Calendar.inp2 : Calendar.inp1;
			}
		}
		
		Calendar.typeBuffer = false;
		Calendar.active = false;
		Calendar.inp1 = null;
		Calendar.inp2 = null;
		Calendar.biOrder = null;
		Calendar.months = null;
		Calendar.limits = null;

		if(Calendar.setFunc){
			Calendar.setFunc();
		}else if(refocus){
			refocus.focus();
		}
	}
	
};
