/*
 * Includes fix for months August and above
 * 
 */


function nCalendar(varname, day_select, month_select, year_select) {
	this.d = new Date();
	this.varname = varname;
	if (month_select == null) {
		this.date_select = day_select;
	}
	else {
		this.day_select = day_select;
		this.month_select = month_select;
		this.year_select = year_select;
	}
	
	
	this.calendar_obj = null;
	this.iframe_obj = null;
	this.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
	this.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	this.cal_month = null;
	this.cal_year = null;
	this.hide_timer = 0;
	this.minimum_date = null;
	this.maximum_date = null;
	this.min_day = null;
	this.min_month = null;
	this.min_year = null;
	this.max_day = null;
	this.max_month = null;
	this.max_year = null;
	this.allowed_dates = [];
};

nCalendar.prototype.appendtoObject=function(obj) {
	if (! obj) {
		alert("The object you are trying to append to does not exist");	
	}
	else {
		this.obj = obj;
		if (this.verifyDateObjects()) {
			obj.onclick = new Function(this.varname + ".draw();this.blur();return false;");
			//obj.onmouseout = new Function(this.varname + ".hide_timer = setTimeout('" + this.varname + ".close()', 1500)");
		}
	}
}

nCalendar.prototype.verifyDateObjects = function() {
	
	if (this.date_select) {
		return true;
	}

	if (! this.day_select) {
		alert("Your day select does not exist");
		return false;
	}
	else if (! this.month_select) {
		alert("Your month select does not exist");
		return false;
	}
	else if (! this.year_select) {
		alert("Your year select does not exist");
		return false;
	}
	else {
		return true;
	}
}

nCalendar.prototype.draw = function(month, year, e) {
	if (document.createElement && this.obj) {
	
		// check its not already open
		this.close();
		
		if ((! month && month != 0) || ! year) {
			month = this.default_month();
			year = this.default_year();
			var day = this.default_day();
		}
		month = parseInt(month);
		year = parseInt(year);
		if (typeof(day) == "undefined") day = 1;

		//alert(day + "\n" + month + "\n" + year);

		// check to see if we have the minimum date has been breached
		if (this.minimum_date != null) {
			var min = this.minimum_date.match(/([0-9]{4})-([0-9]{2})-([0-9]{2})/);
			this.min_day = min[3];
			this.min_month = (parseInt(min[2]) - 1);
			this.min_year = min[1];
			if (this.min_year == year && month <= this.min_month) {
				if (month != this.min_month || day < this.min_day) {
					day = this.min_day;
				}
				month = this.min_month;
			}
		}
		// check to see if we have the maximum date has been breached
		if (this.maximum_date != null) {
			var max = this.maximum_date.match(/([0-9]{4})-([0-9]{2})-([0-9]{2})/);
			this.max_day = max[3];
			//this.max_month = (parseInt(max[2]) - 1);
			this.max_month = (+max[2] - 1);
			this.max_year = max[1];
			if (this.max_year <= year) {	
				if (year > this.max_year) {
					year = this.max_year;	
					month = this.max_month;
					day = this.max_day;
				}
				else if (month >= this.max_month) {
					month = this.max_month;
					if (month == this.max_month && day > this.max_day) {
						day = this.max_day;
					}
				}			
			}
		}

		var num_days_in_month = this.days_in_month(month, year);
		var first_day = this.first_day_in_month(month, year);
		var days_gone_thru = 0;
		var displaying = false;

		var left = get_position(this.obj, "Left");
		var top = (get_position(this.obj, "Top") + this.obj.offsetHeight);
		
		// do select fix for IE
		if (document.all) {
			var ifr = document.createElement("iframe");
			ifr.style.position = "absolute";
			ifr.style.left = (left - 235) + "px";
			ifr.style.top = top + "px";
			ifr.style.width = "235px";
			ifr.style.height = "205px";
			ifr.style.filter = "alpha(opacity=0)";
			ifr.src = "javascript:;";
			document.body.appendChild(ifr);
			this.iframe_obj = ifr;
		}
	
		var div_ical = document.createElement("div");
		div_ical.id = "nbclock";
		//div_ical.onmouseout = new Function(this.varname + ".hide_timer = setTimeout('" + this.varname + ".close()', 1000)");
		div_ical.onmouseover = new Function("clearTimeout(" + this.varname + ".hide_timer)");	
		div_ical.style.left = left + "px";
		div_ical.style.top = top + "px";
		
		var ical = document.createElement("table");	
		ical.Align = "center";
		ical.cellSpacing = 1;

		//header row
		var tr = ical.insertRow(ical.rows.length);
		//date header
		var td = tr.insertCell(0);	
		td.onclick = new Function(this.varname + ".close()");
		td.innerHTML = "<a href=\"#\">close</a>";
		td.colSpan = 7;
		td.className = "header";
		
		//header row
		var tr = ical.insertRow(ical.rows.length);
		//last month link
		var td = tr.insertCell(0);	
		td.innerHTML = "&nbsp;";
		
		if (! this.min_year || (this.min_year == year && month != this.min_month)) {
			td.onclick = new Function(this.varname + ".draw(" + this.lastmonth(month, year, "month") + "," + this.lastmonth(month, year, "year") + ")");
			td.className = "month_top month_top_left";
		}
		//month and year
		td = tr.insertCell(1);
		td.colSpan = "5";
		td.className = "headermonth";
		// month select
		var sel = document.createElement("select");
		sel.name = "cal_month";
		sel.style.marginRight = "2px";
		sel.onchange = new Function(this.varname + ".draw(" + this.varname + ".cal_month.value , " + this.varname + ".cal_year.value)");
		for (var x = 0; x < this.months.length; x ++) {
			if (
				(year != this.min_year && year != this.max_year)
				||
				(year == this.min_year && year == this.max_year && x >= this.min_month && x <= this.max_month)
				|| 
				(year == this.min_year && year != this.max_year && x >= this.min_month)
				||
				(year != this.min_year && year == this.max_year && x <= this.max_month)) {
				var o = new Option(this.months[x], x);
				sel.options[sel.options.length] = o;
			}
		}
		/*
		ie had issues with setting this option the second time around (it would always say it was displaying the right option but actually 
		display the above option) so have moved to setting the value explicitly to avoid this problem
		*/
		sel.value = month;
		td.appendChild(sel);
		this.cal_month = sel;
		// year select
		var sel = document.createElement("select");
		sel.name = "cal_year";
		sel.onchange = new Function(this.varname + ".draw(" + this.varname + ".cal_month.value , " + this.varname + ".cal_year.value)");
		for (var x = 2005; x < 2015; x ++) {
			if (! this.min_month || x >= this.min_year && x <= this.max_year) {
				var o = new Option(x, x);
				sel.options[sel.options.length] = o;
			}
		}
		sel.value = year;
		td.appendChild(sel);
		this.cal_year = sel;


		//next month link
		td = tr.insertCell(2);
		td.innerHTML = "&nbsp;";
		if (! this.max_year || (this.max_year >= year && month < this.max_month)) {
			td.onclick = new Function(this.varname + ".draw(" + this.nextmonth(month, year, "month") + "," + this.nextmonth(month, year, "year") + ")");
			td.className = "month_top month_top_right";
		}
		//display day names
		tr = ical.insertRow(ical.rows.length);
		for (var k = 0; k <= 6; k ++) {
			td = tr.insertCell(k);
			td.className = (k == 6) ? "headerday headerday_last" : "headerday";
			td.innerHTML = this.dayname(k).substring(0, 3);
		}
		//now draw cal days for this month
		while (days_gone_thru != num_days_in_month) {
			tr = ical.insertRow(ical.rows.length);	
			for (k = 0; k <= 6; k ++) {
				
				td = tr.insertCell(k);
				td.className = "day";			
				if (k >= first_day) {
					displaying = true;
				}
				if (displaying && days_gone_thru < num_days_in_month) {	
					// make id properly formatted date string using month (javascript offset month by 1)
					var tdate = year + "-" + this.padstr((month + 1), 2, "0", "left") + "-" + this.padstr((days_gone_thru + 1), 2, "0", "left");
					td.id = "TM:" + tdate;
					if (this.cal_year.value == year && this.cal_month.value == month && (days_gone_thru + 1) == day) {
						td.className = "day selected";
					}
					
					if (this.allowed_dates.length && array_pos(this.allowed_dates, tdate) == - 1) {
						td.className = "day noselect";
					}
					td.onmouseover = new Function(this.varname + ".showInfo('" + td.id + "', '" + k + "')");
					td.onmouseout =  new Function(this.varname + ".hideInfo('" + td.id + "')");
					td.onclick = new Function(this.varname + ".dostuff('" + td.id + "')");
					days_gone_thru ++;
					td.innerHTML = days_gone_thru;
				}
				else {
					td.className = td.className + " no_action";
					td.innerHTML = "&nbsp;";	
				}
				//td.title = td.id + " - " + td.className;
				//td.title = this.dayname(k) + " " + days_gone_thru + " " + this.monthname(month) + " " + year;
			}
		}

		// safari fix
		if (window.navigator.userAgent.search(/Safari/i) != -1) {
			for (var v = ical.rows.length - 1; v >= 0; v --) {
				ical.rows[v].parentNode.appendChild(ical.rows[v]);
			}
		}
		div_ical.appendChild(ical);
		document.body.appendChild(div_ical);
		
		this.calendar_obj = div_ical;
		// set height of iframe to the same size as the calendar
		if (this.iframe_obj) {
			this.iframe_obj.style.width = div_ical.offsetWidth + "px";
			this.iframe_obj.style.height = div_ical.offsetHeight + "px";
		}

		// get xml
		//calendar_populate_xml_data(month, year);
		//cal_get_time();
	}
}

nCalendar.prototype.close = function() {
	if (this.calendar_obj != null && this.calendar_obj.parentNode) {
		this.calendar_obj.parentNode.removeChild(this.calendar_obj);
		if (this.iframe_obj != null && this.iframe_obj.parentNode) {
			this.iframe_obj.parentNode.removeChild(this.iframe_obj);
		}
	}
}

nCalendar.prototype.default_day = function() {
	if (this.date_select) {
		var v = this.date_select.value.match(/[0-9]{4}-[0-9]{2}-([0-9]{2})/);
		if (!v || isNaN(parseInt(v[1]))) {
			return this.d.getDate();
		}
		else {
			return parseInt(v[1]);
		}
	}
	else if (isNaN(parseInt(this.day_select.value))) {
		return this.d.getDate();
	}
	else {
		return this.day_select.value;
	}	
}

nCalendar.prototype.default_month = function() {
	if (this.date_select) {
		var v = this.date_select.value.match(/[0-9]{4}-([0-9]{2})-[0-9]{2}/);
		if (!v || isNaN(parseInt(v[1]))) {
			return this.d.getMonth();
		}
		else {
			return parseInt(v[1]) - 1;
		}
	}
	else if (isNaN(parseFloat(this.month_select.value))) {
		return this.d.getMonth();
	}
	else {
		return (parseFloat(this.month_select.value) - 1);
		//return this.month_select.value;
	}	
}

nCalendar.prototype.default_year = function() {
	if (this.date_select) {
		var v = this.date_select.value.match(/([0-9]{4})-[0-9]{2}-[0-9]{2}/);
		if (!v || isNaN(parseInt(v[1]))) {
			return this.d.getFullYear();
		}
		else {
			return parseInt(v[1]);
		}
	}
	else if (isNaN(parseInt(this.year_select.value))) {
		return this.d.getFullYear();
	}
	else {
		return this.year_select.value;
	}	
}

nCalendar.prototype.days_in_month = function(month, year) {
	var mydate = new Date(year, month, 01);
	var daysinthismonth = [31,28,31,30,31,30,31,31,30,31,30,31];
	
	if (month == 1 && this.is_leap_year(year)) 
		return 29;
	else 
		return daysinthismonth[month];
}

nCalendar.prototype.first_day_in_month = function(month, year) {
	var mydate = new Date(year, month, 01);
	return mydate.getDay();
}

nCalendar.prototype.dayname = function(day) {
	return this.days[day];
}

nCalendar.prototype.monthname = function(month) {
	return this.months[month];
}

nCalendar.prototype.nextmonth = function(month, year, type) {
	if (month == 11)  {
		switch (type) {
			case "month" : return 0; break;
			case "year" : return parseInt(Number(year) + 1); break;
		}
	}
	else {
		switch (type) {
			case "month" : return parseInt(Number(month) + 1); break;
			case "year" : return year; break;
		}
	}
}

nCalendar.prototype.lastmonth = function(month, year, type) {
	if (month == 0)  {
		switch (type) {
			case "month" : return 11; break;
			case "year" : return parseInt(Number(year) - 1); break;
		}
	}
	else {
		switch (type) {
			case "month" : return parseInt(Number(month) - 1); break;
			case "year" : return year; break;
		}
	}
}

nCalendar.prototype.padstr = function(str, length, pvar, dir) {
	str = String(str);
	var padlen = length - str.length;
	if (padlen > 0) {
		var padstr = "";
		for (var i = 0; i < padlen; i ++) {
			padstr += pvar;
		}
		return (dir.toLowerCase() == "left") ? padstr + str : str + padstr;
	}
	return str;
}

nCalendar.prototype.showInfo = function(dayid, dayofweek) {
	document.getElementById(dayid).className = document.getElementById(dayid).className + ' day_over';
	var dparts = dayid.match(/TM:([0-9]{4})-([0-9]{2})-([0-9]{2})/i);
	var x = document.getElementById("caldatehead");
	if (x) {
		x.innerHTML = dparts[3].replace(/^0/, "") + " " + this.monthname(parseInt(dparts[2].replace(/^0/, "")) - 1) + " " + dparts[1];
	}
}

nCalendar.prototype.hideInfo = function(dayid) {
	document.getElementById(dayid).className = document.getElementById(dayid).className.replace(/ day_over/ig, "");
}

nCalendar.prototype.is_leap_year = function(year) {
	return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? true : false;
}

nCalendar.prototype.dostuff = function(id) {
	var d = String(id).match(/TM:([0-9]{4})-([0-9]{2})-([0-9]{2})/i);
	
	var check_date = d[1] + "-" + d[2] + "-" + d[3];
	if (this.allowed_dates.length) {
		var allow = false;
		var g = this.allowed_dates;
		for (var q  in g) {
			if (g[q] == check_date) {
				allow = true;
				break;
			}
		}
		if (! allow) {
			alert("The date you have chosen is not available.\nPlease choose another date");
			return false;
		}
	}
	
	if (this.date_select) {
		this.date_select.value = check_date;
	}
	else {
		//var udate = d[1] + "-" + d[2] + "-" + d[3];
		this.day_select.value = d[3];
		this.month_select.value = d[2];
		this.year_select.value = d[1];
	}
	this.close();
}