// Calendar.js
//
// Pop Up Calendar Code
//
// Author:  Alan Graham
// Date:    Jun-2000 ---> Dec-2002
//
// CHANGES
//
// cmoir 12-FEB-2002 Start Date Offsets will now take account of dates being set
//                   before the defined start-month-offset.

// Some CONSTANTS to be used throughout the script:
var FORM_PREFIX = "_fprc_";
var FORM_WEEKDAY_SUFFIX = "_weekday";
var FORM_DAY_SUFFIX = "_date";
var FORM_MONTH_YEAR_SUFFIX = "_month_year";

var MONTH_LIST    = new Array('January', 'February', 'March', 'April', 'May', 'June','July', 'August', 'September', 'October', 'November', 'December');
var WEEKDAY_LIST  = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');

// CALENDAR COLORS
var topBackground    = "#FFFFFF";               // BG COLOR OF THE TOP FRAME
var bottomBackground = "#FFFFFF";               // BG COLOR OF THE BOTTOM FRAME
var tableBGColor     = "#CCCCCC";               // BG COLOR OF THE BOTTOM FRAME'S TABLE
var cellColor        = "#FFFFFF";               // TABLE CELL BG COLOR OF THE DATE CELLS IN THE BOTTOM FRAME
var headingCellColor = "#CCCCCC";               // TABLE CELL BG COLOR OF THE WEEKDAY ABBREVIATIONS
var headingTextColor = "#333333";               // TEXT COLOR OF THE WEEKDAY ABBREVIATIONS
var dateColor        = "#333366";               // TEXT COLOR OF THE LISTED DATES (1-28+)
var focusColor       = "#FF0000";               // TEXT COLOR OF THE SELECTED DATE (OR CURRENT DATE)
var hoverColor       = "#000000";               // TEXT COLOR OF A LINK WHEN YOU HOVER OVER IT

var fontStyle        = "10pt arial, helvetica"; // TEXT STYLE FOR DATES
var headingFontStyle = "10pt arial, helvetica"; // TEXT STYLE FOR WEEKDAYS

// FORMATTING PREFERENCES
var bottomBorder  = false;        // TRUE/FALSE (WHETHER TO DISPLAY BOTTOM CALENDAR BORDER)
var tableBorder   = 0;            // SIZE OF CALENDAR TABLE BORDER (BOTTOM FRAME) 0=none

var calendarHTML = "<b>Error</b> - Calendar Not Initialised!";

// CALENDAR FUNCTIONS BEGIN HERE ---------------------------------------------------

function generateCalendar(day, month, year, startOffset, endOffset, formName, baseName)
{
  calendarHTML = generateCalendarHead()+
	               generateCalendarBodyTop(day, month, year, startOffset, endOffset, formName, baseName)+
				         generateCalendarBodyBottom(day, month, year, startOffset, endOffset, formName, baseName);
								 
	self.calendarWin.document.location = 'javascript:parent.opener.calendarHTML';
	self.calendarWin.focus();
}

function generateCalendarHead()
{
  var headHTML = "";
	
  headHTML += "<HTML><HEAD><TITLE>Select A Date</TITLE>"+
	            "<STYLE type='text/css'>" +
                "<!--" +
                "TD.heading { text-decoration: none; color:" + headingTextColor + "; font: " + headingFontStyle + "; }" +
                "A.focusDay:link { color: " + focusColor + "; text-decoration: none; font: " + fontStyle + "; }" +
                "A.focusDay:visited { color: " + focusColor + "; text-decoration: none; font: " + fontStyle + "; }" +
                "A.focusDay:hover { color: " + focusColor + "; text-decoration: none; font: " + fontStyle + "; }" +
                "A.weekday:link { color: " + dateColor + "; text-decoration: none; font: " + fontStyle + "; }" +
                "A.weekday:visited { color: " + dateColor + "; text-decoration: none; font: " + fontStyle + "; }" +
                "A.weekday:hover { color: " + hoverColor + "; font: " + fontStyle + "; }" +
                "-->" +
              "</STYLE>" +
							"</HEAD>"+
							"<BODY BGCOLOR='" + bottomBackground + "'>"+
							"<CENTER>";
							
  return headHTML;
}

function generateCalendarBodyTop(day, month, year, startOffset, endOffset, formName, baseName)
{
  var bodyHTML = "";
	
	// This part is the SELECT menu which allows month/year manipulation within the calendar
	bodyHTML += "<FORM NAME='calControl' onSubmit='return false;'>" +
                "<CENTER>" +
                "<TABLE CELLPADDING=0 CELLSPACING=1 BORDER=0>" +
                "<TR><TD COLSPAN=7>" +
                "<CENTER>" +
                "<SELECT NAME='monthyear' onChange=\"parent.opener.popupMonthYearChanged(this, "+day+", "+startOffset+", "+endOffset+", \'"+formName+"\', \'"+baseName+"\');\">\n"+
  	     
				           getMonthYearSelectEntries(month, year, startOffset, endOffset)+
	     
			          "</SELECT>"+
                "</CENTER>" +
                "</TD>" +
                "</TR>" +
                "</TABLE>" +
                "</CENTER>" +
              "</FORM>";
  return bodyHTML;
}

function generateCalendarBodyBottom(day, month, year, startOffset, endOffset, formName, baseName)
{
  var hiddenName     = "parent.opener.document."+formName+"."+baseName;
  var dayName        = "parent.opener.document."+formName+"."+FORM_PREFIX+baseName+FORM_DAY_SUFFIX;
  var monthYearName  = "parent.opener.document."+formName+"."+FORM_PREFIX+baseName+FORM_MONTH_YEAR_SUFFIX;
  var weekDayName    = "parent.opener.document."+formName+"."+FORM_PREFIX+baseName+FORM_WEEKDAY_SUFFIX;

  var days = getDaysInMonth(month, year);
	
	var blankCell = "<TD align=center bgcolor='" + cellColor + "'>&nbsp;&nbsp;&nbsp;</TD>";

	// if day is greater than number of days in this month, then highlight last day
  if (day > days) 
	{
      day = days;
  }
	
	var bodyHTML = "";
	
	// Build the table which contains the actual days of the month displayed
	bodyHTML = "<TABLE CELLPADDING=0 CELLSPACING=1 BORDER=" + tableBorder + " ALIGN=CENTER BGCOLOR='" + tableBGColor + "'>" +
             "<TR BGCOLOR='" + headingCellColor + "'>";
  
  // Generate row headings for week days
	for (var i in WEEKDAY_LIST) 
	{
    bodyHTML += "<TD class='heading' align=center>" + WEEKDAY_LIST[i].substring(0,3) + "</TD>";
  }
  
	bodyHTML += "</TR>";
	
	// DETERMINE WHAT DAY OF THE WEEK THE CALENDAR STARTS ON
  var firstOfMonth = new Date (year, month, 1);
  var startingPos  = firstOfMonth.getDay();
  
	days += startingPos;

  // KEEP TRACK OF THE COLUMNS, START A NEW ROW AFTER EVERY 7 COLUMNS
  var columnCount = 0;

  // MAKE BEGINNING NON-DATE CELLS BLANK
  for (i = 0; i < startingPos; i++) 
	{
    bodyHTML += blankCell;
    columnCount++;
  }

  // SET VALUES FOR DAYS OF THE MONTH
  var currentDay = 0;
  var dayType    = "weekday";

  // DATE CELLS CONTAIN A NUMBER
  for (i = startingPos; i < days; i++) 
	{
    var paddingChar = "&nbsp;";

    // ADJUST SPACING SO THAT ALL LINKS HAVE RELATIVELY EQUAL WIDTHS
    if (i-startingPos+1 < 10) 
		{
      padding = "&nbsp;&nbsp;";
    }
    else 
		{
      padding = "&nbsp;";
    }

    // GET THE DAY CURRENTLY BEING WRITTEN
    currentDay = i-startingPos+1;

    // SET THE TYPE OF DAY, THE focusDay GENERALLY APPEARS AS A DIFFERENT COLOR
    if (currentDay == day) 
		{
      dayType = "focusDay";
    }
    else 
		{
      dayType = "weekDay";
    }

    // ADD THE DAY TO THE CALENDAR STRING
    bodyHTML += "<TD align=center bgcolor='" + cellColor + "'>" +
                  "<a class='" + dayType + "' href='javascript:;' onClick='parent.opener.setDateFromPopup("+currentDay+", "+month+", "+year+", "+hiddenName+", "+weekDayName+", "+dayName+", "+monthYearName+");'>" + padding + currentDay + paddingChar + "</a></TD>";
    
		columnCount++;

    // START A NEW ROW WHEN NECESSARY
    if (columnCount % 7 == 0) 
		{
      bodyHTML += "</TR><TR>";
    }
  } // END for (i = startingPos; i < days; i++) 

  // MAKE REMAINING NON-DATE CELLS BLANK
  for (i=days; i<42; i++)  
	{
	  bodyHTML += blankCell;
    columnCount++;
    
		// START A NEW ROW WHEN NECESSARY
    if (columnCount % 7 == 0) {
      bodyHTML += "</TR>";
      if (i<41) 
			{
        bodyHTML += "<TR>";
      }
    }
  } // END for (i=days; i<42; i++)  
	
	if (bottomBorder) {
    bodyHTML += "<TR></TR>";
  }
	
	bodyHTML += "</BODY></HTML>";
	
	return bodyHTML;
}

function popupMonthYearChanged(monthYearMenu, day, startOffset, endOffset, formName, baseName)
{
  var selMonthYear = monthYearMenu.selectedIndex;
	
  var monthYear = monthYearMenu.options[monthYearMenu.selectedIndex].value;      
  var month     = monthYear.substring(0,monthYear.indexOf('_'));
  var year      = monthYear.substring(monthYear.indexOf('_')+1);
  
  generateCalendar( day ,month, year, startOffset, endOffset, formName, baseName);
}


function setDateFromPage(hiddenBox, weekDayBox, dayMenu, monthYearMenu)
{
  var monthYear = monthYearMenu.options[monthYearMenu.selectedIndex].value;
        
  var month     = monthYear.substring(0,monthYear.indexOf('_'));
  var year      = monthYear.substring(monthYear.indexOf('_')+1);
  var day       = dayMenu.options[dayMenu.selectedIndex].value;
  
  var maxDays = getDaysInMonth(month, year);
  
  if(day>maxDays)
  {
    day=maxDays;
  }
  
  dayMenu.options.length = 0;
  
  var dy;
  for(dy=1;dy<=maxDays;dy++)
  {
    dayMenu.options[dayMenu.options.length] = new Option(formatNumber(dy), makeTwoDigit(dy), false, day==dy); 
  }
    
  setDate(day, month, year, hiddenBox, weekDayBox);
}


function setDateFromPopup(day, month, year, hiddenBox, weekdayBox, dayMenu, monthYearMenu)
{	
  var maxDays = getDaysInMonth(month, year);
  
  if(day>maxDays)
  {
    day=maxDays;
  }
  dayMenu.options.length = 0;
	
  var dy;
  for(dy=1;dy<=maxDays;dy++)
  {
    dayMenu.options[dayMenu.options.length] = new Option(formatNumber(dy), makeTwoDigit(dy), false, day==dy); 
  }
	

  dayMenu.selectedIndex = day-1;
  
  index = 0;
  while(monthYearMenu[index].value != month+"_"+year){index++;}
  
  monthYearMenu.selectedIndex = index;

  setDate(day, month, year, hiddenBox, weekdayBox);  
	
	
  self.calendarWin.blur();
  self.calendarWin.close();
}

function setDate(day, month, year, hiddenBox, weekDayBox)
{
  weekDayBox.value = getDayOfWeek(day, month, year);

  var date = "";
	date = year;
	date += "-"+makeTwoDigit(parseInt(month)+1);
  date += "-"+makeTwoDigit(day)
    
  hiddenBox.value = date;
}


function getDayOfWeek(day, month, year)
{
  var d = new Date(year, month, day, 0, 0, 0, 0);
  return WEEKDAY_LIST[d.getDay()];
}

function getDayOfMonth(calStringDate)
{
  return (parseInt(calStringDate.substring(8),10));
}

function getMonth(calStringDate)
{
  return (parseInt(calStringDate.substring(5,7),10))-1;
}

function getYear(calStringDate)
{ 
  return parseInt(calStringDate.substring(0,4));    
}

function getMonthYearSelectEntries(activeMonth, activeYear, startOffset, endOffset)
{
  var today = new Date();
  var html = "";
  
  startDate   = new Date(today.getFullYear(), today.getMonth()+startOffset,1,0,0,0,0);
  endDate     = new Date(today.getFullYear(), today.getMonth()+endOffset,1,0,0,0,0);
   
  while(startDate.getTime()<endDate.getTime())
  {
    if(startDate.getMonth()==activeMonth && startDate.getFullYear()==activeYear)
    {
      html += '  <OPTION VALUE="'+startDate.getMonth()+'_'+startDate.getFullYear()+'" selected>'+MONTH_LIST[startDate.getMonth()]+', '+startDate.getFullYear()+'</OPTION>\n';
    }
    else
    {
      html += '  <OPTION VALUE="'+startDate.getMonth()+'_'+startDate.getFullYear()+'">'+MONTH_LIST[startDate.getMonth()]+', '+startDate.getFullYear()+'</OPTION>\n';
    }
      
    // ROLL TO NEXT YEAR
	if(startDate.getMonth()==11)
	{
	  startDate.setMonth(0,1);
	  startDate.setFullYear(startDate.getFullYear()+1);
	} else {
	  startDate.setMonth(startDate.getMonth()+1,1);
	}    
  }
    
  return html;
}

function createCalendar(defaultDate, formName, baseElementName, startMonthOffset, endMonthOffset, calImagePath)
{
  var dayOfWeekFormName  = FORM_PREFIX+baseElementName+FORM_WEEKDAY_SUFFIX;
  var dayOfMonthFormName = FORM_PREFIX+baseElementName+FORM_DAY_SUFFIX;
  var monthYearFormName  = FORM_PREFIX+baseElementName+FORM_MONTH_YEAR_SUFFIX;

  today = new Date();

  if(defaultDate==null || defaultDate == "null")
  {
	  defaultDate = today.getFullYear()+"-"+makeTwoDigit(today.getMonth()+1)+"-"+makeTwoDigit(today.getDate());
  }
 
   // SET startMonthOffset
  yearDifference = getYear(defaultDate) - today.getFullYear();
  monthDifference = getMonth(defaultDate) - today.getMonth();
  
  dateDifference = (yearDifference * 12) + monthDifference;
  
  if (dateDifference < startMonthOffset)
  {
  	startMonthOffset = dateDifference;
  }
  
  var calMonthDay = getDayOfMonth(defaultDate);
  var calMonth    = getMonth(defaultDate);
  var calYear     = getYear(defaultDate);

  var html = "";  
  html += "<INPUT type=\"hidden\" name=\""+baseElementName+"\" value=\""+defaultDate+"\">";
  html += "<INPUT type=\"textbox\" name=\""+dayOfWeekFormName+"\" value=\""+getDayOfWeek(calMonthDay, calMonth, calYear)+"\" size=\"11\" readonly=\"y\">&nbsp; ";
  
  html += "<SELECT name=\""+dayOfMonthFormName+"\" onChange=\"setDateFromPage(document."+formName+"."+baseElementName+", document."+formName+"."+dayOfWeekFormName+", this, document."+formName+"."+monthYearFormName+");\">";

  var maxDay = getDaysInMonth(calMonth, calYear); 
  var ii;
  for(ii=1;ii<=maxDay;ii++)
  {
    if(calMonthDay==ii)
    {
      html += "<OPTION value="+makeTwoDigit(ii)+" selected>"+formatNumber(ii)+"</OPTION>\n";
    }
    else
    {
      html += "<OPTION value="+makeTwoDigit(ii)+">"+formatNumber(ii)+"</OPTION>\n";
    }
  }

  html += "</SELECT>&nbsp;";
  html += "<SELECT name=\""+monthYearFormName+"\" onChange=\"setDateFromPage(document."+formName+"."+baseElementName+", document."+formName+"."+dayOfWeekFormName+", document."+formName+"."+dayOfMonthFormName+", this);\">"; 
  html += getMonthYearSelectEntries(calMonth, calYear, startMonthOffset, endMonthOffset);  
  html += "</SELECT>";
  html += "&nbsp;<a href=\"javascript:;\" onClick=\"showCalendarPopUp( document."+formName+"."+baseElementName+", "+startMonthOffset+", "+endMonthOffset+", '"+formName+"', '"+baseElementName+"');\"><img src=\""+calImagePath+"\" border=\"0\"></a>";
  
  return html;
}

function showCalendarPopUp(hiddenBox, startOffset, endOffset, formName, baseName)
{
  // Create the calendar for this calendar instance
  
  var dateStr  = hiddenBox.value;
  
  var day      = getDayOfMonth(dateStr);
  var month    = getMonth(dateStr);
  var year     = getYear(dateStr);	

  self.calendarWin = window.open('','cal','dependent=yes,width=185,height=200,titlebar=yes');

  generateCalendar(day, month, year, startOffset, endOffset, formName, baseName);
}

function makeTwoDigit(inValue) 
{
  var numVal = parseInt(inValue, 10);
  
  // VALUE IS LESS THAN TWO DIGITS IN LENGTH
  if (numVal < 10) {
    // ADD A LEADING ZERO TO THE VALUE AND RETURN IT
    return("0" + numVal);
  }
  else 
  {
    return numVal;
  }
}

function formatNumber(inValue)
{
  if(inValue%10==1 && inValue!=11)
  {
    return (inValue+"st");
  }
  else if(inValue%10==2 && inValue!=12)
  {
    return (inValue+"nd");
  }
  else if(inValue%10==3 && inValue!=13)
  {
    return (inValue+"rd");
  }
  else
  {
    return (inValue+"th");
  }
}

function getDaysInMonth(month, year)  {
  // Months run from 0 to 11.
    var days;

    // RETURN 31 DAYS
    if (month==0 || month==2 || month==4 || month==6 || month==7 ||
        month==9 || month==11)  {
        days=31;
    }
    // RETURN 30 DAYS
    else if (month==3 || month==5 || month==8 || month==10) {
        days=30;
    }
    // RETURN 29 DAYS
    else if (month==1)  {
        if (isLeapYear(year)) {
            days=29;
        }
        // RETURN 28 DAYS
        else {
            days=28;
        }
    }
    return (days);
}

function isLeapYear(Year) {
    if (((Year % 4)==0) && ((Year % 100)!=0) || ((Year % 400)==0)) {
        return (true);
    }
    else
    {
        return (false);
    }
}