var day_ar = ["Sun","Mon","Tue","Wen","Thu","Fri","Sat"];
var month_ar = ["January","February","March","April","May","June","July","August","September","October","November","December"];
var days_month_ar = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

var old_mousedown_hdl;

var g_day_element, g_month_element, g_year_element;
var g_sync_elt;
// initial delta from 
var g_offset_x = 4;
var g_offset_y = 8;

//
// calendarPos
function calendarPos(obj) {
	this.x = g_offset_x;
	this.y = g_offset_y;
	if(obj) {
		//obj
		if (obj.offsetParent) {
			this.x += obj.offsetLeft;
			this.y += obj.offsetTop;
			while (obj = obj.offsetParent) {
				this.x += obj.offsetLeft;
				this.y += obj.offsetTop;
			}
		}
	}
}

//
// define a select element - value object
function SelElement(elt) {
	this.elt = elt;
	this.value = parseInt(elt.options[elt.selectedIndex].value);
}

//
// define a cal_sync_element (the html elements to synchronize with)
function CalSyncElement(day_elt, month_elt, year_elt) {
	// day - month - year
	this.day = new SelElement(day_elt);
	this.month = new SelElement(month_elt);
	this.year = new SelElement(year_elt);
}

//
// get a property for an element given its id
function getIdProperty(id, property) {

	var styleObject = document.getElementById( id );
	if (styleObject != null)
	{
		styleObject = styleObject.style;
		if (styleObject[property])
		{
			return styleObject[ property ];
		}
	}
	return null;

}

//
// set a property to an element given its id
function setIdProperty( id, property, value )
{
	var styleObject = document.getElementById( id );
	if (styleObject != null)
	{
		styleObjectStyle = styleObject.style;
		if(styleObjectStyle[property]) {
			styleObjectStyle[property] = value;
		}
	}

}

//
// show the calendar
function do_show_calendar() {
	if(getIdProperty("calendar_frame", "display") != 'block')
		setIdProperty("calendar_frame", "display", "block");
}

//
// hide the modal dialog box
function do_hide_calendar() {
	if(getIdProperty("calendar_frame", "display") == 'block')
		setIdProperty("calendar_frame", "display", "none");
}

//
// function to open a calendar
function show_calendar(a_event, src_elt, day_element, month_element, year_element) {
	
	// keep form element that will need to be synchronized
	g_sync_elt = new CalSyncElement(day_element, month_element, year_element);

	a_elt = document.getElementById("calendar");
	if(a_elt != null) {
		a_point = new calendarPos(src_elt);
		setIdProperty("calendar", "top", a_point.y + "px");
		setIdProperty("calendar", "left", a_point.x + src_elt.width + "px");
		
		// show the calendar frame
		do_show_calendar();
		
		// build month-year selector
		build_month_select();
	
		var iframe = document.getElementById("iframe");
		iframe.style.width = a_elt.offsetWidth;
		iframe.style.height = a_elt.offsetHeight;
		iframe.style.left = a_elt.offsetLeft;
		iframe.style.top = a_elt.offsetTop;
	
		// add a mouse down event handler 
		// if addEventListener is define -> DOM compliant event handling is possible
		if(document.addEventListener) {
			document.addEventListener("mousedown", track_mouse_down, true);
		}
		else if(document.attachEvent) {
			// attach event is available only in IE
			cal_content = document.getElementById("calendar");
			cal_content.attachEvent("onmousedown", track_mouse_downie);
			document.attachEvent("onmousedown", track_hide_calendar);
		} else {
			// this is our last chance (hope we never use it)
			old_mousedown_hdl = document.onmousedown;
			document.onmousedown = track_mouse_down;
		}
	}
}

//
// to hide the calendar
function hide_calendar() {
	do_hide_calendar();
	// remove all kind of event handler previously created
	if(document.removeEventListener)
		document.removeEventListener("mousedown", track_mouse_down, true);
	else if(document.detachEvent) {
		cal_content = document.getElementById("calendar");
		cal_content.detachEvent("onmousedown", track_mouse_downie);
		document.detachEvent("onmousedown", track_hide_calendar);
	}
	else
		document.onmousedown = old_mousedown_hdl;
}

//
// track mouse down while calendar is displayed
function track_mouse_down(evt) {
	// while mouse in this element -> show calendar
	cal_elt = document.getElementById("calendar");
	tgt = evt.target;
	if(tgt == cal_elt)
		return;
	// loop through hierarchy and let displayed if in calendar element.
	if(tgt.offsetParent) {
		while (tgt = tgt.offsetParent) {
			if(tgt == cal_elt)
				return;
		}
	}
	// if calendar element not found in hierarchy -> hide it
	hide_calendar();
}

//
// track mouse down while calendar is displayed
function track_mouse_downie(evt) {
	evt.cancelBubble = true;
}

//
// track mouse down while calendar is displayed
function track_hide_calendar(evt) {
	hide_calendar();
}

//
// build month select
function build_month_select() {

	// build the default selection val based on 
	if(g_sync_elt.month != undefined) {
		month_val = parseInt(g_sync_elt.month.value);
		if(month_val <= 9) {
			month_str = "0" + month_val;
		} else {
			month_str = String(month_val);
		}
		year_val = g_sync_elt.year.value;
		
		select_str = month_str + year_val;
	}	

	//
	// first empty the current select
	document.calendar_form.calendar_month.options.length = 0;
	
	// 
	// determine start and end period from current date (from current month to december next year.
	var current_date = new Date();
	var cur_year = current_date.getFullYear();
	var cur_month = current_date.getMonth();

	// this is the total number of entries in the select (from current month to december next year)
	select_month = cur_month;
	tot_month = 12 + (12 - cur_month);
	for(i = 0; i < tot_month; i++) {
		// label is month string followed by space followed by year
		label = month_ar[cur_month] + " ";
		label = label + cur_year;
		
		// val is a string : 2 digits month + 4 digits year
		if(cur_month < 9)
			val = "0" + (cur_month  + 1);
		else
			val = String(cur_month  + 1);
		val = val + cur_year;
		
		// create option obj
		if(val == select_str) {
			is_selected = true;
			select_month = cur_month;
		}
		else
			is_selected = false;
		a_option = new Option(label, val, false, is_selected);
		// append option to select
		document.calendar_form.calendar_month.options[i] = a_option;
		
		// next month
		cur_month++;
		if(cur_month == 12) {
			cur_month = 0;
			cur_year++;
		}
	}		
	
	build_days_array(month_val - 1, year_val);
	
}

//
// build days array
function build_days_array(a_month, a_year) {
	// build a date object for first day of this month and year
	a_date = new Date(a_year, a_month, 1, 1, 1, 1);
	
	if(((a_month + 1) == g_sync_elt.month.value) && (a_year == g_sync_elt.year.value))
		can_select = true;
	else
		can_select = false;

	// represent today's date
	today = new Date();
	today_day = today.getDate();
	today_month = today.getMonth();
	today_year = today.getFullYear();
		
	day_of_week = a_date.getDay();
	index_day = 1;
	inner_str = "<table class='cal_class'><tr>"
	inner_str = inner_str + build_day_line();
	inner_str = inner_str + "<\/tr><tr>";
	
	// first line
	for(i = 0; i < 7; i++) {
		str = "<td class='cal_td'>";
		if(i < day_of_week)
			str = str + "&nbsp;";
		else {
				active_day = ((a_year > today_year) || (a_month > today_month) || (index_day >= today_day)) ? true : false;
			if(active_day && can_select && (index_day == g_sync_elt.day.value))
				style_elt = " style='background-color: #aaaaaa;'";
			else
				style_elt = "";
			if(active_day) {
				str = str + "<span class='cal_text'" + style_elt + ">";
				str = str + "<a href='javascript:void(0);' onclick='do_select_day(";
				str = str + index_day;
				str = str + ")'>";
				str = str + index_day;
				str = str + "<\/a>";
				str = str + "<\/span>";
			} else {
				str = str + "<span style='text-decoration: line-through'>";
				str = str + index_day;
				str = str + "<\/span>";
			}
			index_day++;
		}
		str = str + "<\/td>";
		
		inner_str = inner_str + str;
	}
	inner_str = inner_str + "<\/tr>";
	
	do_loop = true;
	max_day = days_month_ar[a_month];
	if((a_year % 4 == 0) && (a_month == 1))
		max_day++;
	while(do_loop) {
		inner_str = inner_str + "<tr>";
		for(i = 0; i < 7; i++) {
			str = "<td class='cal_td'>";
			if(index_day > max_day)
				str = str + "&nbsp;";
			else {
				active_day = ((a_year > today_year) || (a_month > today_month) || (index_day >= today_day)) ? true : false;
				if(active_day && can_select && (index_day == g_sync_elt.day.value))
					style_elt = " style='background-color: #aaaaaa;'";
				else
					style_elt = "";
				if(active_day) {
					str = str + "<span class='cal_text'" + style_elt + ">";
					str = str + "<a href='javascript:void(0);' onclick='do_select_day(";
					str = str + index_day;
					str = str + ")'>";
					str = str + index_day;
					str = str + "<\/a>";
					str = str + "<\/span>";
				} else {
					str = str + "<span style='text-decoration: line-through'>";
					str = str + index_day;
					str = str + "<\/span>";
				}
				index_day++;
				if(index_day > max_day)
					do_loop = false;
			}
			str = str + "<\/td>";
			inner_str = inner_str + str;
		}
		inner_str = inner_str + "<\/tr>";
	}
	inner_str = inner_str + "<\/table>";
	
	daynums_elt = document.getElementById("cal_days");
	daynums_elt.innerHTML = inner_str;
}

//
// build calendar day line
function build_day_line() {

	var str = "";
	var ct = day_ar.length;
	
	for(i = 0; i < ct; i++) {
		str = str + "<td class='cal_td'>";
		str = str + day_ar[i];
		str = str + "<\/td>";
	}
	return str;
}

//
// do calendar select change
function do_month_change() {
	//
	// first get select selection
	var val = document.calendar_form.calendar_month.value;
	a_month = parseInt(val.substr(0, 2), 10);
	a_year = parseInt(val.substr(2, 4), 10);
	build_days_array(a_month - 1, a_year);
}

//
// do next month
function do_next_month() {
	// next selection
	var idx = document.calendar_form.calendar_month.selectedIndex;
	if(idx < (document.calendar_form.calendar_month.options.length - 1)) {
		document.calendar_form.calendar_month.selectedIndex = ++idx;
		do_month_change();
	}
}

//
// do prev month
function do_prev_month() {
	// next selection
	var idx = document.calendar_form.calendar_month.selectedIndex;
	if(idx > 0) {
		document.calendar_form.calendar_month.selectedIndex = --idx;
		do_month_change();
	}
}

//
// do select day
function do_select_day(day_index) {
	// this is the selected day
	var val = document.calendar_form.calendar_month.value;
	a_month = parseInt(val.substr(0, 2), 10);
	a_year = parseInt(val.substr(2, 4), 10);
	
	// build the default selection val based on 
	if(g_sync_elt.month != undefined) {
		g_sync_elt.day.elt.value = day_index;
		g_sync_elt.month.elt.value = a_month;
		g_sync_elt.year.elt.value = a_year;
	}

	// this end the display calendar
	hide_calendar();
}
