// (C)opyright GM Arts 1997-1999
// http://users.chariot.net.au/~gmarts/eastalg.htm#easterscript

//  GLOBAL VARIABLES
//  ~~~~~~~~~~~~~~~~
   var jDay = 0;
   var jMonth = 0;
   var oDay = 0;
   var oMonth = 0;
   var wDay = 0;
   var wMonth = 0;
   var year = 0;
    
//  STARTUP CODE
//  ~~~~~~~~~~~~

// check browser is version 2 or more
   if (parseFloat(navigator.appVersion) < 2)
      alert ("You may need to upgrade your browser to reliably use the Easter Date calculator");

//  FUNCTIONS
//  ~~~~~~~~~
function ShowEasters(yr)
{
   year = parseInt(yr, 10);
   if (isNaN(year))
      year = 0;

   // reset vars
   jDay = 0;
   jMonth = 0;
   oDay = 0;
   oMonth = 0;
   wDay = 0;
   wMonth = 0;

   //get relevant Easter dates
   if ((year <= 325) || (year > 4099))
      alert("select a year from 326 to 4099");

   else {
      EasterJulian();   // used for all calculations
      if ((year > 325) && (year <= 1582)) {
         alert("Easter Sunday date for " + year + ": "
            + GetMonth(jMonth) + " " + GetOrdinal(jDay)
            + " in the Julian calendar ");
      }
      else {    // year is 1583 to 4099
         EasterOrthodox (year, jDay, jMonth);
         EasterWestern ();

         if (year <= 1923) { 
            // clarify that this is a Gregorian date
            // last known use of the Julian calendar was in 1923
            alert("Easter Sunday date for " + year + ": "
               + GetMonth(wMonth) + " " + GetOrdinal(wDay)
               + ".\n\n"
               + "Orthodox Easter Sunday date for " + year + ": "
               + GetMonth(oMonth) + " " + GetOrdinal(oDay)
               + "\n(in the Gregorian calendar), which is the same day as\n"
               + GetMonth(jMonth) + " " + GetOrdinal(jDay)
               + " in the Julian calendar\n(for regions using that calender at the time).");
         }  
         else {
            alert("Easter Sunday date for " + year + ": "
               + GetMonth(wMonth) + " " + GetOrdinal(wDay) + ".\n\n"
               + "Orthodox Easter Sunday date for " + year + ": "
               + GetMonth(oMonth) + " " + GetOrdinal(oDay) + ",\n"
               + "which is the same day as\n"
               + GetMonth(jMonth) + " " + GetOrdinal(jDay)
               + " in the Julian calendar (no longer in use).");
         }
      }
   }
}

function IntDiv (num, dvsr)
// performs integer division of num/dvsr - eg IntDiv(9,4)=2
{
   var negate = false;
   var result = 0;

   if (dvsr == 0)
      return null;
   else {
      if (num * dvsr < 0 )
         negate = true;
      if (num < 0)
         num = -num;
      if (dvsr < 0)
         dvsr = -dvsr;
      result = ((num - (num % dvsr)) / dvsr);
      if (negate)
         return -result;
      else
         return result;
   }
}

function GetMonth(m)
{
   //switch is better, but not supported in JavaScript ver 1.0
   if (m==3)
      return ("March");
   if (m==4)
      return ("April");
   if (m==5)
      return ("May");
}

function GetOrdinal(d)
{
   var rmdr = 0;
   rmdr = d % 10;

   if (((d >= 4) && (d <= 20)) || (rmdr == 0) || (rmdr > 3))
      return (d + "th");
   else {
      //switch is better, but not supported in JavaScript ver 1.0
      if (rmdr==1)
         return (d + "st");
      if (rmdr==2)
         return (d + "nd");
      if (rmdr==3)
         return (d + "rd");
   }
}

function EasterJulian()
{
   var g = 0;
   var i = 0;
   var j = 0;
   var p = 0;

   g = year % 19;
   i = (19 * g + 15) % 30;
   j = (year + IntDiv(year, 4) + i) % 7;
   p = i - j + 28;

   jDay = p;
   jMonth = 4;
   if (p > 31)
      jDay = p - 31;
   else
      jMonth = 3;
}

function EasterWestern()
{
   var g = 0;
   var c = 0;
   var h = 0;
   var i = 0;
   var j = 0;
   var p = 0;

   g = year % 19;
   c = IntDiv(year, 100);
   h = (c - IntDiv(c, 4) - IntDiv(8 * c + 13, 25) + 19 * g + 15) % 30;
   i = h - IntDiv(h, 28) * (1 - IntDiv(h, 28)
      * IntDiv(29, h + 1) * IntDiv(21 - g, 11));
   j = (year + IntDiv(year, 4) + i + 2 - c + IntDiv(c, 4)) % 7;
   p = i - j + 28;

   wDay = p;
   wMonth = 4;
   if (p > 31)
      wDay = p - 31;
   else
      wMonth = 3;
}

function EasterOrthodox (yr, jDay, jMonth)
/* Even though the Julian calendar is no longer in use
   Orthodox Easters are still based on this calendar
   NOTE! JULIAN Easter Date must be calculated first!
   This function converts Julian March and April
   Easter Sunday dates to Gregorian calendar dates  */
{
   var extra = 0;
   var tmp = 0;

   oDay = 0;
   oMonth = 0;

   if ((yr > 1582) && (yr <= 4099)) {
      extra = 10;
   if (yr > 1600) {
         tmp = IntDiv(yr, 100) - 16;
         extra = extra + tmp - IntDiv(tmp, 4);
      }
      
      oDay = jDay + extra;
      oMonth = jMonth;

      if ((oMonth == 3) && (oDay > 31)) {
         oMonth = 4;
         oDay = oDay - 31;
      }

      if ((oMonth == 4) && (oDay > 30)) {
         oMonth = 5;
         oDay = oDay - 30;
      }
   }
}

