function openCalendar(opener, calendarId) {
	displayCalendar(calendarId);
	positionCalendar(opener,calendarId);
	$('calendar_'+calendarId).show();	
}

function positionCalendar(opener, calendarId){
	if( opener != null ) {
		var pos = Element.cumulativeOffset(opener);
		var scroll = Element.cumulativeScrollOffset(opener);
		var calendarObj = document.getElementById('calendar_' + calendarId);
		var height = Element.getHeight(calendarObj);
		var clientHeight = windowSize().height + scroll.top;
		var top = pos.top - scroll.top;
		while( (top + height) > clientHeight ) {
			top = top - 10;
		}
		
		calendarObj.style.top = top + "px";
		calendarObj.style.left = (pos.left - scroll.left) + "px";
		calendarObj.style.visibility="visible"			
	} 
}

function closeCalendar(calendarId) {
		var calendarObj = document.getElementById('calendar_' + calendarId);
		calendarObj.style.display="none";
}

function displayCalendar(calendarId) { 
	var day = eval('calendar_'+ calendarId +'.getCurrentDay()'); 
	var month = eval('calendar_'+ calendarId +'.getCurrentMonth()'); 
	var year = eval('calendar_'+ calendarId +'.getCurrentYear()'); 	
	document.getElementById('calMonth_'+calendarId+'_select').selectedIndex = eval('calendar_'+ calendarId +'.getCurrentMonth()') - 1; 	
	document.getElementById('calYear_'+calendarId).innerHTML = year;
	document.getElementById('calMonth_'+calendarId).innerHTML = document.getElementById('calMonth_'+calendarId+'_select')[document.getElementById('calMonth_'+calendarId+'_select').selectedIndex].innerHTML;	
	var calendarForm = document.getElementById('calButtons_' + calendarId); 	
	var numberOfButtons = 42; //calendarForm.length; 
	var tempCal, numDays, offset, index; 	
	var isSunday = false; 
	document.getElementById('calMonth_'+calendarId+'_select').selectedIndex = month - 1; 	
	for (i = 0; i < numberOfButtons ; i++) { 
		var button = document.getElementById('calButton_' + calendarId + '_' + i); 	
		button.disabled = true; 
		button.style.display = 'none';
		button.innerHTML = ""; 
		button.className = "date"; 		
	} 		
	tempCal = new Calendar(); ;		
	tempCal.setDate(1, month, year); ;	
	offset = tempCal.getCurrentDayOfWeekOfFirst(); ;
	numDays = tempCal.getNumDaysOfMonth(); ;
	if (!isSunday) { 	
		if (offset == 0){ 
			offset = 6 
		}else{
			offset = offset - 1;
		} 	
	}
	for (i=0; i<numDays; i++) {
		index = i + offset;
		var button = document.getElementById('calButton_' + calendarId + '_' + index); 
		var buttonValue = document.getElementById('calButton_' + calendarId + '_' + index + '_value'); 	
		button.disabled = false;		
		button.style.display = 'block'; 				
		button.innerHTML = tempCal.getCurrentDay(); 		
		buttonValue.value = eval("tempCal.getCurrentDate( document.getElementById('calFormat_"+ calendarId+"').value)"); 		
		if (eval('calendar_'+ calendarId +'.getCurrentDay()') == tempCal.getCurrentDay()) { 				
			button.className = "date_selected"; 	
			eval('setSelectedDate_' + calendarId + '('+ index +')');	
		} 		
		tempCal.setNextDay(); 		
	}
}	
			
function setThisDate(calendarId) { 
	var day = eval('calendar_'+ calendarId +'.getCurrentDay()'); 
	var month = document.getElementById('calMonth_'+calendarId+'_select').selectedIndex + 1; 
	var year = eval('calendar_'+ calendarId +'.getCurrentYear()'); 	
	while (!isValidDate(day, month, year)) { 	
		day--; 	
	}
	eval('calendar_'+ calendarId +'.setDate(day, month, year)');
	
	document.getElementById('calMonth_'+calendarId+'_select').selectedIndex = eval('calendar_'+ calendarId +'.getCurrentMonth()') - 1; 

	displayCalendar(calendarId);
}

/*********************************************************/
/*                  CALENDAR UTILITIES                   */
/*********************************************************/

/**********************************************************
* Check if a given date is valid.
* inDay   - value of the day, e.g. 1 - 31.
* inMonth - value of the month, e.g. 1 - 12.
* inYear  - value of the year, e.g. 1 - 9999.
* Return: true or false.
**********************************************************/
function isValidDate(inDay, inMonth, inYear) {
	var days;

	inYear = parseInt(inYear, 10);
	inMonth = parseInt(inMonth, 10);
	inDay = parseInt(inDay, 10);

	if (!isNaN(inYear) && !isNaN(inMonth) && !isNaN(inDay)) {
		if ((inYear > 0 && inYear < 10000) &&
			(inMonth > 0 && inMonth < 13) &&
			(inDay > 0 || inDay < 32)) {
			days = getNumDaysInMonth(inMonth, inYear);

			if (inYear == 1752 && inMonth == 9) {
				days = 30;
				if (inDay > 2 && inDay < 14)
					return false;
			}

			if (inDay > 0 && inDay <= days)
				return true;
			else
				return false;
		}
		else
			return false;
	}
	else
		return false;
}

/**********************************************************
* Check if a given year is within the valid year range.
* year  - value of the year, e.g. 1 - 9999.
* Return: true or false.
**********************************************************/
function isLeapYear(year) {
	if (year < 1 || year > 9999)
		return false;

	if (year > 1752) {
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
			return true;
		else
			return false;
	}
	else {
		if (year % 4 == 0)
			return true;
		else
			return false;
	}
}

/**********************************************************
* Get the number of days in particular month and year.
* year - an input year,.
* Return: true or false.
**********************************************************/
function getNumDaysInMonth(month, year) {
	var days;

	if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
		days = 31;
	else if (month == 4 || month == 6 || month == 9 || month == 11)
		days = 30;
	else if (month == 2)
		if (isLeapYear(year))
			days = 29;
	else
		days = 28;

	if (month == 9 && year == 1752)
		days = 19;

	return days;
}


/*********************************************************/
/*                   CALENDAR CLASS                      */
/*********************************************************/


/**********************************************************
* Calendar class.
* Default date is set to today's date.
* Public methods:
* - setDate(day, month, year)
* - setToday()
* - setPreviousDay()
* - setPreviousWeek()
* - setPreviousMonth()
* - setPreviousYear()
* - setNextDay()
* - setNextWeek()
* - setNextMonth()
* - setNextYear()
* - getCurrentDate()
* - getCurrentDay()
* - getCurrentMonth()
* - getCurrentYear()
* - getCurrentDayOfWeek()
* - getLastDayOfMonth()
* - getNumDaysOfMonth()
**********************************************************/
function Calendar() {
	var now = new Date();

	this.day = now.getDate();
	this.month = now.getMonth() + 1;
	this.year = now.getYear();
	this.setDate = Calendar.setDate;
	this.setToday = Calendar.setToday;
	this.setPreviousDay = Calendar.setPreviousDay;
	this.setPreviousWeek = Calendar.setPreviousWeek;
	this.setPreviousMonth = Calendar.setPreviousMonth;
	this.setPreviousYear = Calendar.setPreviousYear;
	this.setNextDay = Calendar.setNextDay;
	this.setNextWeek = Calendar.setNextWeek;
	this.setNextMonth = Calendar.setNextMonth;
	this.setNextYear = Calendar.setNextYear;
	this.getCurrentDate = Calendar.getCurrentDate;
	this.getCurrentDay = Calendar.getCurrentDay;
	this.getCurrentMonth = Calendar.getCurrentMonth;
	this.getCurrentYear = Calendar.getCurrentYear;
	this.getCurrentDayOfWeek = Calendar.getCurrentDayOfWeek;
	this.getCurrentDayOfWeekOfFirst = Calendar.getCurrentDayOfWeekOfFirst;
	this.getLastDayOfMonth = Calendar.getLastDayOfMonth;
	this.getNumDaysOfMonth = Calendar.getNumDaysOfMonth;
}

/**********************************************************
* Set the calendar to a specific date.
* day   - value of the day, e.g. 1 - 31.
* month - value of the month, e.g. 1 - 12.
* year  - value of the year, e.g. 1 - 9999.
**********************************************************/
Calendar.setDate = function(day, month, year) {
	this.day = parseInt(day, 10);
	this.month = parseInt(month, 10);
	this.year = parseInt(year, 10);
};

/**********************************************************
* Set the calendar to today's date.
**********************************************************/
Calendar.setToday = function() {
	var now = new Date();

	this.day = now.getDate();
	this.month = now.getMonth() + 1;
	this.year = now.getYear();
};

/**********************************************************
* Set the calendar to previous day.
**********************************************************/
Calendar.setPreviousDay = function() {
	var day = this.day;
	var month = this.month;
	var year = this.year;
	var firstDay = false;

	if (month == 9 && year == 1752 && day - 1 > 2 && day - 1 < 14)
		day = 2;
	else if (day - 1 >= 1)
		day--;
	else {
		firstDay = true;
		day = 31;

		if (month > 1)
			month--;
		else {
			month = 12;
			year--;
		}

		while(!isValidDate(day, month, year) && year >= 1)
			day--;
	}

	if (isValidDate(day, month, year)) {
		this.day = day;
		if (firstDay)
			this.setPreviousMonth();
	}
};

/**********************************************************
* Set the calendar to previous week.
**********************************************************/
Calendar.setPreviousWeek = function() {
	var i;

	for (i=0; i<7; i++)
		this.setPreviousDay();
};

/**********************************************************
* Set the calendar to previous month.
**********************************************************/
Calendar.setPreviousMonth = function() {
	var day = this.day
	var month = this.month;
	var year = this.year;

	if (month == 1 && year > 1) {
		month = 12;
		year--;
	}
	else
		month--;

	while(!isValidDate(day, month, year) && year >= 1)
			day--;

	this.day = day;
	this.month = month;
	if (month == 12)
		this.setPreviousYear();
};

/**********************************************************
* Set the calendar to previous year.
**********************************************************/
Calendar.setPreviousYear = function() {
	var day = this.day;
	var month = this.month;
	var year = this.year;

	if (year > 1) {
		year--;

		while(!isValidDate(day, month, year) && year >= 1)
			day--;

		this.day = day;
		this.year = year;
	}
};

/**********************************************************
* Set the calendar to next day.
**********************************************************/
Calendar.setNextDay = function() {
	var day = this.day;
	var month = this.month;
	var year = this.year;
	var lastDay = this.getLastDayOfMonth();

	if (month == 9 && year == 1752 && day + 1 > 2 && day + 1 < 14)
		day = 14;
	else if (day + 1 <= lastDay)
		day++;
	else {
		day = 1;

		if (month < 12)
			month++;
		else {
			month = 1;
			year++;
		}
	}

	if (isValidDate(day, month, year)) {
		this.day = day;
		if (day == 1)
			this.setNextMonth();
	}
};

/**********************************************************
* Set the calendar to next week.
**********************************************************/
Calendar.setNextWeek = function() {
	var i;

	for (i=0; i<7; i++)
		this.setNextDay();
};

/**********************************************************
* Set the calendar to next month.
**********************************************************/
Calendar.setNextMonth = function() {
	var day = this.day
	var month = this.month;
	var year = this.year;

	if (month == 12 && year < 9999) {
		month = 1;
		year++;
	}
	else
		month++;

	while(!isValidDate(day, month, year) && year >= 1)
		day--;

	this.day = day;
	this.month = month;
	if (month == 1)
		this.setNextYear();
};

/**********************************************************
* Set the calendar to next year.
**********************************************************/
Calendar.setNextYear = function() {
	var day = this.day;
	var month = this.month;
	var year = this.year;

	if (year < 9999) {
		year++;

		while(!isValidDate(day, month, year) && year >= 1)
			day--;

		this.day = day;
		this.year = year;
	}
};

/**********************************************************
* Get the current day in the YYYYMMDD format.
* Return: YYYYMMDD.
**********************************************************/
Calendar.getCurrentDate = function(outputformat) {
	var format = '';

    if (!outputformat) {
      format="MM/dd/yyyy";               
    } else {
      format = outputformat;
    }

	if( this.month < 10 ) {
		format = format.replace("MM", "0" + this.month.toString());     
	} else {
		format = format.replace("MM",this.month.toString());  
	}
 

    if (format.indexOf("yyyy") > -1)
        format = format.replace("yyyy",this.year.toString());
    else if (format.indexOf("yy") > -1)
        format = format.replace("yy",this.year.toString().substr(2,2));

	if( this.day < 10 ) {
    	format = format.replace("dd", "0" + this.day.toString());
	} else {
	    format = format.replace("dd",this.day.toString());
	}

	return format;
};

/**********************************************************
* Get the day that the calendar currently points to.
* Return: 1 - 31.
**********************************************************/
Calendar.getCurrentDay = function() {
	return this.day;
};

/**********************************************************
* Get the month that the calendar currently points to.
* Return: 1 - 12.
**********************************************************/
Calendar.getCurrentMonth = function() {
	return this.month;
};

/**********************************************************
* Get the year that the calendar currently points to.
* Return: 1 - 9999.
**********************************************************/
Calendar.getCurrentYear = function() {
	return this.year;
};

/**********************************************************
* Get day of week of the current date.
* Return: 0(Sun) - 6(Sat)
**********************************************************/
Calendar.getCurrentDayOfWeek = function() {
	var firstDay = this.getCurrentDayOfWeekOfFirst();
	var day = this.day - 1;
	var month = this.month;
	var year = this.year;

	if (day >= 13 && day <= 29 && month == 9 && year == 1752)
		day = day - 11;

	return ((day + firstDay) % 7);
};

/**********************************************************
* Get day of week of first of the month.
* Return: 0(Sun) - 6(Sat)
**********************************************************/
Calendar.getCurrentDayOfWeekOfFirst = function() {
	var firstDay, startYear, numDays, m, y;
	var month = this.month;
	var year = this.year;

	if (year >= 1 && year <= 999) {
		firstDay = 6;
		startYear = 1;
	}
	else if (year >= 1000 && year <= 1999) {
		firstDay = 1;
		startYear = 1000;
	}
	else {
		y = Math.floor(year / 1000);

		if (y % 2 == 0)
			firstDay = 6;
		else
			firstDay = 3;

		startYear = y * 1000;
	}

	for (y=startYear; y<=year; y++) {
		m = 1;
		while (m <= 12) {
			if (m == month && y == year) {
				m = 13;
			}
			else {
				numDays = getNumDaysInMonth(m, y);
				firstDay = (numDays + firstDay) % 7;
				m++;
			}
		}
	}

	return firstDay;
};

/**********************************************************
* Get the last day of the mnoth.
* Return: 31, 30, 29, 28.
**********************************************************/
Calendar.getLastDayOfMonth = function() {
	var lastDay;
	var month = this.month;
	var year = this.year;

	if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
		lastDay = 31;
	else if (month == 4 || month == 6 || month == 9 || month == 11)
		lastDay = 30;
	else if (month == 2)
		if (isLeapYear(year))
			lastDay = 29;
	else
		lastDay = 28;

	return lastDay;
};

/**********************************************************
* Get the number of days that the current month has.
* Return: 0(Sun) - 6(Sat)
**********************************************************/
Calendar.getNumDaysOfMonth = function() {
	var month = this.month;
	var year = this.year;
	var days = getNumDaysInMonth(month, year);

	return days;
};

