// Author: Mark Horila
// Date: Dec 2007
function calendar(var_name, value_element_id, output_element_id, title, hide_on_select){

	var isDOM = (document.getElementById ? true : false);
	var isIE4 = ((document.all && !isDOM) ? true : false);
	var isNS4 = (document.layers ? true : false);
	
	//var saMonthLabel = ['January','February','March','April','May','June','July','August','September','October','November','December'];
	var saMonthLabel = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
	var saDayLabel = ['Su','Mo','Tu','We','Th','Fr','Sa'];
	var naMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	
	var dCurrent = new Date();

	var nTodayMonth=dCurrent.getMonth();
	var nTodayYear=dCurrent.getFullYear();
	var nTodayDay=dCurrent.getDate();	
	
	var nMonth=dCurrent.getMonth();
	var nYear=dCurrent.getFullYear();
	
	var nSelYear = -1;
	var nSelMonth = -1;
	var nSelDay = -1;
	
	var valueElementId = value_element_id;
	var outputElementId = output_element_id;
	var variableName = var_name;
	var hideOnSelect = hide_on_select;
	
	var sTitle = title;
	
	this.getRef = function(id) {
		if (isDOM) return document.getElementById(id);
		else if (isIE4) return document.all[id];
		else if (isNS4) return document.layers[id];	
		return document;
	};

	this.getStyle = function(id) { return this.getRef(id).style; };
	
	this.setSelectDate = function(m,d,y){
		nSelYear = y;
		nSelMonth = m;
		nSelDay = d;
		this.getRef(valueElementId).value = this.dateToString(nSelMonth+1,nSelDay,nSelYear);
		this.generate();		
		if(hideOnSelect==true) getStyle(output_element_id).display='none';
	};
	
	this.onInputValueChange = function(){
		var str = document.getElementById(valueElementId).value;
		this.setDateByString(str);
	};
	
	this.isLeapYear = function(){
		if (nMonth == 1) { // February only!
			if ((nYear % 4 == 0 && nYear % 100 != 0) || nYear % 400 == 0) return true;
		}
		return false;
	};
	
	this.dateToString = function(m,d,y){	
		var sm = (m < 10) ? '0' + m : '' + m;
		var sd = (d < 10) ? '0' + d : '' + d;	
		return '' + sm + '/' + sd + '/' + y;
	};
	
	this.setDateByString = function(s){
		if(s.length != 10) return false;
		var arg = new Array();
		arg = s.split('/');
		this.setDate(parseInt(arg[0]),parseInt(arg[1]),parseInt(arg[2]));
		return true;
	};
	
	this.setDate = function(m,d,y){
		var c = 0;
		
		if(m < 1) m = 1;
		else if(m > 12) m = 12;
		else c++;
		m--;
		
		if(y < 1900) y = 1900;
		else if(y > 2100) y = 2100;
		else c++;
		
		if(d < 1) d = 1;
		else if(this.isLeapYear() && d > 29) d = 29;
		else if(d > naMonthDays[m]) d = naMonthDays[m];
		else c++;
		
		nMonth = m;
		nYear = y;
		nSelMonth = m;
		nSelYear = y;
		nSelDay = d;
		
		if(c!=3) this.getRef(valueElementId).value = this.dateToString(nSelMonth+1,nSelDay,nSelYear);
		
		this.generate();
	};
	
	this.setDisplayMonth = function(m,y){
		if(m < 0) m = 0;
		else if(m > 11) m = 11;
		if(y < 1900) y = 1900;
		else if(y > 2100) y = 2100;
		nMonth = m;
		nYear = y;		
		this.generate();
	};
	
	this.setDisplayYear = function(y){
		if(y < 1900) y = 1900;
		else if(y > 2100) y = 2100;
		nYear = y;		
		this.generate();
	};

	this.generate = function(){
	
		var bHLSelected;
		if(nYear==nSelYear && nMonth==nSelMonth) bHLSelected = true;
		else bHLSelected = false;

		var bHLToday;
		if(nYear==nTodayYear && nMonth==nTodayMonth) bHLToday = true;
		else bHLToday = false;

		var firstDay = new Date(nYear, nMonth, 1);
		var startingDay = firstDay.getDay();
		
		var monthLength = naMonthDays[nMonth];
		if(this.isLeapYear()) monthLength = 29;
		
		var prev_month = nMonth-1, prev_year=nYear;
		var next_month = nMonth+1, next_year=nYear;
		
		if(prev_month < 0){
			prev_month = 11;
			prev_year -= 1;
		}

		if(next_month > 11){
			next_month = 0;
			next_year += 1;
		}
		
		var temp = '<table cellspacing="0" class="calendar">';

		if(sTitle.length>0) temp += '<tr><td class="cal_title" colspan="7">'+sTitle+'</td></tr>';
		
		temp += '<tr>';
		temp += '<td class="cal_yearnav" onclick="'+variableName+'.setDisplayYear('+(nYear-1)+')">&lt;</td>';
		temp += '<td class="cal_monthnav" onclick="'+variableName+'.setDisplayMonth('+prev_month+','+prev_year+')">&lt;</td>';
		temp += '<td class="cal_monthtitle" colspan="3">' + saMonthLabel[nMonth] + '&nbsp;' + nYear + '</td>';
		temp += '<td class="cal_monthnav" onclick="'+variableName+'.setDisplayMonth('+next_month+','+next_year+')">&gt;</td>';
		temp += '<td class="cal_yearnav" onclick="'+variableName+'.setDisplayYear('+(nYear+1)+')">&gt;</td>';
		temp += '</tr>';
		
		temp += '<tr>';
		for(var i = 0; i < 7; i++){
			temp += '<td class="cal_dow">' + saDayLabel[i] + '</td>';
		}		
		temp += '</tr><tr>';

		var day = 1;
		for(var i = 0; i < 9; i++){
			for(var j = 0; j <= 6; j++){
				temp += '<td';				
				if (day <= monthLength && (i > 0 || j >= startingDay)) {
					if(bHLSelected && day==nSelDay){
						temp += ' class="cal_selected"';
					}
					else{						
						if(bHLToday && day==nTodayDay){
							temp += ' class="cal_today"';
						}
						else{					
							temp += ' class="cal_day"';
						}
					}			
				
					temp += ' onclick="' + variableName + '.setSelectDate('+nMonth+','+day+','+nYear+')">' + day;
					day++;
				}
				else temp += '>';
				
				temp += '</td>';
			}
			
			if (day > monthLength) break;
			else temp += '</tr><tr>';
 		}
		
		temp += '</tr></table>';

		this.getRef(output_element_id).innerHTML = temp;
	};
	
	if(this.setDateByString(this.getRef(value_element_id).value) == false) this.generate();

	return this;
}