//
// Feiertage
//

// Die Berechnung der Monate beruecksichtigt, dass
// diese intern mit 0 bis 11 gekennzeichnet werden.
// Ob dies auch bei dem Konstruktor Date() so
// gewuenscht ist oder nur falsch dokumentiert ist,
// konnte bisweilen nicht in Erfahrung gebracht werden.

// 4stellige Jahreszahl
function get4DigitYear(theDate)
{
  if(theDate.getFullYear)
    return theDate.getFullYear()
  var y = theDate.getYear()
  return y + ((y < 1900) ? 1900 : 0)
}

// Ostersonntag nach Gauss'scher Formel
function Ostersonntag(Jahr)
{
  // Bem.: intern darf nicht einmal vor dem 1.1.1970 datiert werden
  if((Jahr < 1583) || (Jahr > 2299))
    return null

  var m, n

  if(Jahr <= 1699)
  {
    m = 22
    n = 2
  }
  else if(Jahr <= 1799)
  {
    m = 23
    n = 3
  }
  else if(Jahr <= 1899)
  {
    m = 23
    n = 4
  }
  else if(Jahr <= 2099)
  {
    m = 24
    n = 5
  }
  else if(Jahr <= 2199)
  {
    m = 24
    n = 6
  }
  else
  {
    m = 25
    n = 0
  }

  var a = Jahr % 19
  var b = Jahr % 4
  var c = Jahr % 7
  var d = (19 * a + m) % 30
  var e = (2 * b + 4 * c + 6 * d + n) % 7
  var t = 22 + d + e
  if(t > 31)
  {
    t = t - 31
    if(t == 26)
      t = 19
    else if(t == 25)
    {
      if((d == 28) && (e == 6) && (a > 10))
        t = 18
    }
    return new Date(Jahr, 3, t, 12, 0, 0)
  }

  return new Date(Jahr, 2, t, 12, 0, 0)
}

// 4. Advent in Abhaengigkeit des 1. Weihnachtstags berechnen
function VierterAdvent(Jahr)
{
  var StartDatum = new Date(Jahr, 11, 25, 12, 0, 0)
  var WTag       = StartDatum.getDay()
  var Temp       = StartDatum.getTime()

  StartDatum.setTime(Temp - ((WTag == 0) ? 7 : WTag) * 86400000)

  return StartDatum
}

// Feiertag anlegen mit Datum und Name
function feiertag(datum, name)
{
  this.datum = datum
  this.datum.setHours(12)
  this.datum.setMinutes(0)
  this.datum.setSeconds(0)
  this.name  = name

  return this
}

// Feiertag anlegen mit Datum (aus Zeit in Millisekunden) und Name
function feiertag_time(time, name)
{
  var TempDate = new Date()

  TempDate.setTime(time)
  this.datum = TempDate
  this.datum.setHours(12)
  this.datum.setMinutes(0)
  this.datum.setSeconds(0)
  this.name  = name

  return this
}

// Vergleichsfunktion zur Sortierung nach Datum
function compare_date(d1, d2)
{
  if(d1.datum.getTime() < d2.datum.getTime())
    return -1
  if(d1.datum.getTime() > d2.datum.getTime())
    return 1
  return 0
}

// Anlage eines Felds mit allen Feiertagen zum angegebenen Jahr
function feiertage(Jahr)
{
  var TagMS    = 86400000    // Anzahl Millisekunden pro Tag
  var Feiertag = new Array() // Feld fuer Feiertage
  var cnt      = 0           // Zaehler fuer Feiertage

  // Von Ostern abhaengige Feiertage
  var Ostern   = Ostersonntag(Jahr)
  var OTime    = Ostern.getTime()

  Feiertag[cnt]   = new feiertag(Ostern, "Ostersonntag")
  Feiertag[++cnt] = new feiertag_time(OTime + TagMS, "Ostermontag")
  Feiertag[++cnt] = new feiertag_time(OTime + 39 * TagMS, "Christi Himmelfahrt")
  Feiertag[++cnt] = new feiertag_time(OTime + 49 * TagMS, "Pfingstsonntag")
  Feiertag[++cnt] = new feiertag_time(OTime + 50 * TagMS, "Pfingstmontag")
  Feiertag[++cnt] = new feiertag_time(OTime + 60 * TagMS, "Fronleichnam")
  Feiertag[++cnt] = new feiertag_time(OTime - 48 * TagMS, "Rosenmontag")
  Feiertag[++cnt] = new feiertag_time(OTime - 47 * TagMS, "Fastnacht")
  Feiertag[++cnt] = new feiertag_time(OTime - 46 * TagMS, "Aschermittwoch")
  Feiertag[++cnt] = new feiertag_time(OTime - 2 * TagMS, "Karfreitag")

  // Vom 4. Advent abhaengige Feiertage
  var Advent4 = VierterAdvent(Jahr)
  var A4Time  = Advent4.getTime()

  Feiertag[++cnt] = new feiertag(Advent4, "4. Advent")
  Feiertag[++cnt] = new feiertag_time(A4Time - 7 * TagMS, "3. Advent")
  Feiertag[++cnt] = new feiertag_time(A4Time - 14 * TagMS, "2. Advent")
  Feiertag[++cnt] = new feiertag_time(A4Time - 21 * TagMS, "1. Advent")
  Feiertag[++cnt] = new feiertag_time(A4Time - 28 * TagMS, "Totensonntag")
  Feiertag[++cnt] = new feiertag_time(A4Time - 35 * TagMS, "Volkstrauertag")
  Feiertag[++cnt] = new feiertag_time(A4Time - 32 * TagMS, "Buß- und Bettag")

  // Feste Feiertage
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 0, 1), "Neujahr")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 0, 6), "Heilige 3 Könige")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 1, 14), "Valentinstag")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 4, 1), "Maifeiertag")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 7, 15), "Maria Himmelfahrt")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 9, 3), "Tag der Deutschen Einheit")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 9, 31), "Reformationstag")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 10, 1), "Allerheiligen")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 11, 24), "Heiligabend")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 11, 25), "1. Weihnachtstag")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 11, 26), "2. Weihnachtstag")
  Feiertag[++cnt] = new feiertag(new Date(Jahr, 11, 31), "Silvester")

  // Feiertage nach Datum sortieren
  Feiertag.sort(compare_date)

  // und zurueck!
  return Feiertag
}



