DayNames = new Array("Sunday","Monday","Tuesday","Wednesday",
                     "Thursday","Friday","Saturday")
MonthNames = new Array("","January","February","March","April",
                       "May","June","July","August","September",
                       "October","November","December")
MaxDays = new Array(0,31,29,31,30,31,30,31,31,30,31,30,31)
LeapYearMonthAdjust = new Array(0,6,2,3,6,1,4,6,2,5,0,3,5)
NonLeapYearMonthAdjust = new Array(0,0,3,3,6,1,4,6,2,5,0,3,5)


JulianCenturyAdjust = new Array(1,0,6,5,4,3,2,1,0,6,5)
GregorianCenturyAdjust = new Array(2,0,6,4,2,0,6,4,2,0,6)
PaschalFullMoonMonth = new Array(0,4,4,3,4,3,4,4,3,4,4,3,4,4,3,4,3,4,4,3)
PaschalFullMoonDay = new Array(0,14,3,23,11,31,18,8,28,16,5,25,13,2,22,10,30,17,7,27)

function IsInteger(StringText)
{
   if (StringText.length == 0)
      result = false
   else
   {
      result = true
      for (i=0; i<StringText.length; i++)
         if ((StringText.charAt(i) < "0") ||
             (StringText.charAt(i) > "9"))
            result = false 
   }
   return(result)
}

function JulianDoW(day,month,year)
{
   if ((year % 4) == 0)
      LeapYear = true
   else
      LeapYear = false

   result = Math.floor(((year % 100) * 5) / 4)
   result += day
   if (LeapYear)
      result += LeapYearMonthAdjust[month]
   else
      result += NonLeapYearMonthAdjust[month]
   result += JulianCenturyAdjust[Math.floor(year / 100) - 10]
   result %= 7
   return(result)
}

function GregorianDoW(day,month,year)
{
   if (((year % 100) == 0) && ((year % 400) != 0))
      LeapYear = false
   else if ((year % 4) == 0)
      LeapYear = true
   else
      LeapYear = false

   result = Math.floor(((year % 100) * 5) / 4)
   result += day
   if (LeapYear)
      result += LeapYearMonthAdjust[month]
   else
      result += NonLeapYearMonthAdjust[month]
   result += GregorianCenturyAdjust[Math.floor(year / 100) - 10]
   result %= 7
   return(result)
}

function DayOfWeek(DayText,MonthText,YearText)
{
   if ((!IsInteger(DayText)) &&        (!IsInteger(MonthText)) &&
       (!IsInteger(YearText)))
      return("Invalid date")
   else
   {
      day = eval(DayText)
      month = eval(MonthText)
      year = eval(YearText)

      /* Validate the date. The additional check for the Gregorian
       * Calendar will be performed later as required.
       */
      if ((day < 1) || (month < 1) || (month > 12) ||
            (year < 1000) || (year > 2099))
         return("Invalid date")
      else if ((day > MaxDays[month]) ||
               ((month == 2) && (day == 29) && ((year % 4) != 0)))
              return("Invalid date")
      else
      {
         if ((year < 1752) ||
             ((year == 1752) && (month < 9)) ||
             ((year == 1752) && (month == 9) && (day < 3)))
         {
            result = JulianDoW(day, month, year)

            return(day + " " + MonthNames[month] + " " + year +
                   " is a " + DayNames[result])
         }
         else if ((year > 1752) ||
                  ((year == 1752) && (month > 9)) ||
                  ((year == 1752) && (month == 9) && (day > 13)))
         {
            /* Process the date according to the Gregorian Calendar */
            if (((year % 100) == 0) && ((year % 400) != 0) &&
                (day == 29) && (month == 2))
               return("Invalid date")
            else
            {
               result = GregorianDoW(day, month, year)

               return(day + " " + MonthNames[month] +
                      " " + year +
                      " is a " + DayNames[result])
            }
         }
         else
            return("Invalid date")
      }
   }
}

function DateOfEaster(YearText)
{
   if (!IsInteger(YearText))
      return ("Invalid year")
   else
   {
      year = eval(YearText)
      if ((year < 1900) || (year > 2099))
         return ("Invalid year")
      else 
      {
         GoldenNumber = (year % 19) + 1
         day = PaschalFullMoonDay[GoldenNumber]
         month = PaschalFullMoonMonth[GoldenNumber]
         dayofweek = GregorianDoW(day, month, year)
         day += (7 - dayofweek)
         if (day > 31)
         { 
            day -= 31
            month++
         } 
         return("Easter " + year + " is " + day + " " + 
                MonthNames[month])
      }
   }
}

