/* 
CalendarPopup.js
Author: Matt Kruse
Last modified: 3/21/02
DESCRIPTION: This object implements a popup calendar to allow the user to
select a date, month, quarter, or year.
COMPATABILITY: Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
positioning errors - usually with Window positioning - occur on the 
Macintosh platform.
The calendar can be modified to work for any location in the world by 
changing which weekday is displayed as the first column, changing the month
names, and changing the column headers for each day.
USAGE:
var cal = new CalendarPopup(); 
var cal = new CalendarPopup('mydiv'); 
cal.select(inputObject, anchorname, dateFormat);
<A HREF="#" onClick="cal.select(document.forms[0].date,'anchorname','MM/dd/yyyy'); return false;">Select</A>
cal.setDisplayType(type);
cal.setReturnFunction(functionname);
cal.setReturnMonthFunction(functionname);
cal.setReturnQuarterFunction(functionname);
cal.setReturnYearFunction(functionname);
cal.showCalendar(anchorname, offsetX, offsetY);
cal.hideCalendar();
cal.setMonthNames("January","February","March",...);
cal.setMonthAbbreviations("Jan","Feb","Mar",...);
cal.setDayHeaders("S","M","T",...);
cal.setWeekStartDay(1); // week is Monday - Saturday
cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week
cal.setYearSelectStartOffset(2);
cal.setCloseLink("Close");
cal.offsetX = 20;
cal.offsetY = 20;
NOTES:
1) Requires the functions in AnchorPosition.js and PopupWindow.js
2) Your anchor tag MUST contain both NAME and ID attributes which are the 
same. For example:
<A NAME="test" ID="test"> </A>
3) There must be at least a space between <A> </A> for IE5.5 to see the 
anchor tag correctly. Do not do <A></A> with no space.
4) When a CalendarPopup object is created, a handler for 'onmouseup' is
attached to any event handler you may have already defined. Do NOT define
an event handler for 'onmouseup' after you define a CalendarPopup object 
or the autoHide() will not work correctly.
5) The calendar display uses "graypixel.gif" which is a 1x1 gray pixel of
color #C0C0C0. If this file is not present, the calendar display should 
still be fine but will not show the gray lines.
6) The calendar popup display uses style sheets to make it look nice.
*/ 
function y2k(number) { return (number < 1000) ? number + 1900 : number; }
function CalendarPopup() {
var c;
if (arguments.length>0) {
c = new PopupWindow(arguments[0]);
} else {
c = new PopupWindow();
c.setSize(150,175);
}
c.autoHide();
c.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
c.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
c.dayHeaders = new Array("S","M","T","W","T","F","S");
c.returnFunction = "CalendarPopup_tmpReturnFunction";
c.returnMonthFunction = "CalendarPopup_tmpReturnMonthFunction";
c.returnQuarterFunction = "CalendarPopup_tmpReturnQuarterFunction";
c.returnYearFunction = "CalendarPopup_tmpReturnYearFunction";
c.weekStartDay = 0;
c.isShowYearNavigation = false;
c.displayType = "date";
c.disabledWeekDays = new Object();
c.yearSelectStartOffset = 2;
c.currentDate = null;
c.closeLink="Close";
window.CalendarPopup_targetInput = null;
window.CalendarPopup_dateFormat = "mm/dd/yyyy";
window.CalendarPopup_targetFunc = null;
var today = new Date();
c.startDate = today ;//new Date(today.getFullYear(),today.getMonth(),today.getDate()-1,today.getHours(),today.getMinutes(),today.getSeconds());
c.endDate = new Date(today.getFullYear(),today.getMonth(),today.getDate()+365,today.getHours(),today.getMinutes(),today.getSeconds());
c.setReturnFunction = CalendarPopup_setReturnFunction;
c.setReturnMonthFunction = CalendarPopup_setReturnMonthFunction;
c.setReturnQuarterFunction = CalendarPopup_setReturnQuarterFunction;
c.setReturnYearFunction = CalendarPopup_setReturnYearFunction;
c.setMonthNames = CalendarPopup_setMonthNames;
c.setMonthAbbreviations = CalendarPopup_setMonthAbbreviations;
c.setDayHeaders = CalendarPopup_setDayHeaders;
c.setWeekStartDay = CalendarPopup_setWeekStartDay;
c.setDisplayType = CalendarPopup_setDisplayType;
c.setDisabledWeekDays = CalendarPopup_setDisabledWeekDays;
c.setYearSelectStartOffset = CalendarPopup_setYearSelectStartOffset;
c.setCloseLink = CalendarPopup_setCloseLink;
c.showCalendar = CalendarPopup_showCalendar;
c.hideCalendar = CalendarPopup_hideCalendar;
c.getStyles = CalendarPopup_getStyles;
c.refreshCalendar = CalendarPopup_refreshCalendar;
c.getCalendar = CalendarPopup_getCalendar;
c.select = CalendarPopup_select;
return c;
}
function CalendarPopup_tmpReturnFunction(y,m,d) { 
if (window.CalendarPopup_targetInput!=null) {
var d = new Date(y,m-1,d,0,0,0);
window.CalendarPopup_targetInput.value = formatDate(d,window.CalendarPopup_dateFormat);
} 
if (window.CalendarPopup_targetFunc!=null) { 
window.CalendarPopup_targetFunc(window.document);
}
}
function CalendarPopup_tmpReturnMonthFunction(y,m) { 
alert('Use setReturnMonthFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , month='+m); 
}
function CalendarPopup_tmpReturnQuarterFunction(y,q) { 
alert('Use setReturnQuarterFunction() to define which function will get the clicked results!\nYou clicked: year='+y+' , quarter='+q); 
}
function CalendarPopup_tmpReturnYearFunction(y) { 
alert('Use setReturnYearFunction() to define which function will get the clicked results!\nYou clicked: year='+y); 
}
function CalendarPopup_setReturnFunction(name) { this.returnFunction = name; }
function CalendarPopup_setReturnMonthFunction(name) { this.returnMonthFunction = name; }
function CalendarPopup_setReturnQuarterFunction(name) { this.returnQuarterFunction = name; }
function CalendarPopup_setReturnYearFunction(name) { this.returnYearFunction = name; }
function CalendarPopup_setMonthNames() {
for (var i=0; i<arguments.length; i++) { this.monthNames[i] = arguments[i];}
}
function CalendarPopup_setMonthAbbreviations() {
for (var i=0; i<arguments.length; i++) { this.monthAbbreviations[i] = arguments[i]; }
}
function CalendarPopup_setDayHeaders() {
for (var i=0; i<arguments.length; i++) { this.dayHeaders[i] = arguments[i]; }
}
function CalendarPopup_setWeekStartDay(day) { this.weekStartDay = day; }
function CalendarPopup_setDisplayType(type) {
if (type!="date"&&type!="week-end"&&type!="month"&&type!="quarter"&&type!="year") { alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); return false; }
this.displayType=type;
}
function CalendarPopup_setYearSelectStartOffset(num) { this.yearSelectStartOffset=num; }
function CalendarPopup_setDisabledWeekDays() {
this.disabledWeekDays = new Object();
for (var i=0; i<arguments.length; i++) { this.disabledWeekDays[arguments[i]] = true; }
}
function CalendarPopup_setCloseLink(text) {
this.closeLink = text;
}
function CalendarPopup_hideCalendar() {
if (arguments.length > 0) { window.popupWindowObjects[arguments[0]].hidePopup(); }
else { this.hidePopup(); }
}
function CalendarPopup_refreshCalendar(index) {
var calObject = window.popupWindowObjects[index];
if (arguments.length>1) { 
calObject.populate(calObject.getCalendar(arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]));
}
else {
calObject.populate(calObject.getCalendar());
}
calObject.refresh();
}
function CalendarPopup_showCalendar(anchorname, offsetX, offsetY) {
iframeObj = document.getElementById(this.divName+"iframe");
this.populate(this.getCalendar());
this.offsetX = offsetX;
if ( document.getElementById(this.divName+"iframe")) {
iframeObj.offsetX = offsetX;};
this.offsetY = offsetY;
if (document.getElementById(this.divName+"iframe")) {
iframeObj.offsetY =offsetY ;};
this.showPopup(anchorname, offsetX, offsetY);
}
function CalendarPopup_select(inputobj, linkname, offsetX, offsetY, format, callFunc) {
if (!window.getDateFromFormat) {
alert("calendar.select: To use this method you must also include 'Date.js' for date formatting");
return;
}
if (this.displayType!="date"&&this.displayType!="week-end") {
alert("calendar.select: This function can only be used with displayType 'date' or 'week-end'");
return;
}
if (inputobj.type!="text" && inputobj.type!="hidden" && inputobj.type!="textarea") { 
alert("calendar.select: Input object passed is not a valid form input object"); 
window.CalendarPopup_targetInput=null;
return;
}
window.CalendarPopup_targetInput = inputobj;
window.CalendarPopup_targetFunc = callFunc;
if (inputobj.value!="") {
var time = getDateFromFormat(inputobj.value,format);
if (time==0) { this.currentDate=null; }
else { 
if(this.startDate.getTime<time || this.endDate.getTime()<time){ 
this.currentDate=null;
} else{
this.currentDate = new Date(time);
}
}
}
else { this.currentDate=null; }
window.CalendarPopup_dateFormat = format;
this.showCalendar(linkname, offsetX, offsetY);
}
function CalendarPopup_getStyles() {
var result = "";
result += "<style type='text/css' media='screen' >\n";
result += " .calendar { border: 1px solid black; width: 134px; margin: 0; padding: 0; }\n";
result += " .calendar table caption { border: 0px; color: #5A595A; width: 134px; text-align: center;\n"; 
result += " margin: 0; padding: 0; font-size: 100%; height: 15px; line-height: 15px; min-height : 15px; \n";
result += " background-color: #CCCCCC; }\n";
result += " *html .calendar table caption { margin: 0; padding: 0; font-size: 100%; height: 15px; line-height: 15px; } \n"; 
result += " .calendar caption a { margin: 0; padding: 0; }\n"; 
result += " .calendar .align_caption { margin: 0; padding: 0; height: 15px; float: left; width: 92px; text-align:center; }\n";
result += " .calendar .link_caption_left { height: 15px; width: 19px; font-size: 90%; margin: 0; padding: 0;\n"; 
result += " float: left; border-right: 1px solid #FFFFFF; color: #313031; }\n";
result += " .calendar .link_caption_right { height: 15px; width: 19px; font-size: 90%; margin: 0; padding: 0; \n";
result += " float: right; border-left: 1px solid #FFFFFF; color: #313031; }\n";
result += " .calendar th { border: 0px; border-bottom: 1px solid black; \n";
result += " margin: 0; padding: 0 2px 0 0; height: 12px; width: 19px; text-align: right; \n";
result += " background: none; font-weight: normal; color: #5A595A; background-color: #FFFFFF; } \n";
result += " *html .calendar th { font-size: 90%; } \n"; 
result += " .calendar tfoot td { border: none; text-align:center; height: 14px; border-top: 1px solid #000000; font-size: 95%; \n";
result += " color: #808080; margin: 0; padding: 0; }\n";
result += " .calendar tbody td { border: none; height: 8px; text-align: center; margin: 0; padding: 0; color: #808080; font-size: 95%; font-family: Arial, Helvetica, sans-serif; } \n";
result += " *html .calendar tbody td { font-size: 85%; padding-bottom: 1px; } \n"; 
result += " .calendar tbody a { color: #000000; background: none; text-align: center; padding: 0; margin: 0; } \n"; 
result += " .calendar tfoot a { color: #000000; background: none; text-align: center; padding: 0; margin: 0; } \n"; 
result += " *html .calendar tfoot td { font-size: 110%; } \n"; 
result += "td.caltoday { background-color:#CCCCCC; font-weight: bold }\n";
result += "td.calthismonth a { text-decoration:none; color: #000000; background: none; }\n"; 
result += "</style>\n";
return result;
}
function CalendarPopup_getCalendar() {
var now = new Date();
var windowref = ""; 
var result = "";
result += '<div class="calendar"><table cellpadding="0" cellspacing="0" id="caltable">\n';
if (this.currentDate==null) { this.currentDate = now; }
if (arguments.length > 0) { var month = arguments[0]; }
else { var month = this.currentDate.getMonth()+1; }
if (arguments.length > 1) { var year = arguments[1]; }
else { var year = this.currentDate.getFullYear(); }
var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
daysinmonth[2] = 29;
}
var current_month = new Date(year,month-1,1);
var display_year = year;
var display_month = month;
var display_date = 1;
var weekday= current_month.getDay();
var offset = 0;
if (weekday >= this.weekStartDay) {
offset = weekday - this.weekStartDay;
} else {
offset = 7-this.weekStartDay+weekday;
}
if (offset > 0) {
display_month--;
if (display_month < 1) { display_month = 12; display_year--; }
display_date = daysinmonth[display_month]-offset+1;
}
var next_month = month+1;
var next_month_year = year;
if (next_month > 12) { next_month=1; next_month_year++; }
var last_month = month-1;
var last_month_year = year;
if (last_month < 1) { last_month=12; last_month_year--; }
var date_class;
var refresh = 'javascript:'+windowref+'CalendarPopup_refreshCalendar';
result += '<caption>\n';
if (hasNextOrLastMonth(month,year,this.startDate))
result += '<span class="link_caption_left"><a class="calFleche" href="'+refresh+'('+this.index+','+last_month+','+last_month_year+');"><img width="6" height="9" src="/dimg/cal_bwd.gif" border="0" alt="" /></a></span>\n';
else
result += '<span class="link_caption_left"><img width="19" height="10" src="/dimg/s.gif" /></span>\n'; 
result += '<span class="align_caption">'+this.monthNames[month-1]+' '+year+'</span>\n';
if (hasNextOrLastMonth(month,year,this.endDate))
result += '<span class="link_caption_right"><a class="calFleche" href="'+refresh+'('+this.index+','+next_month+','+next_month_year+');"><img src="/dimg/cal_fwd.gif" width="6" height="9" border="0" alt="" /></a></span>\n';
else
result += '<span class="link_caption_right"><img width="19" height="10" src="/dimg/s.gif" /></span></td>\n'; 
result += '</caption>\n';
result += '<thead>\n';
result += '<tr>\n';
var td = '<th scope="col">';
for (var j=0; j<7; j++) {
result += td + this.dayHeaders[(this.weekStartDay+j)%7]+'</th>\n';
}
result += '</tr>\n';
result += '</thead>\n'; 
result += '<tbody>'; 
while ((display_month <= month && display_year<=year) || (display_month==12 && display_year==(year-1))) {
result += '<tr>\n';
for (var col=1; col<=7; col++) { 
if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
td_class="class='caltoday'";
} else {
td_class="";
} 
var selected_date = display_date;
var selected_month = display_month;
var selected_year = display_year;
var d_start = new Date(selected_year,selected_month-1,selected_date,this.startDate.getHours(),this.startDate.getMinutes(),"60",0);
var d_end = new Date(selected_year,selected_month-1,selected_date,this.endDate.getHours(),this.endDate.getMinutes(),0,0);
if ((d_start.getTime() < this.startDate.getTime()) || (d_end.getTime() > this.endDate.getTime())){
date_class="calnotvalid";
result += '<td '+td_class+'>&nbsp;</td>\n';
} 
else if (display_month != month) {
date_class="calnotvalid";
result += '<td '+td_class+'>&nbsp;</td>\n';
} else {
date_class = "calthismonth";
if (this.disabledWeekDays[col-1]) { 
result += '<td '+td_class+'>'+display_date+'</td>\n';
}
else {
result += '<td '+td_class+'><a href="javascript:'+windowref+this.returnFunction+'('+selected_year+','+selected_month+','+selected_date+');'+windowref+'CalendarPopup_hideCalendar(\''+this.index+'\');">'+display_date+'</a></td>\n';
}
}
display_date++;
if (display_date > daysinmonth[display_month]) {
display_date=1;
display_month++;
}
if (display_month > 12) {
display_month=1;
display_year++;
}
}
result += '</tr>';
}
result += '</tbody>'; 
var current_weekday = now.getDay();
result += '<tfoot><tr>';
result += '<td colspan="8">';
if (this.disabledWeekDays[current_weekday+1]) { 
result += this.closeLink;
} else {
result += '<a href="javascript:'+windowref+'CalendarPopup_hideCalendar(\''+this.index+'\');">'+this.closeLink+'</a>';
}
result += '</td></tr></tfoot></table></div>\n';
return result;
}
function hasNextOrLastMonth(month,year,date)
{
if (month-1 == date.getMonth() && year == date.getFullYear())
return false;
else
return true;
}
