var PI = Math.PI;
var DR = PI/180;
var K1 = 15*DR*1.0027379
var Moonrise = false;
var Moonset  = false;
var Rise_time = [0, 0];
var Set_time  = [0, 0];
var Rise_az = 0.0;
var Set_az  = 0.0;
var Sky = [0.0, 0.0, 0.0];
var RAn = [0.0, 0.0, 0.0];
var Dec = [0.0, 0.0, 0.0];
var VHz = [0.0, 0.0, 0.0];
var Now;

function calcMoon(d,m,y,xcor,ycor,moonpr, print)
{
    var lat = xcor;
    var lon = ycor;
    var year  = parseInt(y, 10);
    var month = parseInt(m, 10) - 1;
    var day   = parseInt(d, 10);
    Now = new Date(year, month, day, 0, 0, 0);
    return riseset(lat, lon, moonpr, print);
}

function riseset(lat,lon,moonpr,print)
{
    var i, j, k;
    var zone = Math.round(Now.getTimezoneOffset()/60);
    var jd = julian_day() - 2451545;
    var mp = new Array(3);
    for (i = 0; i < 3; i++)
    {
        mp[i] = new Array(3);
        for (j = 0; j < 3; j++) {
            mp[i][j] = 0.0;
        }
    }
    lon = lon/360;
    var tz = zone/24;
    var t0 = lst(lon, jd, tz);
    jd = jd + tz;
    for (k = 0; k < 3; k++)
    {
        moon(jd);
        mp[k][0] = Sky[0];
        mp[k][1] = Sky[1];
        mp[k][2] = Sky[2];
        jd = jd + 0.5;      
    }   
    if (mp[1][0] <= mp[0][0])
        mp[1][0] = mp[1][0] + 2*PI;
    if (mp[2][0] <= mp[1][0])
        mp[2][0] = mp[2][0] + 2*PI;
    RAn[0] = mp[0][0];
    Dec[0] = mp[0][1];
    Moonrise = false;
    Moonset  = false;
    for (k = 0; k < 24; k++)
    {
        ph = (k + 1)/24;
        RAn[2] = interpolate(mp[0][0], mp[1][0], mp[2][0], ph);
        Dec[2] = interpolate(mp[0][1], mp[1][1], mp[2][1], ph);
        VHz[2] = test_moon(k, zone, t0, lat, mp[1][2]);
        RAn[0] = RAn[2];
        Dec[0] = Dec[2];
        VHz[0] = VHz[2];
    }
    var mrise1=zintstr(Rise_time[0], 2);
    var mrise2=zintstr(Rise_time[1], 2);
    var mrise = mrise1  + ":" + mrise2;
    var mset1 = zintstr( Set_time[0], 2);
    var mset2 = zintstr( Set_time[1], 2);
    var mset  = mset1 + ":" + mset2;
    if (moonpr == "0") {
        fux('ks_w',mrise);
        fux('ks_z',mset);
        special_message();		
    } else {
        if (moonpr == "1") {
            if(print=="1") {
                document.write(Rise_time[0] + "." + mrise2);
            } else {
                return Rise_time[0] + "." + mrise2;
            }
        } else {
            if(print=="1") {
                document.write(Set_time[0] + "." + mset2);
            } else {
                return Set_time[0] + "." + mset2;
            }
        }
    }
}
function lst( lon, jd, z )
{
    var s = 24110.5 + 8640184.812999999*jd/36525 + 86636.6*z + 86400*lon;
    s = s/86400;
    s = s - Math.floor(s);
    return s*360*DR;
}
function interpolate( f0, f1, f2, p )
{
    var a = f1 - f0;
    var b = f2 - f1 - a;
    var f = f0 + p*(2*a + b*(2*p - 1));
    return f;
}
function test_moon( k, zone, t0, lat, plx )
{
    var ha = [0.0, 0.0, 0.0];
    var a, b, c, d, e, s, z;
    var hr, min, time;
    var az, hz, nz, dz;
    if (RAn[2] < RAn[0]) {
        RAn[2] = RAn[2] + 2*PI;
    }
    ha[0] = t0 - RAn[0] + k*K1;
    ha[2] = t0 - RAn[2] + k*K1 + K1;
    ha[1]  = (ha[2] + ha[0])/2;
    Dec[1] = (Dec[2] + Dec[0])/2;
    s = Math.sin(DR*lat);
    c = Math.cos(DR*lat);
    z = Math.cos(DR*(90.567 - 41.685/plx));
    if (k <= 0) {
        VHz[0] = s*Math.sin(Dec[0]) + c*Math.cos(Dec[0])*Math.cos(ha[0]) - z;
    }
    VHz[2] = s*Math.sin(Dec[2]) + c*Math.cos(Dec[2])*Math.cos(ha[2]) - z;
    if (sgn(VHz[0]) == sgn(VHz[2])) {
        return VHz[2];
    }
    VHz[1] = s*Math.sin(Dec[1]) + c*Math.cos(Dec[1])*Math.cos(ha[1]) - z;
    a = 2*VHz[2] - 4*VHz[1] + 2*VHz[0];
    b = 4*VHz[1] - 3*VHz[0] - VHz[2];
    d = b*b - 4*a*VHz[0];
    if (d < 0) {
        return VHz[2];
    }
    d = Math.sqrt(d);
    e = (-b + d)/(2*a);
    if (( e > 1 )||( e < 0 )) {
        e = (-b - d)/(2*a);
    }
    time = k + e + 1/120;
    hr   = Math.floor(time);
    min  = Math.floor((time - hr)*60);
    hz = ha[0] + e*(ha[2] - ha[0]);
    nz = -Math.cos(Dec[1])*Math.sin(hz);
    dz = c*Math.sin(Dec[1]) - s*Math.cos(Dec[1])*Math.cos(hz);
    az = Math.atan2(nz, dz)/DR;
    if (az < 0) az = az + 360;
    if ((VHz[0] < 0)&&(VHz[2] > 0))
    {
        Rise_time[0] = hr;
        Rise_time[1] = min;
        Rise_az = az;
        Moonrise = true;
    }
    if ((VHz[0] > 0)&&(VHz[2] < 0))
    {
        Set_time[0] = hr;
        Set_time[1] = min;
        Set_az = az;
        Moonset = true;
    }
    return VHz[2];
}

function special_message()
{
    if ((!Moonrise)&&(!Moonset))
    {
        if (VHz[2] < 0) {
            fux('ks_w',"--");
        } else {
            fux('ks_w',"--");
            fux('ks_z',"--");
        }
    } else {
        if (!Moonrise) {
            fux('ks_w',"--");
        } else if (!Moonset) {
            fux('ks_z',"--");
        }
    }
}

function moon( jd ) {
    var d, f, g, h, m, n, s, u, v, w;
    h = 0.606434 + 0.03660110129*jd;
    m = 0.374897 + 0.03629164709*jd;
    f = 0.259091 + 0.0367481952 *jd;
    d = 0.827362 + 0.03386319198*jd;
    n = 0.347343 - 0.00014709391*jd;
    g = 0.993126 + 0.0027377785 *jd;
    h = h - Math.floor(h);
    m = m - Math.floor(m);
    f = f - Math.floor(f);
    d = d - Math.floor(d);
    n = n - Math.floor(n);
    g = g - Math.floor(g);
    h = h*2*PI;
    m = m*2*PI;
    f = f*2*PI;
    d = d*2*PI;
    n = n*2*PI;
    g = g*2*PI;
    v = 0.39558*Math.sin(f + n);
    v = v + 0.082  *Math.sin(f);
    v = v + 0.03257*Math.sin(m - f - n);
    v = v + 0.01092*Math.sin(m + f + n);
    v = v + 0.00666*Math.sin(m - f);
    v = v - 0.00644*Math.sin(m + f - 2*d + n);
    v = v - 0.00331*Math.sin(f - 2*d + n);
    v = v - 0.00304*Math.sin(f - 2*d);
    v = v - 0.0024 *Math.sin(m - f - 2*d - n);
    v = v + 0.00226*Math.sin(m + f);
    v = v - 0.00108*Math.sin(m + f - 2*d);
    v = v - 0.00079*Math.sin(f - n);
    v = v + 0.00078*Math.sin(f + 2*d + n);   
    u = 1 - 0.10828*Math.cos(m);
    u = u - 0.0188 *Math.cos(m - 2*d);
    u = u - 0.01479*Math.cos(2*d);
    u = u + 0.00181*Math.cos(2*m - 2*d);
    u = u - 0.00147*Math.cos(2*m);
    u = u - 0.00105*Math.cos(2*d - g);
    u = u - 0.00075*Math.cos(m - 2*d + g);   
    w = 0.10478*Math.sin(m);
    w = w - 0.04105*Math.sin(2*f + 2*n);
    w = w - 0.0213 *Math.sin(m - 2*d);
    w = w - 0.01779*Math.sin(2*f + n);
    w = w + 0.01774*Math.sin(n);
    w = w + 0.00987*Math.sin(2*d);
    w = w - 0.00338*Math.sin(m - 2*f - 2*n);
    w = w - 0.00309*Math.sin(g);
    w = w - 0.0019 *Math.sin(2*f);
    w = w - 0.00144*Math.sin(m + n);
    w = w - 0.00144*Math.sin(m - 2*f - n);
    w = w - 0.00113*Math.sin(m + 2*f + 2*n);
    w = w - 0.00094*Math.sin(m - 2*d + g);
    w = w - 0.00092*Math.sin(2*m - 2*d);
    s = w/Math.sqrt(u - v*v);
    Sky[0] = h + Math.atan(s/Math.sqrt(1 - s*s));
    s = v/Math.sqrt(u);
    Sky[1] = Math.atan(s/Math.sqrt(1 - s*s));
    Sky[2] = 60.40974*Math.sqrt( u );
}

function julian_day()
{
    var a, b, jd;
    var gregorian;
    var month = Now.getMonth() + 1;
    var day   = Now.getDate();
    var year  = Now.getFullYear();
    gregorian = (year < 1583) ? false : true;
    if ((month == 1)||(month == 2))
    {
        year  = year  - 1;
        month = month + 12;
    }
    a = Math.floor(year/100);
    if (gregorian) {
        b = 2 - a + Math.floor(a/4);
    } else {
        b = 0.0;
    }
    jd = Math.floor(365.25*(year + 4716)) + Math.floor(30.6001*(month + 1)) + day + b - 1524.5;
    return jd;
}

function sgn( x )
{
    var rv;
    if (x > 0.0)      rv =  1;
    else if (x < 0.0) rv = -1;
    else              rv =  0;
    return rv;
}

function zintstr( num, width )
{
    var str = num.toString(10);
    var len = str.length;
    var intgr = "";
    var i;
    for (i = 0; i < width - len; i++) {
        intgr += '0';
    }
    for (i = 0; i < len; i++) {
        intgr += str.charAt(i);
    }
    return intgr;
}

function cintstr( num, width )
{
    var str = num.toString(10);
    var len = str.length;
    var intgr = "";
    var i;
    for (i = 0; i < width - len; i++) {
        intgr += ' ';
    }
    for (i = 0; i < len; i++) {
        intgr += str.charAt(i);
    }
    return intgr;
}

function frealstr( num, width, fract )
{
    var str = num.toFixed(fract);
    var len = str.length;
    var real = "";
    var i;
    for (i = 0; i < width - len; i++) {
        real += ' ';
    }
    for (i = 0; i < len; i++) {
        real += str.charAt(i);
    }
    return real;
}

function MoonPhase(year,month,day) {
    var j=dayno(year,month,day,12)+2451543.5;
    var T=(j-2451545.0)/36525;
    var T2=T*T;
    var T3=T2*T;
    var T4=T3*T;
    var D=297.8501921+445267.1114034*T-0.0018819*T2+T3/545868.0-T4/113065000.0; 
    var MP=134.9633964+477198.8675055*T+0.0087414*T2+T3/69699.0-T4/14712000.0;
    var M=357.5291092+35999.0502909*T-0.0001536*T2+T3/24490000.0;
    var pa=180.0-D-6.289*sind(MP)+2.1*sind(M)-1.274*sind(2*D-MP)-0.658*sind(2*D)-0.214*sind(2*MP)-0.11*sind(D);
    return(rev(pa));
}

function MoonQuarters(year,month,day) {
    var quarters = new Array();
    var k=Math.floor((year+((month-1)+day/30)/12-2000)*12.3685);
    var T=k/1236.85;
    var M=rev(2.5534+29.10535669*k-0.0000218*T*T);
    var MP=rev(201.5643+385.81693528*k+0.0107438*T*T+0.00001239*T*T*T-0.00000011*T*T*T);
    var E=1-0.002516*T-0.0000074*T*T;
    var F=rev(160.7108+390.67050274*k-0.0016341*T*T-0.00000227*T*T*T+0.000000011*T*T*T*T);
    var Omega=rev(124.7746-1.56375580*k+0.0020691*T*T+0.00000215*T*T*T);
    var A = new Array();
    A[1]=rev(299.77+ 0.107408*k-0.009173*T*T);
    A[2]=rev(251.88+ 0.016321*k);
    A[3]=rev(251.83+26.651886*k);
    A[4]=rev(349.42+36.412478*k);
    A[5]=rev( 84.88+18.206239*k);
    A[6]=rev(141.74+53.303771*k);
    A[7]=rev(207.14+ 2.453732*k);
    var JDE0=2451550.09765+29.530588853*k+0.0001337*T*T-0.000000150*T*T*T+0.00000000073*T*T*T*T;
    JDE0=JDE0-56.184/(24*60*60);
    var JDE=JDE0 -0.40720*sind(MP)+0.17241*E*sind(M)+0.01608*sind(2*MP)+0.01039*sind(2*F)+0.00739*E*sind(MP-M)-0.00514*E*sind(MP+M)+0.00208*E*E*sind(2*M)-0.00111*sind(MP-2*F)-0.00057*sind(MP+2*F)+0.00056*E*sind(2*MP+M)-0.00042*sind(3*MP)+0.00042*E*sind(M+2*F)+0.00038*E*sind(M-2*F)-0.00024*E*sind(2*MP-M)-0.00017*sind(Omega)-0.00007*sind(MP+2*M);
    quarters[0]=JDE+0.000325*sind(A[1])+0.000165*sind(A[2])+0.000164*sind(A[3])+0.000126*sind(A[4])+0.000110*sind(A[5])+0.000062*sind(A[6])+0.000060*sind(A[7]);
    JDE=JDE0+29.530588853*0.25;
    M=rev(M+29.10535669*0.25);
    MP=rev(MP+385.81693528*0.25);
    F=rev(F+390.67050274*0.25);
    Omega=rev(Omega-1.56375580*0.25);
    A[1]=rev(A[1]+ 0.107408*0.25);
    A[2]=rev(A[2]+ 0.016321*0.25);
    A[3]=rev(A[3]+26.651886*0.25);
    A[4]=rev(A[4]+36.412478*0.25);
    A[5]=rev(A[5]+18.206239*0.25);
    A[6]=rev(A[6]+53.303771*0.25);
    A[7]=rev(A[7]+ 2.453732*0.25);
    JDE=JDE-0.62801*sind(MP)+0.17172*E*sind(M)-0.01183*E*sind(MP+M)+0.00862*sind(2*MP)+0.00804*sind(2*F)+0.00454*E*sind(MP-M)+0.00204*E*E*sind(2*M)-0.00180*sind(MP-2*F)-0.00070*sind(MP+2*F)-0.00040*sind(3*MP)-0.00034*E*sind(2*MP-M)+0.00032*E*sind(M+2*F)+0.00032*E*sind(M-2*F)-0.00028*E*E*sind(MP+2*M)+0.00027*E*sind(2*MP+M)-0.00017*sind(Omega);
    JDE=JDE+ (0.00306 - 0.00038*E*cosd(M) + 0.00026*cosd(MP) - 0.00002*cosd(MP-M) + 0.00002*cosd(MP+M) + 0.00002*cosd(2*F));
    quarters[1]=JDE+0.000325*sind(A[1])+0.000165*sind(A[2])+0.000164*sind(A[3])+0.000126*sind(A[4])+0.000110*sind(A[5])+0.000062*sind(A[6])+0.000060*sind(A[7]);
    JDE=JDE0+29.530588853*0.5;
    M=rev(M+29.10535669*0.25);
    MP=rev(MP+385.81693528*0.25);
    F=rev(F+390.67050274*0.25);
    Omega=rev(Omega-1.56375580*0.25);
    A[1]=rev(A[1]+ 0.107408*0.25);
    A[2]=rev(A[2]+ 0.016321*0.25);
    A[3]=rev(A[3]+26.651886*0.25);
    A[4]=rev(A[4]+36.412478*0.25);
    A[5]=rev(A[5]+18.206239*0.25);
    A[6]=rev(A[6]+53.303771*0.25);
    A[7]=rev(A[7]+ 2.453732*0.25);
    JDE=JDE-0.40614*sind(MP)+0.17302*E*sind(M)+0.01614*sind(2*MP)+0.01043*sind(2*F)+0.00734*E*sind(MP-M)-0.00515*E*sind(MP+M)+0.00209*E*E*sind(2*M)-0.00111*sind(MP-2*F)-0.00057*sind(MP+2*F)+0.00056*E*sind(2*MP+M)-0.00042*sind(3*MP)+0.00042*E*sind(M+2*F)+0.00038*E*sind(M-2*F)-0.00024*E*sind(2*MP-M)-0.00017*sind(Omega)-0.00007*sind(MP+2*M);
    quarters[2]=JDE+0.000325*sind(A[1])+0.000165*sind(A[2])+0.000164*sind(A[3])+0.000126*sind(A[4])+0.000110*sind(A[5])+0.000062*sind(A[6])+0.000060*sind(A[7]);
    JDE=JDE0+29.530588853*0.75;
    M=rev(M+29.10535669*0.25);
    MP=rev(MP+385.81693528*0.25);
    F=rev(F+390.67050274*0.25);
    Omega=rev(Omega-1.56375580*0.25);
    A[1]=rev(A[1]+ 0.107408*0.25);
    A[2]=rev(A[2]+ 0.016321*0.25);
    A[3]=rev(A[3]+26.651886*0.25);
    A[4]=rev(A[4]+36.412478*0.25);
    A[5]=rev(A[5]+18.206239*0.25);
    A[6]=rev(A[6]+53.303771*0.25);
    A[7]=rev(A[7]+ 2.453732*0.25);
    JDE=JDE-0.62801*sind(MP)+0.17172*E*sind(M)-0.01183*E*sind(MP+M)+0.00862*sind(2*MP)+0.00804*sind(2*F)+0.00454*E*sind(MP-M)+0.00204*E*E*sind(2*M)-0.00180*sind(MP-2*F)-0.00070*sind(MP+2*F)-0.00040*sind(3*MP)-0.00034*E*sind(2*MP-M)+0.00032*E*sind(M+2*F)+0.00032*E*sind(M-2*F)-0.00028*E*E*sind(MP+2*M)+0.00027*E*sind(2*MP+M)-0.00017*sind(Omega);
    JDE=JDE-(0.00306-0.00038*E*cosd(M)+0.00026*cosd(MP)-0.00002*cosd(MP-M)+0.00002*cosd(MP+M)+0.00002*cosd(2*F));
    quarters[3]=JDE+0.000325*sind(A[1])+0.000165*sind(A[2])+0.000164*sind(A[3])+0.000126*sind(A[4])+0.000110*sind(A[5])+0.000062*sind(A[6])+0.000060*sind(A[7]);
    return quarters;
}
