/*
 *******************************************************************************
 * Copyright (C) 1996-2000, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/Attic/CalendarAstronomer.java,v $ 
 * $Date: 2002/12/05 01:25:10 $ 
 * $Revision: 1.10 $
 *
 *****************************************************************************************
 */
package com.ibm.icu.util;

import java.util.*;

/**
 * <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
 * @stable ICU 2.0
 */
public class CalendarAstronomer {
    
    //-------------------------------------------------------------------------
    // Astronomical constants
    //-------------------------------------------------------------------------

    /**
     * The number of standard hours in one sidereal day.
     * Approximately 24.93.
     * @stable ICU 2.0
     */
    public static final double SIDEREAL_DAY = 23.93446960027;
    
    /**
     * The number of sidereal hours in one mean solar day.
     * Approximately 24.07.
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    public static final double SIDEREAL_YEAR = 365.25636;

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

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

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

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

    /** 
     * The number of milliseconds in one day. 
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    public CalendarAstronomer() {
        this(System.currentTimeMillis());
    }
    
    /**
     * Construct a new <code>CalendarAstronomer</code> object that is initialized to
     * the specified date and time.
     * @stable ICU 2.0
     */
    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()
     * @stable ICU 2.0
     */
    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()
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    public double getJulianCentury() {
        if (julianCentury == INVALID) {
            julianCentury = (getJulianDay() - 2415020.0) / 36525;
        }
        return julianCentury;
    }

    /**
     * Returns the current Greenwich sidereal time, measured in hours
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    public final Equatorial eclipticToEquatorial(double eclipLong)
    {
        return eclipticToEquatorial(eclipLong, 0);  // TODO: optimize
    }

    /**
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.  
     * @stable ICU 2.0
     */
    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.  
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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}
     * @stable ICU 2.0
     */
    public static final MoonAge NEW_MOON      = new MoonAge(0);

    /**
     * Constant representing the moon's first quarter.
     * For use with {@link #getMoonTime getMoonTime}
     * @stable ICU 2.0
     */
    public static final MoonAge FIRST_QUARTER = new MoonAge(PI/2);
    
    /**
     * Constant representing a full moon.
     * For use with {@link #getMoonTime getMoonTime}
     * @stable ICU 2.0
     */
    public static final MoonAge FULL_MOON     = new MoonAge(PI);
    
    /**
     * Constant representing the moon's last quarter.
     * For use with {@link #getMoonTime getMoonTime}
     * @stable ICU 2.0
     */
    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. 
     * @stable ICU 2.0
     */
    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. 
     * @stable ICU 2.0
     */
    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.
     * @stable ICU 2.0
     */
    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";
    }

    /**
     * @stable ICU 2.0
     */
    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
     * @stable ICU 2.0
     */
    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.
         * @stable ICU 2.0
         */
        public Ecliptic(double lat, double lon) {
            latitude = lat;
            longitude = lon;
        }

        /**
         * Return a string representation of this object
         * @stable ICU 2.0
         */
        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.
         * @stable ICU 2.0
         */
        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.
         * @stable ICU 2.0
         */
        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
     * @stable ICU 2.0
     */
    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.
         * @stable ICU 2.0
         */
        public Equatorial(double asc, double dec) {
            ascension = asc;
            declination = dec;
        }

        /**
         * Return a string representation of this object, with the
         * angles measured in degrees.
         * @stable ICU 2.0
         */
        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.
         * @stable ICU 2.0
         */
        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.
         * @stable ICU 2.0
         */
        public final double ascension;
        
        /**
         * The declination, in radians.
         * This is the position north or south of the equatorial plane,
         * with positive angles representing north.
         * @stable ICU 2.0
         */
        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
     * @stable ICU 2.0
     */
    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.
         * @stable ICU 2.0
         */
        public Horizon(double alt, double azim) {
            altitude = alt;
            azimuth = azim;
        }

        /**
         * Return a string representation of this object, with the
         * angles measured in degrees.
         * @stable ICU 2.0
         */
        public String toString() {
            return Double.toString(altitude*RAD_DEG) + "," + (azimuth*RAD_DEG);
        }
        
        /** 
         * The object's altitude above the horizon, in radians. 
         * @stable ICU 2.0
         */
        public final double altitude;
        
        /** 
         * The object's direction, in radians clockwise from north. 
         * @stable ICU 2.0
         */
        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 + "\"";
    }
}
