/*
       JavaScript functions for the Fourmilab Calendar Converter

                  by John Walker  --  September, MIM
              http://www.fourmilab.ch/documents/calendar/

                This program is in the public domain.
*/

function mod(a, b)
{
    return a - (b * Math.floor(a / b));
}

//  AMOD  --  Modulus function which returns numerator if modulus is zero

function amod(a, b)
{
    return mod(a - 1, b) + 1;
}


//  GREGORIAN_TO_JD  --  Determine Julian day number from Gregorian calendar date

var GREGORIAN_EPOCH = 1721425.5;



function gregorian_to_jd(year, month, day)
{
    return (GREGORIAN_EPOCH - 1) +
           (365 * (year - 1)) +
           Math.floor((year - 1) / 4) +
           (-Math.floor((year - 1) / 100)) +
           Math.floor((year - 1) / 400) +
           Math.floor((((367 * month) - 362) / 12) +
           ((month <= 2) ? 0 :
                               (leap_gregorian(year) ? -1 : -2)
           ) +
           day);
}


//  LEAP_GREGORIAN  --  Is a given year in the Gregorian calendar a leap year ?
function leap_gregorian(year)
{
    return ((year % 4) == 0) &&
            (!(((year % 100) == 0) && ((year % 400) != 0)));
}


/*  PAD  --  Pad a string to a given length with a given fill character.  */

function pad(str, howlong, padwith) {
    var s = str.toString();

    while (s.length < howlong) {
        s = padwith + s;
    }
    return s;
}

//  MAYAN_COUNT_TO_JD  --  Determine Julian day from Mayan long count
var MAYAN_COUNT_EPOCH = 584282.5;
function mayan_count_to_jd(baktun, katun, tun, uinal, kin)
{
    return MAYAN_COUNT_EPOCH +
           (baktun * 144000) +
           (katun  *   7200) +
           (tun    *    360) +
           (uinal  *     20) +
           kin;
}


//  JD_TO_MAYAN_COUNT  --  Calculate Mayan long count from Julian day
function jd_to_mayan_count(jd)
{
    var d, baktun, katun, tun, uinal, kin;
    jd = Math.floor(jd) + 0.5;
    d = jd - MAYAN_COUNT_EPOCH;
    baktun = Math.floor(d / 144000);
    d = mod(d , 144000);
    katun = Math.floor(d / 7200);
    d = mod(d , 7200);
    tun = Math.floor(d / 360);
    d = mod(d , 360);
    uinal = Math.floor(d / 20);
    kin = mod(d , 20);
    return new Array(baktun, katun, tun, uinal, kin);
}

//  JD_TO_MAYAN_HAAB  --  Determine Mayan Haab "month" and day from Julian day
var MAYAN_HAAB_MONTHS = new Array("Pop", "Uo", "Zip", "Zotz", "Tzec", "Xul",
                                  "Yaxkin", "Mol", "Chen", "Yax", "Zac", "Ceh",
                                  "Mac", "Kankin", "Muan", "Pax", "Kayab", "Cumku", "Uayeb");
/*
function jd_to_mayan_haab(jd)
{
    var lcount, day;
    jd = Math.floor(jd) + 0.5;
    lcount = jd - MAYAN_COUNT_EPOCH;
    day = mod((lcount + 8 + (18 - 1) * 20) , 365);
    return new Array (Math.floor(day / 20) + 1, mod(day , 20));
}
*/
function jd_to_mayan_haab(jd)
{
    var lcount, day;

    jd = Math.floor(jd) + 0.5;
    lcount = jd - MAYAN_COUNT_EPOCH;
    day = mod(lcount + 8 + ((18 - 1) * 20), 365);

    return new Array (Math.floor(day / 20) + 1, mod(day, 20));
}
//  JD_TO_MAYAN_TZOLKIN  --  Determine Mayan Tzolkin "month" and day from Julian day

var MAYAN_TZOLKIN_MONTHS = new Array("Imix (Smok)", "Ik (Wiatr)", "Akbal (Noc)", "Kan (Nasiono)", "Chicchan (Wąż)",
		"Cimi (Planetarny Łącznik)", "Manik (Ręka)", "Lamat (Gwiazda)", "Muluc (Księżyc)", "Oc (Pies)",
		"Chuen (Małpa)", "Eb (Człowiek)", "Ben (Podniebny Wędrowiec)", "Ix (Mag)", "Men (Orzeł)",
		"Cib (Wojownik)", "Caban (Ziemia)", "Etznab (Zwierciadło)", "Cauac (Wicher)", "Ahau (Słońce)");

function jd_to_mayan_tzolkin(jd)
{
    var lcount;
    jd = Math.floor(jd) + 0.5;
    lcount = jd - MAYAN_COUNT_EPOCH;
    return new Array (amod(lcount + 20, 20), amod(lcount + 4, 13));
}


function updateFromGregorian()
{
    var j, year, mon, mday, hour, min, sec,
        weekday, julcal, hebcal, islcal, hmindex, utime, isoweek,
        may_countcal, mayhaabcal, maytzolkincal, bahcal, frrcal,
        indcal, isoday, xgregcal;

    var today = new Date();
    var y = today.getYear();
    if (y < 1000) {
        y += 1900;
    }

    var gregorian_year = y;
    var gregorian_month = today.getMonth();
    var gregorian_day = today.getDate();
    var gregorian_hour = "00";
    var gregorian_min = "00";
    var gregorian_sec = "00";

    j = gregorian_to_jd(gregorian_year, gregorian_month + 1, gregorian_day) +
           (Math.floor(gregorian_sec + 60 * (gregorian_min + 60 * gregorian_hour) + 0.5) / 86400.0);

    //  Update Mayan Calendars
    //alert(j);
    may_countcal = jd_to_mayan_count(j);
    data = new Array();
    data['Baktun'] = may_countcal[0];
    data['Katun'] =  may_countcal[1];
    data['Tun'] = may_countcal[2];
    data['Uinal'] = may_countcal[3];
    data['Kin'] = may_countcal[4];
    mayhaabcal = jd_to_mayan_haab(j);
    data['Haab'] = "" + mayhaabcal[1] + " " + MAYAN_HAAB_MONTHS[mayhaabcal[0] - 1];
    maytzolkincal = jd_to_mayan_tzolkin(j);
    data['Tzolkin'] = "" + maytzolkincal[1] + " " + MAYAN_TZOLKIN_MONTHS[maytzolkincal[0] - 1];
    return data;
}
