/*
 *******************************************************************************
 * Copyright (C) 1996-2000, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/CalendarAstronomer.java,v $ 
 * $Date: 2000/11/28 22:17:06 $ 
 * $Revision: 1.5 $
 *
 *****************************************************************************************
 */
package com.ibm.util;

import java.util.*;
import java.text.*;

/**
 * <code>CalendarAstronomer</code> is a class that can perform the calculations to
 * determine the positions of the sun and moon, the time of sunrise and
 * sunset, and other astronomy-related data.  The calculations it performs
 * are in some cases quite complicated, and this utility class saves you
 * the trouble of worrying about them.
 * <p>
 * The measurement of time is a very important part of astronomy.  Because
 * astronomical bodies are constantly in motion, observations are only valid
 * at a given moment in time.  Accordingly, each <code>CalendarAstronomer</code>
 * object has a <code>time</code> property that determines the date
 * and time for which its calculations are performed.  You can set and
 * retrieve this property with {@link #setDate setDate}, {@link #getDate getDate}
 * and related methods.
 * <p>
 * Almost all of the calculations performed by this class, or by any
 * astronomer, are approximations to various degrees of accuracy.  The
 * calculations in this class are mostly modelled after those described
 * in the book
 * <a href="http://www.amazon.com/exec/obidos/ISBN=0521356997" target="_top">
 * Practical Astronomy With Your Calculator</a>, by Peter J.
 * Duffett-Smith, Cambridge University Press, 1990.  This is an excellent
 * book, and if you want a greater understanding of how these calculations
 * are performed it a very good, readable starting point.
 * <p>
 * <strong>WARNING:</strong> This class is very early in its development, and
 * it is highly likely that its API will change to some degree in the future.
 * At the moment, it basically does just enough to support {@link IslamicCalendar}
 * and {@link ChineseCalendar}.
 *
 * @author Laura Werner
 * @author Alan Liu
 */
public class CalendarAstronomer {
    
    //-------------------------------------------------------------------------
    // Astronomical constants
    //-------------------------------------------------------------------------

    /**
     * The number of standard hours in one sidereal day.
     * Approximately 24.93.
     */
    public static final double SIDEREAL_DAY = 23.93446960027;
    
    /**
     * The number of sidereal hours in one mean solar day.
     * Approximately 24.07.
     */
    public static final double SOLAR_DAY =  24.065709816;
    
    /**
     * The average number of solar days from one new moon to the next.  This is the time
     * it takes for the moon to return the same ecliptic longitude as the sun.
     * It is longer than the sidereal month because the sun's longitude increases
     * during the year due to the revolution of the earth around the sun.
     * Approximately 29.53.
     *
     * @see #SIDEREAL_MONTH
     */
    public static final double SYNODIC_MONTH = 29.530588853;
    
    /**
     * The average number of days it takes
     * for the moon to return to the same ecliptic longitude relative to the
     * stellar background.  This is referred to as the sidereal month.
     * It is shorter than the synodic month due to
     * the revolution of the earth around the sun.
     * Approximately 27.32.
     *
     * @see #SYNODIC_MONTH
     */
    public static final double SIDEREAL_MONTH = 27.32166;
    
    /**
     * The average number number of days between successive vernal equinoxes.
     * Due to the precession of the earth's
     * axis, this is not precisely the same as the sidereal year.
     * Approximately 365.24
     *
     * @see #SIDEREAL_YEAR
     */
    public static final double TROPICAL_YEAR = 365.242191;
    
    /**
     * The average number of days it takes
     * for the sun to return to the same position against the fixed stellar
     * background.  This is the duration of one orbit of the earth about the sun
     * as it would appear to an outside observer.
     * Due to the precession of the earth's
     * axis, this is not precisely the same as the tropical year.
     * Approximately 365.25.
     *
     * @see #TROPICAL_YEAR
     */
    public static final double SIDEREAL_YEAR = 365.25636;

    //-------------------------------------------------------------------------
    // Time-related constants
    //-------------------------------------------------------------------------

    /** The number of milliseconds in one second. */
    public static final int  SECOND_MS = 1000;

    /** The number of milliseconds in one minute. */
    public static final int  MINUTE_MS = 60*SECOND_MS;

    /** The number of milliseconds in one hour. */
    public static final int  HOUR_MS   = 60*MINUTE_MS;

    /** The number of milliseconds in one day. */
    public static final long DAY_MS    = 24*HOUR_MS;

    /**
     * The start of the julian day numbering scheme used by astronomers, which
     * is 1/1/4713 BC (Julian), 12:00 GMT.  This is given as the number of milliseconds
     * since 1/1/1970 AD (Gregorian), a negative number.
     * Note that julian day numbers and
     * the Julian calendar are <em>not</em> the same thing.  Also note that
     * julian days start at <em>noon</em>, not midnight.
     */
    public static final long JULIAN_EPOCH_MS = -210866760000000L;
    

    //-------------------------------------------------------------------------
    // Assorted private data used for conversions
    //-------------------------------------------------------------------------

    // My own copies of these so compilers are more likely to optimize them away
    static private final double PI = 3.14159265358979323846;
    static private final double PI2 = PI * 2.0;

    static private final double HOUR_RAD = PI / 12;        // hours -> radians
    static private final double RAD_HOUR = 12 / PI;        // radians -> hours
    static private final double DEG_RAD  = PI / 180;        // degrees -> radians
    static private final double RAD_DEG  = 180 / PI;        // radians -> degrees
    
    //-------------------------------------------------------------------------
    // Constructors
    //-------------------------------------------------------------------------

    /**
     * Construct a new <code>CalendarAstronomer</code> object that is initialized to
     * the current date and time.
     */
    public CalendarAstronomer() {
        this(System.currentTimeMillis());
    }
    
    /**
     * Construct a new <code>CalendarAstronomer</code> object that is initialized to
     * the specified date and time.
     */
    public CalendarAstronomer(Date d) {
        this(d.getTime());
    }
    
    /**
     * Construct a new <code>CalendarAstronomer</code> object that is initialized to
     * the specified time.  The time is expressed as a number of milliseconds since
     * January 1, 1970 AD (Gregorian).
     *
     * @see java.util.Date#getTime
     */
    public CalendarAstronomer(long aTime) {
        time = aTime;
    }
    
    /**
     * Construct a new <code>CalendarAstronomer</code> object with the given
     * latitude and longitude.  The object's time is set to the current
     * date and time.
     * <p>
     * @param longitude The desired longitude, in <em>degrees</em> east of
     *                  the Greenwich meridian.
     *
     * @param latitude  The desired latitude, in <em>degrees</em>.  Positive
     *                  values signify North, negative South.
     *
     * @see java.util.Date#getTime
     */
    public CalendarAstronomer(double longitude, double latitude) {
        this();
        fLongitude = normPI(longitude * DEG_RAD);
        fLatitude  = normPI(latitude  * DEG_RAD);
        fGmtOffset = (long)(fLongitude * 24 * HOUR_MS / PI2);
    }
    
    
    //-------------------------------------------------------------------------
    // Time and date getters and setters
    //-------------------------------------------------------------------------
    
    /**
     * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
     * astronomical calculations are performed based on this time setting.
     *
     * @param aTime the date and time, expressed as the number of milliseconds since
     *              1/1/1970 0:00 GMT (Gregorian).
     *
     * @see #setDate
     * @see #getTime
     */
    public void setTime(long aTime) {
        time = aTime;
        clearCache();
    }
    
    /**
     * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
     * astronomical calculations are performed based on this time setting.
     *
     * @param aTime the time and date, expressed as a <code>Date</code> object.
     *
     * @see #setTime
     * @see #getDate
     */
    public void setDate(Date date) {
        setTime(date.getTime());
    }
    
    /**
     * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
     * astronomical calculations are performed based on this time setting.
     *
     * @param jdn   the desired time, expressed as a "julian day number",
     *              which is the number of elapsed days since 
     *              1/1/4713 BC (Julian), 12:00 GMT.  Note that julian day
     *              numbers start at <em>noon</em>.  To get the jdn for
     *              the corresponding midnight, subtract 0.5.
     *
     * @see #getJulianDay
     * @see #JULIAN_EPOCH_MS
     */
    public void setJulianDay(double jdn) {
        time = (long)(jdn * DAY_MS) + JULIAN_EPOCH_MS;
        clearCache();
        julianDay = jdn;
    }
    
    /**
     * Get the current time of this <code>CalendarAstronomer</code> object,
     * represented as the number of milliseconds since
     * 1/1/1970 AD 0:00 GMT (Gregorian).
     *
     * @see #setTime
     * @see #getDate
     */
    public long getTime() {
        return time;
    }
    
    /**
     * Get the current time of this <code>CalendarAstronomer</code> object,
     * represented as a <code>Date</code> object.
     *
     * @see #setDate
     * @see #getTime
     */
    public Date getDate() {
        return new Date(time);
    }
    
    /**
     * Get the current time of this <code>CalendarAstronomer</code> object,
     * expressed as a "julian day number", which is the number of elapsed
     * days since 1/1/4713 BC (Julian), 12:00 GMT.
     *
     * @see #setJulianDay
     * @see #JULIAN_EPOCH_MS
     */
    public double getJulianDay() {
        if (julianDay == INVALID) {
            julianDay = (double)(time - JULIAN_EPOCH_MS) / (double)DAY_MS;
        }
        return julianDay;
    }
    
    /**
     * Return this object's time expressed in julian centuries:
     * the number of centuries after 1/1/1900 AD, 12:00 GMT
     *
     * @see #getJulianDay
     */
    public double getJulianCentury() {
        if (julianCentury == INVALID) {
            julianCentury = (getJulianDay() - 2415020.0) / 36525;
        }
        return julianCentury;
    }

    /**
     * Returns the current Greenwich sidereal time, measured in hours
     */
    public double getGreenwichSidereal() {
        if (siderealTime == INVALID) {
            // See page 86 of "Practial Astronomy with your Calculator",
            // by Peter Duffet-Smith, for details on the algorithm.
                
            double UT = normalize((double)time/HOUR_MS, 24);
        
            siderealTime = normalize(getSiderealOffset() + UT*1.002737909, 24);
        }
        return siderealTime;
    }
    
    private double getSiderealOffset() {
        if (siderealT0 == INVALID) {
            double JD  = Math.floor(getJulianDay() - 0.5) + 0.5;
            double S   = JD - 2451545.0;
            double T   = S / 36525.0;
            siderealT0 = normalize(6.697374558 + 2400.051336*T + 0.000025862*T*T, 24);
        }
        return siderealT0;
    }
    
    /**
     * Returns the current local sidereal time, measured in hours
     */
    public double getLocalSidereal() {
        return normalize(getGreenwichSidereal() + (double)fGmtOffset/HOUR_MS, 24);
    }
    
    /**
     * Converts local sidereal time to Universal Time.
     *
     * @param lst   The Local Sidereal Time, in hours since sidereal midnight
     *              on this object's current date.
     *
     * @return      The corresponding Universal Time, in milliseconds since
     *              1 Jan 1970, GMT.  
     */
    private long lstToUT(double lst) {
        // Convert to local mean time
        double lt = normalize((lst - getSiderealOffset()) * 0.9972695663, 24);
        
        // Then find local midnight on this day
        long base = DAY_MS * ((time + fGmtOffset)/DAY_MS) - fGmtOffset;
        
        //out("    lt  =" + lt + " hours");
        //out("    base=" + new Date(base));
        
        return base + (long)(lt * HOUR_MS);
    }
    
    
    //-------------------------------------------------------------------------
    // Coordinate transformations, all based on the current time of this object
    //-------------------------------------------------------------------------

    /**
     * Convert from ecliptic to equatorial coordinates.
     *
     * @param ecliptic  A point in the sky in ecliptic coordinates.
     * @return          The corresponding point in equatorial coordinates.
     */
    public final Equatorial eclipticToEquatorial(Ecliptic ecliptic)
    {
        return eclipticToEquatorial(ecliptic.longitude, ecliptic.latitude);
    }

    /**
     * Convert from ecliptic to equatorial coordinates.
     *
     * @param eclipLong     The ecliptic longitude
     * @param eclipLat      The ecliptic latitude
     *
     * @return              The corresponding point in equatorial coordinates.
     */
    public final Equatorial eclipticToEquatorial(double eclipLong, double eclipLat)
    {
        // See page 42 of "Practial Astronomy with your Calculator",
        // by Peter Duffet-Smith, for details on the algorithm.

        double obliq = eclipticObliquity();
        double sinE = Math.sin(obliq);
        double cosE = Math.cos(obliq);
        
        double sinL = Math.sin(eclipLong);
        double cosL = Math.cos(eclipLong);
        
        double sinB = Math.sin(eclipLat);
        double cosB = Math.cos(eclipLat);
        double tanB = Math.tan(eclipLat);
        
        return new Equatorial(Math.atan2(sinL*cosE - tanB*sinE, cosL),
                               Math.asin(sinB*cosE + cosB*sinE*sinL) );
    }

    /**
     * Convert from ecliptic longitude to equatorial coordinates.
     *
     * @param eclipLong     The ecliptic longitude
     *
     * @return              The corresponding point in equatorial coordinates.
     */
    public final Equatorial eclipticToEquatorial(double eclipLong)
    {
        return eclipticToEquatorial(eclipLong, 0);  // TODO: optimize
    }


    public Horizon eclipticToHorizon(double eclipLong)
    {
        Equatorial equatorial = eclipticToEquatorial(eclipLong);
        
        double H = getLocalSidereal()*PI/12 - equatorial.ascension;     // Hour-angle
        
        double sinH = Math.sin(H);
        double cosH = Math.cos(H);
        double sinD = Math.sin(equatorial.declination);
        double cosD = Math.cos(equatorial.declination);
        double sinL = Math.sin(fLatitude);
        double cosL = Math.cos(fLatitude);
        
        double altitude = Math.asin(sinD*sinL + cosD*cosL*cosH);
        double azimuth  = Math.atan2(-cosD*cosL*sinH, sinD - sinL * Math.sin(altitude));

        return new Horizon(azimuth, altitude);
    }

    
    //-------------------------------------------------------------------------
    // The Sun
    //-------------------------------------------------------------------------
    
    //
    // Parameters of the Sun's orbit as of 1/1/1990
    // Angles are in radians (after multiplying by PI/180)
    //
    double jdnEpoch  = 2447891.5;           // JDN of epoch (Jan 0.0 1990)

    double sunEtaG   = 279.403303 * PI/180; // Ecliptic longitude at epoch
    double sunOmegaG = 282.768422 * PI/180; // Ecliptic longitude of perigee
    double sunE      =   0.016713;          // Eccentricity of orbit
    double sunR0     =   1.495585e8;        // Semi-major axis in KM
    double sunTheta0 =   0.533128 * PI/180; // Angular diameter at R0

    /**
     * The longitude of the sun at the time specified by this object.
     * The longitude is measured in radians along the ecliptic
     * from the "first point of Aries," the point at which the ecliptic
     * crosses the earth's equatorial plane at the vernal equinox.
     * <p>
     * Currently, this method uses an approximation of the two-body Kepler's
     * equation for the earth and the sun.  It does not take into account the
     * perturbations caused by the other planets, the moon, etc.
     */
    public double getSunLongitude()
    {
        // See page 86 of "Practial Astronomy with your Calculator",
        // by Peter Duffet-Smith, for details on the algorithm.
        
        if (sunLongitude == INVALID) {
            double day = getJulianDay() - jdnEpoch;       // Days since epoch
            
            // Find the angular distance the sun in a fictitious
            // circular orbit has travelled since the epoch.
            double epochAngle = norm2PI(PI2/TROPICAL_YEAR*day);
            
            // The epoch wasn't at the sun's perigee; find the angular distance
            // since perigee, which is called the "mean anomaly"
            meanAnomalySun = norm2PI(epochAngle + sunEtaG - sunOmegaG);
            
            // Now find the "true anomaly", e.g. the real solar longitude
            // by solving Kepler's equation for an elliptical orbit
            sunLongitude = norm2PI(trueAnomaly(meanAnomalySun, sunE) + sunOmegaG);
        }
        return sunLongitude;
    }
  
    /**
     * The position of the sun at this object's current date and time,
     * in equatorial coordinates.
     */
    public Equatorial getSunPosition() {
        return eclipticToEquatorial(getSunLongitude(), 0);
    }
    
    private static class SolarLongitude {
        double value;
        SolarLongitude(double val) { value = val; }
    }
    
    /**
     * Constant representing the vernal equinox.
     * For use with {@link #getSunTime getSunTime}. 
     * Note: In this case, "vernal" refers to the northern hemisphere's seasons.
     */
    public static final SolarLongitude VERNAL_EQUINOX  = new SolarLongitude(0);
    
    /**
     * Constant representing the summer solstice.
     * For use with {@link #getSunTime getSunTime}.
     * Note: In this case, "summer" refers to the northern hemisphere's seasons.
     */
    public static final SolarLongitude SUMMER_SOLSTICE = new SolarLongitude(PI/2);
    
    /**
     * Constant representing the autumnal equinox.
     * For use with {@link #getSunTime getSunTime}.
     * Note: In this case, "autumn" refers to the northern hemisphere's seasons.
     */
    public static final SolarLongitude AUTUMN_EQUINOX  = new SolarLongitude(PI);
    
    /**
     * Constant representing the winter solstice.
     * For use with {@link #getSunTime getSunTime}.
     * Note: In this case, "winter" refers to the northern hemisphere's seasons.
     */
    public static final SolarLongitude WINTER_SOLSTICE = new SolarLongitude((PI*3)/2);
    
    /**
     * Find the next time at which the sun's ecliptic longitude will have
     * the desired value.  
     */
    public long getSunTime(double desired, boolean next)
    {
        return timeOfAngle( new AngleFunc() { public double eval() { return getSunLongitude(); } },
                            desired,
                            TROPICAL_YEAR,
                            MINUTE_MS,
                            next);
    }
    
    /**
     * Find the next time at which the sun's ecliptic longitude will have
     * the desired value.  
     */
    public long getSunTime(SolarLongitude desired, boolean next) {
        return getSunTime(desired.value, next);
    }
    
    /**
     * Returns the time (GMT) of sunrise or sunset on the local date to which
     * this calendar is currently set.
     */
    public long getSunRiseSet(boolean rise)
    {
        // Make a rough guess: 6am or 6pm local time on the current day
        long noon = ((time + fGmtOffset)/DAY_MS)*DAY_MS - fGmtOffset + 12*HOUR_MS;
        
        setTime(noon + (long)((rise ? -6 : 6) * HOUR_MS));
        
        return riseOrSet(new CoordFunc() {
                            public Equatorial eval() { return getSunPosition(); }
                         },
                         rise,
                         .533 * DEG_RAD,        // Angular Diameter
                         34 /60.0 * DEG_RAD,    // Refraction correction
                         MINUTE_MS);            // Desired accuracy
    }

    //-------------------------------------------------------------------------
    // The Moon
    //-------------------------------------------------------------------------
    
    static final double moonL0 = 318.351648 * PI/180;   // Mean long. at epoch
    static final double moonP0 =  36.340410 * PI/180;   // Mean long. of perigee
    static final double moonN0 = 318.510107 * PI/180;   // Mean long. of node
    static final double moonI  =   5.145366 * PI/180;   // Inclination of orbit
    static final double moonE  =   0.054900;            // Eccentricity of orbit
    
    // These aren't used right now
    static final double moonA  =   3.84401e5;           // semi-major axis (km)
    static final double moonT0 =   0.5181 * PI/180;     // Angular size at distance A
    static final double moonPi =   0.9507 * PI/180;     // Parallax at distance A
    
    /**
     * The position of the moon at the time set on this
     * object, in equatorial coordinates.
     */
    public Equatorial getMoonPosition()
    {
        //
        // See page 142 of "Practial Astronomy with your Calculator",
        // by Peter Duffet-Smith, for details on the algorithm.
        //
        if (moonPosition == null) {
            // Calculate the solar longitude.  Has the side effect of
            // filling in "meanAnomalySun" as well.
            double sunLongitude = getSunLongitude();
            
            //
            // Find the # of days since the epoch of our orbital parameters.
            // TODO: Convert the time of day portion into ephemeris time
            //
            double day = getJulianDay() - jdnEpoch;       // Days since epoch
            
            // Calculate the mean longitude and anomaly of the moon, based on
            // a circular orbit.  Similar to the corresponding solar calculation.
            double meanLongitude = norm2PI(13.1763966*PI/180*day + moonL0);
            double meanAnomalyMoon = norm2PI(meanLongitude - 0.1114041*PI/180 * day - moonP0);
            
            //
            // Calculate the following corrections:
            //  Evection:   the sun's gravity affects the moon's eccentricity
            //  Annual Eqn: variation in the effect due to earth-sun distance
            //  A3:         correction factor (for ???)
            //
            double evection = 1.2739*PI/180 * Math.sin(2 * (meanLongitude - sunLongitude)
                                                - meanAnomalyMoon);
            double annual   = 0.1858*PI/180 * Math.sin(meanAnomalySun);
            double a3       = 0.3700*PI/180 * Math.sin(meanAnomalySun);

            meanAnomalyMoon += evection - annual - a3;
            
            //
            // More correction factors:
            //  center  equation of the center correction
            //  a4      yet another error correction (???)
            //
            // TODO: Skip the equation of the center correction and solve Kepler's eqn?
            //
            double center = 6.2886*PI/180 * Math.sin(meanAnomalyMoon);
            double a4 =     0.2140*PI/180 * Math.sin(2 * meanAnomalyMoon);
            
            // Now find the moon's corrected longitude
            moonLongitude = meanLongitude + evection + center - annual + a4;

            //
            // And finally, find the variation, caused by the fact that the sun's
            // gravitational pull on the moon varies depending on which side of
            // the earth the moon is on
            //
            double variation = 0.6583*PI/180 * Math.sin(2*(moonLongitude - sunLongitude));
            
            moonLongitude += variation;
            
            //
            // What we've calculated so far is the moon's longitude in the plane
            // of its own orbit.  Now map to the ecliptic to get the latitude
            // and longitude.  First we need to find the longitude of the ascending
            // node, the position on the ecliptic where it is crossed by the moon's
            // orbit as it crosses from the southern to the northern hemisphere.
            //
            double nodeLongitude = norm2PI(moonN0 - 0.0529539*PI/180 * day);

            nodeLongitude -= 0.16*PI/180 * Math.sin(meanAnomalySun);

            double y = Math.sin(moonLongitude - nodeLongitude);
            double x = Math.cos(moonLongitude - nodeLongitude);
            
            moonEclipLong = Math.atan2(y*Math.cos(moonI), x) + nodeLongitude;
            double moonEclipLat = Math.asin(y * Math.sin(moonI));

            moonPosition = eclipticToEquatorial(moonEclipLong, moonEclipLat);
        }
        return moonPosition;
    }
    
    /**
     * The "age" of the moon at the time specified in this object.
     * This is really the angle between the
     * current ecliptic longitudes of the sun and the moon,
     * measured in radians.
     *
     * @see #getMoonPhase
     */
    public double getMoonAge() {
        // See page 147 of "Practial Astronomy with your Calculator",
        // by Peter Duffet-Smith, for details on the algorithm.
        //
        // Force the moon's position to be calculated.  We're going to use
        // some the intermediate results cached during that calculation.
        //
        getMoonPosition();
        
        return norm2PI(moonEclipLong - sunLongitude);
    }
    
    /**
     * Calculate the phase of the moon at the time set in this object.
     * The returned phase is a <code>double</code> in the range
     * <code>0 <= phase < 1</code>, interpreted as follows:
     * <ul>
     * <li>0.00: New moon
     * <li>0.25: First quarter
     * <li>0.50: Full moon
     * <li>0.75: Last quarter
     * </ul>
     *
     * @see #getMoonAge
     */
    public double getMoonPhase() {
        // See page 147 of "Practial Astronomy with your Calculator",
        // by Peter Duffet-Smith, for details on the algorithm.
        return 0.5 * (1 - Math.cos(getMoonAge()));
    }
    
    private static class MoonAge {
        double value;
        MoonAge(double val) { value = val; }
    }
    
    /**
     * Constant representing a new moon.
     * For use with {@link #getMoonTime getMoonTime}
     */
    public static final MoonAge NEW_MOON      = new MoonAge(0);

    /**
     * Constant representing the moon's first quarter.
     * For use with {@link #getMoonTime getMoonTime}
     */
    public static final MoonAge FIRST_QUARTER = new MoonAge(PI/2);
    
    /**
     * Constant representing a full moon.
     * For use with {@link #getMoonTime getMoonTime}
     */
    public static final MoonAge FULL_MOON     = new MoonAge(PI);
    
    /**
     * Constant representing the moon's last quarter.
     * For use with {@link #getMoonTime getMoonTime}
     */
    public static final MoonAge LAST_QUARTER  = new MoonAge((PI*3)/2);
    
    /**
     * Find the next or previous time at which the Moon's ecliptic
     * longitude will have the desired value.  
     * <p>
     * @param desired   The desired longitude.
     * @param next      <tt>true</tt> if the next occurrance of the phase
     *                  is desired, <tt>false</tt> for the previous occurrance. 
     */
    public long getMoonTime(double desired, boolean next)
    {
        return timeOfAngle( new AngleFunc() {
                            public double eval() { return getMoonAge(); } },
                            desired,
                            SYNODIC_MONTH,
                            MINUTE_MS,
                            next);
    }
    
    /**
     * Find the next or previous time at which the moon will be in the
     * desired phase.
     * <p>
     * @param desired   The desired phase of the moon.
     * @param next      <tt>true</tt> if the next occurrance of the phase
     *                  is desired, <tt>false</tt> for the previous occurrance. 
     */
    public long getMoonTime(MoonAge desired, boolean next) {
        return getMoonTime(desired.value, next);
    }
    
    /**
     * Returns the time (GMT) of sunrise or sunset on the local date to which
     * this calendar is currently set.
     */
    public long getMoonRiseSet(boolean rise)
    {
        return riseOrSet(new CoordFunc() {
                            public Equatorial eval() { return getMoonPosition(); }
                         },
                         rise,
                         .533 * DEG_RAD,        // Angular Diameter
                         34 /60.0 * DEG_RAD,    // Refraction correction
                         MINUTE_MS);            // Desired accuracy
    }

    //-------------------------------------------------------------------------
    // Interpolation methods for finding the time at which a given event occurs
    //-------------------------------------------------------------------------
    
    private interface AngleFunc {
        public double eval();
    };
    
    private long timeOfAngle(AngleFunc func, double desired,
                             double periodDays, long epsilon, boolean next)
    {
        // Find the value of the function at the current time
        double lastAngle = func.eval();
        
        // Find out how far we are from the desired angle
        double deltaAngle = norm2PI(desired - lastAngle) ;
        
        // Using the average period, estimate the next (or previous) time at
        // which the desired angle occurs.
        double deltaT =  (deltaAngle + (next ? 0 : -PI2)) * (periodDays*DAY_MS) / PI2;
        
        double lastDeltaT = deltaT; // Liu
        long startTime = time; // Liu
        
        setTime(time + (long)deltaT);

        // Now iterate until we get the error below epsilon.  Throughout
        // this loop we use normPI to get values in the range -Pi to Pi,
        // since we're using them as correction factors rather than absolute angles.
        do {
            // Evaluate the function at the time we've estimated
            double angle = func.eval();

            // Find the # of milliseconds per radian at this point on the curve
            double factor = Math.abs(deltaT / normPI(angle-lastAngle));

            // Correct the time estimate based on how far off the angle is
            deltaT = normPI(desired - angle) * factor;
            
            // HACK:
            // 
            // If abs(deltaT) begins to diverge we need to quit this loop.
            // This only appears to happen when attempting to locate, for
            // example, a new moon on the day of the new moon.  E.g.:
            // 
            // This result is correct:
            // newMoon(7508(Mon Jul 23 00:00:00 CST 1990,false))=
            //   Sun Jul 22 10:57:41 CST 1990
            // 
            // But attempting to make the same call a day earlier causes deltaT
            // to diverge:
            // CalendarAstronomer.timeOfAngle() diverging: 1.348508727575625E9 ->
            //   1.3649828540224032E9
            // newMoon(7507(Sun Jul 22 00:00:00 CST 1990,false))=
            //   Sun Jul 08 13:56:15 CST 1990
            //
            // As a temporary solution, we catch this specific condition and
            // adjust our start time by one eighth period days (either forward
            // or backward) and try again.
            // Liu 11/9/00
            if (Math.abs(deltaT) > Math.abs(lastDeltaT)) {
                long delta = (long) (periodDays * DAY_MS / 8);
                setTime(startTime + (next ? delta : -delta));
                return timeOfAngle(func, desired, periodDays, epsilon, next);
            }

            lastDeltaT = deltaT;
            lastAngle = angle;

            setTime(time + (long)deltaT);
        }
        while (Math.abs(deltaT) > epsilon);
        
        return time;
    }
    
    private interface CoordFunc {
        public Equatorial eval();
    };
    
    private long riseOrSet(CoordFunc func, boolean rise,
                           double diameter, double refraction, 
                           long epsilon)
    {        
        Equatorial  pos = null;
        double      tanL   = Math.tan(fLatitude);
        long        deltaT = Long.MAX_VALUE;
        int         count = 0;
        
        //
        // Calculate the object's position at the current time, then use that
        // position to calculate the time of rising or setting.  The position
        // will be different at that time, so iterate until the error is allowable.
        //
        do {
            // See "Practical Astronomy With Your Calculator, section 33.
            pos = func.eval();
            double angle = Math.acos(-tanL * Math.tan(pos.declination));
            double lst = ((rise ? PI2-angle : angle) + pos.ascension ) * 24 / PI2;
                         
            // Convert from LST to Universal Time.
            long newTime = lstToUT( lst );
            
            deltaT = newTime - time;
            setTime(newTime);
        }
        while (++ count < 5 && Math.abs(deltaT) > epsilon);
        
        // Calculate the correction due to refraction and the object's angular diameter
        double cosD  = Math.cos(pos.declination);
        double psi   = Math.acos(Math.sin(fLatitude) / cosD);
        double x     = diameter / 2 + refraction;
        double y     = Math.asin(Math.sin(x) / Math.sin(psi));
        long  delta  = (long)((240 * y * RAD_DEG / cosD)*SECOND_MS);
        
        return time + (rise ? -delta : delta);
    }
    
    //-------------------------------------------------------------------------
    // Other utility methods
    //-------------------------------------------------------------------------

    private static final double normalize(double value, double range) {
        return value - range * Math.floor(value / range);
    }
    
    /**
     * Normalize an angle so that it's in the range 0 - 2pi.
     * For positive angles this is just (angle % 2pi), but the Java
     * mod operator doesn't work that way for negative numbers....
     */
    private static final double norm2PI(double angle) {
        return normalize(angle, PI2);
    }
    
    /**
     * Normalize an angle into the range -PI - PI
     */
    private static final double normPI(double angle) {
        return normalize(angle + PI, PI2) - PI;
    }
    
    /**
     * Find the "true anomaly" (longitude) of an object from
     * its mean anomaly and the eccentricity of its orbit.  This uses
     * an iterative solution to Kepler's equation.
     *
     * @param meanAnomaly   The object's longitude calculated as if it were in
     *                      a regular, circular orbit, measured in radians
     *                      from the point of perigee.  
     *
     * @param eccentricity  The eccentricity of the orbit
     *
     * @return The true anomaly (longitude) measured in radians
     */
    private double trueAnomaly(double meanAnomaly, double eccentricity)
    {
        // First, solve Kepler's equation iteratively
        double delta;
        double E = meanAnomaly;
        do {
            delta = E - eccentricity * Math.sin(E) - meanAnomaly;
            E = E - delta / (1 - eccentricity * Math.cos(E));
        } 
        while (Math.abs(delta) > accuracy);

        return 2.0 * Math.atan( Math.tan(E/2) * Math.sqrt( (1+eccentricity)
                                                          /(1-eccentricity) ) );
    }
    
    static private final double accuracy = 0.01 * PI/180;  // 0.01 degrees
    
    /**
     * Return the obliquity of the ecliptic (the angle between the ecliptic
     * and the earth's equator) at the current time.  This varies due to
     * the precession of the earth's axis.
     *
     * @return  the obliquity of the ecliptic relative to the equator,
     *          measured in radians.
     */
    private double eclipticObliquity() {
        if (eclipObliquity == INVALID) {
            final double epoch = 2451545.0;     // 2000 AD, January 1.5

            double T = (getJulianDay() - epoch) / 36525;
            
            eclipObliquity = 23.439292
                           - 46.815/3600 * T
                           - 0.0006 * T*T
                           + 0.00181 * T*T*T;
                           
            eclipObliquity *= DEG_RAD;
        }
        return eclipObliquity;
    }
    
     
    //-------------------------------------------------------------------------
    // Private data
    //-------------------------------------------------------------------------
    
    /**
     * Current time in milliseconds since 1/1/1970 AD
     * @see java.util.Date#getTime
     */
    private long time;
    
    /* These aren't used yet, but they'll be needed for sunset calculations
     * and equatorial to horizon coordinate conversions
     */
    private double fLongitude = 0.0;
    private double fLatitude  = 0.0;
    private long   fGmtOffset = 0;
    
    //
    // The following fields are used to cache calculated results for improved
    // performance.  These values all depend on the current time setting
    // of this object, so the clearCache method is provided.
    //
    static final private double INVALID = Double.MIN_VALUE;
    
    private transient double    julianDay       = INVALID;
    private transient double    julianCentury   = INVALID;
    private transient double    sunLongitude    = INVALID;
    private transient double    meanAnomalySun  = INVALID;
    private transient double    moonLongitude   = INVALID;
    private transient double    moonEclipLong   = INVALID;
    private transient double    meanAnomalyMoon = INVALID;
    private transient double    eclipObliquity  = INVALID;
    private transient double    siderealT0      = INVALID;
    private transient double    siderealTime    = INVALID;
    
    private transient Equatorial  moonPosition = null;

    private void clearCache() {
        julianDay       = INVALID;
        julianCentury   = INVALID;
        sunLongitude    = INVALID;
        meanAnomalySun  = INVALID;
        moonLongitude   = INVALID;
        moonEclipLong   = INVALID;
        meanAnomalyMoon = INVALID;
        eclipObliquity  = INVALID;
        siderealTime    = INVALID;
        siderealT0      = INVALID;
        moonPosition    = null;
    }
    
    private static void out(String s) {
        System.out.println(s);
    }
    
    private static String deg(double rad) {
        return Double.toString(rad * RAD_DEG);
    }
    
    private static String hours(long ms) {
        return Double.toString((double)ms / HOUR_MS) + " hours";
    }
    public String local(long localMillis) {
        return new Date(localMillis - TimeZone.getDefault().getRawOffset()).toString();
    }
    
    
    /**
     * Represents the position of an object in the sky relative to the ecliptic,
     * the plane of the earth's orbit around the Sun. 
     * This is a spherical coordinate system in which the latitude
     * specifies the position north or south of the plane of the ecliptic.
     * The longitude specifies the position along the ecliptic plane
     * relative to the "First Point of Aries", which is the Sun's position in the sky
     * at the Vernal Equinox.
     * <p>
     * Note that Ecliptic objects are immutable and cannot be modified
     * once they are constructed.  This allows them to be passed and returned by
     * value without worrying about whether other code will modify them.
     *
     * @see CalendarAstronomer.Equatorial
     * @see CalendarAstronomer.Horizon
     */
    public static final class Ecliptic {
        /**
         * Constructs an Ecliptic coordinate object.
         * <p>
         * @param lat The ecliptic latitude, measured in radians.
         * @param lon The ecliptic longitude, measured in radians.
         */
        public Ecliptic(double lat, double lon) {
            latitude = lat;
            longitude = lon;
        }

        /**
         * Return a string representation of this object
         */
        public String toString() {
            return Double.toString(longitude*RAD_DEG) + "," + (latitude*RAD_DEG);
        }
        
        /**
         * The ecliptic latitude, in radians.  This specifies an object's
         * position north or south of the plane of the ecliptic,
         * with positive angles representing north.
         */
        public final double latitude;
        
        /**
         * The ecliptic longitude, in radians.
         * This specifies an object's position along the ecliptic plane
         * relative to the "First Point of Aries", which is the Sun's position
         * in the sky at the Vernal Equinox,
         * with positive angles representing east.
         * <p>
         * A bit of trivia: the first point of Aries is currently in the
         * constellation Pisces, due to the precession of the earth's axis.
         */
        public final double longitude;
    };

    /**
     * Represents the position of an 
     * object in the sky relative to the plane of the earth's equator. 
     * The <i>Right Ascension</i> specifies the position east or west
     * along the equator, relative to the sun's position at the vernal
     * equinox.  The <i>Declination</i> is the position north or south
     * of the equatorial plane.
     * <p>
     * Note that Equatorial objects are immutable and cannot be modified
     * once they are constructed.  This allows them to be passed and returned by
     * value without worrying about whether other code will modify them.
     *
     * @see CalendarAstronomer.Ecliptic
     * @see CalendarAstronomer.Horizon
     */
    public static final class Equatorial {
        /**
         * Constructs an Equatorial coordinate object.
         * <p>
         * @param asc The right ascension, measured in radians.
         * @param dec The declination, measured in radians.
         */
        public Equatorial(double asc, double dec) {
            ascension = asc;
            declination = dec;
        }

        /**
         * Return a string representation of this object, with the
         * angles measured in degrees.
         */
        public String toString() {
            return Double.toString(ascension*RAD_DEG) + "," + (declination*RAD_DEG);
        }
        
        /**
         * Return a string representation of this object with the right ascension
         * measured in hours, minutes, and seconds.
         */
        public String toHmsString() {
            return radToHms(ascension) + "," + radToDms(declination);
        }
        
        /**
         * The right ascension, in radians. 
         * This is the position east or west along the equator
         * relative to the sun's position at the vernal equinox,
         * with positive angles representing East.
         */
        public final double ascension;
        
        /**
         * The declination, in radians.
         * This is the position north or south of the equatorial plane,
         * with positive angles representing north.
         */
        public final double declination;
    };

    /**
     * Represents the position of an  object in the sky relative to 
     * the local horizon.
     * The <i>Altitude</i> represents the object's elevation above the horizon,
     * with objects below the horizon having a negative altitude.
     * The <i>Azimuth</i> is the geographic direction of the object from the
     * observer's position, with 0 representing north.  The azimuth increases
     * clockwise from north.
     * <p>
     * Note that Horizon objects are immutable and cannot be modified
     * once they are constructed.  This allows them to be passed and returned by
     * value without worrying about whether other code will modify them.
     *
     * @see CalendarAstronomer.Ecliptic
     * @see CalendarAstronomer.Equatorial
     */
    public static final class Horizon {
        /**
         * Constructs a Horizon coordinate object.
         * <p>
         * @param alt  The altitude, measured in radians above the horizon.
         * @param azim The azimuth, measured in radians clockwise from north.
         */
        public Horizon(double alt, double azim) {
            altitude = alt;
            azimuth = azim;
        }

        /**
         * Return a string representation of this object, with the
         * angles measured in degrees.
         */
        public String toString() {
            return Double.toString(altitude*RAD_DEG) + "," + (azimuth*RAD_DEG);
        }
        
        /** The object's altitude above the horizon, in radians. */
        public final double altitude;
        
        /** The object's direction, in radians clockwise from north. */
        public final double azimuth;
    };

    static private String radToHms(double angle) {
        int hrs = (int) (angle*RAD_HOUR);
        int min = (int)((angle*RAD_HOUR - hrs) * 60);
        int sec = (int)((angle*RAD_HOUR - hrs - min/60.0) * 3600);
        
        return Integer.toString(hrs) + "h" + min + "m" + sec + "s";
    }
    
    static private String radToDms(double angle) {
        int deg = (int) (angle*RAD_DEG);
        int min = (int)((angle*RAD_DEG - deg) * 60);
        int sec = (int)((angle*RAD_DEG - deg - min/60.0) * 3600);
        
        return Integer.toString(deg) + "\u00b0" + min + "'" + sec + "\"";
    }
}
