//
//  JavaScriptLunarEclipseExplorer.js
//  SolarCoaster
//
//  Created by Steve Lidie on 10/17/18.
//  Copyright © 2018 Steve Lidie. All rights reserved.
//

// Javascript Lunar Eclipse Explorer
//
// This code is being released under the terms of the GNU General Public
// License (http://www.gnu.org/copyleft/gpl.html) with the request
// that if you do improve on it or use it in your own site,
// please let us know at
// chris@obyrne.com  and  espenak@gsfc.nasa.gov    Thanks!
//
//http://sunearth.gsfc.nasa.gov/eclipse/JLEX/JLEX-index.html
//

//
// Observer constants -
// (0) North Latitude (radians)
// (1) West Longitude (radians)
// (2) Altitude (metres)
// (3) West time zone (hours)
// (4) index into the elements array for the eclipse in question
// (5) maximum eclipse type
//
var obsvconst = new Array();

//
// Eclipse circumstances
//  (0) Event type (p1=-3, u1=-2, u2=-1, mid=0, u3=1, u4=2, p4=3)
//  (1) t
//  (2) hour angle
//  (3) declination
//  (4) alt
//  (5) visibility
//      (0 = above horizon, 1 = no event, 2 = below horizon)
//
var circumstances = new Array();

var month = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul",
                      "Aug","Sep","Oct","Nov","Dec");

var p1 = new Array();
var u1 = new Array();
var u2 = new Array();
var mid = new Array();
var u3 = new Array();
var u4 = new Array();
var p4 = new Array();

//
// Populate the circumstances array
// entry condition - circumstances[1] must contain the correct value
function populatecircumstances(elements, circumstances) {
    var index, t, ra, dec, h;
    
    index = obsvconst[4]
    t = circumstances[1]
    ra = elements[18+index] * t + elements[17+index]
    ra = ra * t + elements[16+index]
    dec = elements[21+index] * t + elements[20+index]
    dec = dec * t + elements[19+index]
    dec = dec * Math.PI / 180.0
    circumstances[3] = dec
    h = 15.0*(elements[6+index] + (t - elements[2+index]/3600.0)*1.00273791) - ra
    h = h * Math.PI / 180.0 - obsvconst[1]
    circumstances[2] = h
    circumstances[4] = Math.asin(Math.sin(obsvconst[0]) * Math.sin(dec) + Math.cos(obsvconst[0]) * Math.cos(dec) * Math.cos(h))
    circumstances[4] -= Math.asin(Math.sin(elements[7+index]*Math.PI/180.0) * Math.cos(circumstances[4]))
    if (circumstances[4] * 180.0 / Math.PI < elements[8+index] - 0.5667) {
        circumstances[5] = 2
    } else if (circumstances[4] < 0.0) {
        circumstances[4] = 0.0
        circumstances[5] = 0
    } else {
        circumstances[5] = 0
    }
}

//
// Populate the p1, u1, u2, mid, u3, u4 and p4 arrays
function getall(elements) {
    var pattern, index
    
    index = obsvconst[4]
    p1[1] = elements[index+9]
    populatecircumstances(elements,p1)
    mid[1] = elements[index+12]
    populatecircumstances(elements,mid)
    p4[1] = elements[index+15]
    populatecircumstances(elements,p4)
    if (elements[index+5] < 3) {
        u1[1] = elements[index+10]
        populatecircumstances(elements,u1)
        u4[1] = elements[index+14]
        populatecircumstances(elements,u4)
        if (elements[index+5] < 2) {
            u2[1] = elements[index+11]
            u3[1] = elements[index+13]
            populatecircumstances(elements,u2)
            populatecircumstances(elements,u3)
        } else {
            u2[5] = 1
            u3[5] = 1
        }
    } else {
        u1[5] = 1
        u2[5] = 1
        u3[5] = 1
        u4[5] = 1
    }
    if ((p1[5] != 0) && (u1[5] != 0) && (u2[5] != 0) && (mid[5] != 0) && (u3[5] != 0) && (u4[5] != 0) && (p4[5] != 0)) {
        mid[5] = 1
    }
}


//
// Get the local date of an event
function getdate(elements,circumstances) {
    var t, ans, jd, a, b, c, d, e, index
    
    index = obsvconst[4]
    // Calculate the JD for noon (TDT) the day before the day that contains T0
    jd = Math.floor(elements[index] - (elements[1+index]/24.0))
    // Calculate the local time (ie the offset in hours since midnight TDT on the day containing T0).
    t = circumstances[1] + elements[1+index] - obsvconst[3] - (elements[2+index] - 30.0) / 3600.0
    if (t < 0.0) {
        jd--;
    }
    if (t >= 24.0) {
        jd++;
    }
    if (jd >= 2299160.0) {
        a = Math.floor((jd - 1867216.25) / 36524.25)
        a = jd + 1 + a - Math.floor(a/4);
    } else {
        a = jd;
    }
    b = a + 1525.0
    c = Math.floor((b-122.1)/365.25)
    d = Math.floor(365.25*c)
    e = Math.floor((b - d) / 30.6001)
    d = b - d - Math.floor(30.6001*e)
    if (e < 13.5) {
        e = e - 1
    } else {
        e = e - 13
    }
    if (e > 2.5) {
        ans = c - 4716 + "-"
    } else {
        ans = c - 4715 + "-"
    }
    ans += month[e-1] + "-"
    if (d < 10) {
        ans = ans + "0"
    }
    ans = ans + d
    return ans
}

//
// Get the local time of an event
function gettime(elements,circumstances) {
    var t, ans, index, html, ital
    
    ans = ""
    index = obsvconst[4]
    t = circumstances[1] + elements[1+index] - obsvconst[3] - (elements[2+index] - 30.0) / 3600.0
    if (t < 0.0) {
        t = t + 24.0
    }
    if (t >= 24.0) {
        t = t - 24.0
    }
    if (t < 10.0) {
        ans = ans + "0"
    }
    ans = ans + Math.floor(t) + ":"
    t = (t * 60.0) - 60.0 * Math.floor(t)
    if (t < 10.0) {
        ans = ans + "0"
    }
    ans = ans + Math.floor(t)
    if (circumstances[5] == 2) {
        html = document.createElement("font");
        html.setAttribute("color","#808080");
        ital = document.createElement("i");
        ital.appendChild(document.createTextNode(ans));
        html.appendChild(ital);
        return html;
    } else {
        return document.createTextNode(ans);
    }
}

//
// Get the altitude
function getalt(circumstances) {
    var t, ans, html, ital
    
    t = circumstances[4] * 180.0 / Math.PI
    t = Math.floor(t+0.5)
    if (t < 0.0) {
        ans = "-"
        t = -t
    } else {
        ans = "+"
    }
    if (t < 10.0) {
        ans = ans + "0"
    }
    ans = ans + t
    if (circumstances[5] == 2) {
        html = document.createElement("font");
        html.setAttribute("color","#808080");
        ital = document.createElement("i");
        ital.appendChild(document.createTextNode(ans));
        html.appendChild(ital);
        return html;
    } else {
        return document.createTextNode(ans);
    }
}


function clearoldresults() {
    results = document.getElementById("el_results");
    resultsTable = document.getElementById("el_locationtable");
    if (resultsTable != null) results.removeChild(resultsTable);
    resultsTable = document.getElementById("el_resultstable");
    if (resultsTable != null) results.removeChild(resultsTable);
}

function initObservables ( latitude, longitude, altitude ) { // obsvconst=0.715584993317675,1.6755160819145563,0,0,0,4
    
    let now = getNowDateObject();
    
    obsvconst[0] = latitude * Math.PI / 180.0;
    obsvconst[1] = -longitude * Math.PI / 180.0;
    obsvconst[2] = altitude;              // altitude
    obsvconst[3] = - now.offset / 60 // DateTime offset is opposite of JS offset
    obsvconst[4] = 0;                     // elements array index
    obsvconst[5] = 4;                     // all lunar eclipses
    
} // end initObservables

/*var fullMonth = {
    'Jan' : 0,
    'Feb' : 1,
    'Mar' : 2,
    'Apr' : 3,
    'May' : 4,
    'Jun' : 5,
    'Jul' : 6,
    'Aug' : 7,
    'Sep' : 8,
    'Oct' : 9,
    'Nov' : 10,
    'Dec' : 11,
};

function before(now, humanDate) {
    
    var y = humanDate.substring(0,4);
    var m = humanDate.substring(5,8);
    m = fullMonth[ m ];
    var d = humanDate.substring(9,11);
    var eclDate = new Date( y, m, d );
    var start = new Date( now.getFullYear(), now.getMonth(), now.getDate() );
    return ( eclDate.getTime() < start.getTime() ? 1 : 0 );
    
} // end before*/

// CALCULATE!
function calculateforLunar(latitude, longitude, altitude, el) {
    
    initObservables ( latitude, longitude, altitude );
    var now = getNowDateObject();
    now = now.toJSDate()
    clearoldresults();
    let lunarEclipses = []
    
   /* results = document.getElementById("el_results");
    p = document.createElement("p");

    resultsTable = document.createElement("table");
    resultsTable.setAttribute("border","0");
    tbody = document.createElement("tbody");
    row = document.createElement("tr");
    td = document.createElement("td");
    row.appendChild(td);
    tbody.appendChild(row);
    resultsTable.appendChild(tbody);
    p.appendChild(resultsTable);
    results.appendChild(p);
    
    resultsTable = document.createElement("table");
    resultsTable.setAttribute("id","el_resultstable");
    resultsTable.setAttribute("width","150");
    resultsTable.setAttribute("border","2");
    tbody = document.createElement("tbody");
    row = document.createElement("tr");
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Calendar Date"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Ecl. Type"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Pen. Mag."));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Umbral Mag."));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Pen. Eclipse Begins"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Partial Eclipse Begins"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Total Eclipse Begins"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Mid. Eclipse"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Total Eclipse Ends"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Partial Eclipse Ends"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Pen. Eclipse Ends"));
    row.appendChild(td);
    td = document.createElement("th");
    td.appendChild(document.createTextNode("Alt"));
    row.appendChild(td);
    tbody.appendChild(row);*/

    var le = 0;
    for (i = 1 ; i < el.length ; i+=22) {
        //console.log("el="+)
        var line = new Array ();
        if (el[5+i] <= obsvconst[5]) {
            obsvconst[4]=i;
            getall(el)
            // Is there an event...
            if (mid[5] != 1) {
                row = document.createElement("tr");
                // Calendar Date
                td = document.createElement("td");
                td.setAttribute("nowrap","")
                val = document.createTextNode(getdate(el,p1));
                var leYear = val.textContent.substring(0,4);
                var nYear = now.getFullYear();
                if ( leYear != nYear && leYear != nYear+1 ) {
                    continue;
                } else {
                    // Ignore eclipse if before Today.
                    if ( before( now, val.textContent) ) {
                        continue;
                    }
                }
                td.appendChild(val);
                row.appendChild(td);
                line[0] = val.textContent; // ##########
                // Eclipse Type
                td = document.createElement("td");
                td.setAttribute("align","center")
                if (el[5+i] == 1) {
                    td.appendChild(document.createTextNode("T"))
                } else if (el[5+i] == 2) {
                    td.appendChild(document.createTextNode("P"))
                } else {
                    td.appendChild(document.createTextNode("N"))
                }
                row.appendChild(td);
                line[1] = h2t( td ); // ##########
                // Pen. Mag
                td = document.createElement("td");
                td.setAttribute("align","right");
                td.appendChild(document.createTextNode(el[3+i]));
                row.appendChild(td);
                line[2] = h2t( td ); // ##########
                // Umbral Mag
                td = document.createElement("td");
                td.setAttribute("align","right");
                td.appendChild(document.createTextNode(el[4+i]));
                row.appendChild(td);
                line[3] = h2t( td ); // ##########
                // P1
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(gettime(el, p1));
                row.appendChild(td)
                line[4] = h2t( td ); // ##########
                // P1 alt
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(getalt(p1));
                row.appendChild(td)
                line[5] = h2t( td ); // ##########
                if (u1[5] == 1) {
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[6] = h2t( td ); // ##########
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[7] = h2t( td ); // ##########
                } else {
                    // U1
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(gettime(el, u1));
                    row.appendChild(td)
                    line[6] = h2t( td ); // ##########
                    // U1 alt
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(getalt(u1));
                    row.appendChild(td)
                    line[7] = h2t( td ); // ##########
                }
                if (u2[5] == 1) {
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[8] = h2t( td ); // ##########
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[9] = h2t( td ); // ##########
                } else {
                    // U2
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(gettime(el, u2));
                    row.appendChild(td)
                    line[8] = h2t( td ); // ##########
                    // U2 alt
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(getalt(u2));
                    row.appendChild(td)
                    line[9] = h2t( td ); // ##########
                }
                // mid
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(gettime(el, mid));
                row.appendChild(td)
                line[10] = h2t( td ); // ##########
                // mid alt
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(getalt(mid));
                row.appendChild(td)
                line[11] = h2t( td ); // ##########
                if (u3[5] == 1) {
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[12] = h2t( td ); // ##########
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[13] = h2t( td ); // ##########
                } else {
                    // u3
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(gettime(el, u3));
                    row.appendChild(td)
                    line[12] = h2t( td ); // ##########
                    // u3 alt
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(getalt(u3));
                    row.appendChild(td)
                    line[13] = h2t( td ); // ##########
                }
                if (u4[5] == 1) {
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[14] = h2t( td ); // ##########
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(document.createTextNode("-"))
                    row.appendChild(td);
                    line[15] = h2t( td ); // ##########
                } else {
                    // u4
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(gettime(el, u4));
                    row.appendChild(td)
                    line[14] = h2t( td ); // ##########
                    // u4 alt
                    td = document.createElement("td");
                    td.setAttribute("align","center")
                    td.appendChild(getalt(u4));
                    row.appendChild(td)
                    line[15] = h2t( td ); // ##########
                }
                // P4
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(gettime(el, p4));
                row.appendChild(td)
                line[16] = h2t( td ); // ##########
                // P4 alt
                td = document.createElement("td");
                td.setAttribute("align","center")
                td.appendChild(getalt(p4));
                row.appendChild(td)
                line[17] = h2t( td ); // ##########
                //tbody.appendChild(row);
                //
                lunarEclipses[le] = line;
                le++;
            }
        }
    }
    //resultsTable.appendChild(tbody);
    //results.appendChild(resultsTable);
    return lunarEclipses;

}

/*function h2t( td ) {
    var t = td.textContent;
    var ih = td.innerHTML;
    var s = ih.search("<i>");
    return ( s == -1 ) ? t : "italic-"+t;
}*/

function setLunartimeperiod( timeperiod, simEvent ) {
    
    return eval( timeperiod + '(' + simEvent.locLat + ', ' + simEvent.locLon + ', ' + simEvent.locAlt + ')' )

}


