/*
 * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.util.calendar;

import java.util.Locale;
import java.util.TimeZone;

/**
 * The <code>AbstractCalendar</code> class provides a framework for
 * implementing a concrete calendar system.
 *
 * <p><a name="fixed_date"></a><B>Fixed Date</B><br>
 *
 * For implementing a concrete calendar system, each calendar must
 * have the common date numbering, starting from midnight the onset of
 * Monday, January 1, 1 (Gregorian). It is called a <I>fixed date</I>
 * in this class. January 1, 1 (Gregorian) is fixed date 1. (See
 * Nachum Dershowitz and Edward M. Reingold, <I>CALENDRICAL
 * CALCULATION The Millennium Edition</I>, Section 1.2 for details.)
 *
 * @author Masayoshi Okutsu
 * @since 1.5
 */

public abstract class AbstractCalendar extends CalendarSystem {

    // The constants assume no leap seconds support.
    static final int SECOND_IN_MILLIS = 1000;
    static final int MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
    static final int HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
    static final int DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;

    // The number of days between January 1, 1 and January 1, 1970 (Gregorian)
    static final int EPOCH_OFFSET = 719163;

    private Era[] eras;

    protected AbstractCalendar() {
    }

    public Era getEra(String eraName) {
        if (eras != null) {
            for (int i = 0; i < eras.length; i++) {
                if (eras[i].equals(eraName)) {
                    return eras[i];
                }
            }
        }
        return null;
    }

    public Era[] getEras() {
        Era[] e = null;
        if (eras != null) {
            e = new Era[eras.length];
            System.arraycopy(eras, 0, e, 0, eras.length);
        }
        return e;
    }

    public void setEra(CalendarDate date, String eraName) {
        if (eras == null) {
            return; // should report an error???
        }
        for (int i = 0; i < eras.length; i++) {
            Era e = eras[i];
            if (e != null && e.getName().equals(eraName)) {
                date.setEra(e);
                return;
            }
        }
        throw new IllegalArgumentException("unknown era name: " + eraName);
    }

    protected void setEras(Era[] eras) {
        this.eras = eras;
    }

    public CalendarDate getCalendarDate() {
        return getCalendarDate(System.currentTimeMillis(), newCalendarDate());
    }

    public CalendarDate getCalendarDate(long millis) {
        return getCalendarDate(millis, newCalendarDate());
    }

    public CalendarDate getCalendarDate(long millis, TimeZone zone) {
        CalendarDate date = newCalendarDate(zone);
        return getCalendarDate(millis, date);
    }

    public CalendarDate getCalendarDate(long millis, CalendarDate date) {
        int ms = 0;             // time of day
        int zoneOffset = 0;
        int saving = 0;
        long days = 0;          // fixed date

        // adjust to local time if `date' has time zone.
        TimeZone zi = date.getZone();
        if (zi != null) {
            int[] offsets = new int[2];
            if (zi instanceof ZoneInfo) {
                zoneOffset = ((ZoneInfo)zi).getOffsets(millis, offsets);
            } else {
                zoneOffset = zi.getOffset(millis);
                offsets[0] = zi.getRawOffset();
                offsets[1] = zoneOffset - offsets[0];
            }

            // We need to calculate the given millis and time zone
            // offset separately for java.util.GregorianCalendar
            // compatibility. (i.e., millis + zoneOffset could cause
            // overflow or underflow, which must be avoided.) Usually
            // days should be 0 and ms is in the range of -13:00 to
            // +14:00. However, we need to deal with extreme cases.
            days = zoneOffset / DAY_IN_MILLIS;
            ms = zoneOffset % DAY_IN_MILLIS;
            saving = offsets[1];
        }
        date.setZoneOffset(zoneOffset);
        date.setDaylightSaving(saving);

        days += millis / DAY_IN_MILLIS;
        ms += (int) (millis % DAY_IN_MILLIS);
        if (ms >= DAY_IN_MILLIS) {
            // at most ms is (DAY_IN_MILLIS - 1) * 2.
            ms -= DAY_IN_MILLIS;
            ++days;
        } else {
            // at most ms is (1 - DAY_IN_MILLIS) * 2. Adding one
            // DAY_IN_MILLIS results in still negative.
            while (ms < 0) {
                ms += DAY_IN_MILLIS;
                --days;
            }
        }

        // convert to fixed date (offset from Jan. 1, 1 (Gregorian))
        days += EPOCH_OFFSET;

        // calculate date fields from the fixed date
        getCalendarDateFromFixedDate(date, days);

        // calculate time fields from the time of day
        setTimeOfDay(date, ms);
        date.setLeapYear(isLeapYear(date));
        date.setNormalized(true);
        return date;
    }

    public long getTime(CalendarDate date) {
        long gd = getFixedDate(date);
        long ms = (gd - EPOCH_OFFSET) * DAY_IN_MILLIS + getTimeOfDay(date);
        int zoneOffset = 0;
        TimeZone zi = date.getZone();
        if (zi != null) {
            if (date.isNormalized()) {
                return ms - date.getZoneOffset();
            }
            // adjust time zone and daylight saving
            int[] offsets = new int[2];
            if (date.isStandardTime()) {
                // 1) 2:30am during starting-DST transition is
                //    intrepreted as 2:30am ST
                // 2) 5:00pm during DST is still interpreted as 5:00pm ST
                // 3) 1:30am during ending-DST transition is interpreted
                //    as 1:30am ST (after transition)
                if (zi instanceof ZoneInfo) {
                    ((ZoneInfo)zi).getOffsetsByStandard(ms, offsets);
                    zoneOffset = offsets[0];
                } else {
                    zoneOffset = zi.getOffset(ms - zi.getRawOffset());
                }
            } else {
                // 1) 2:30am during starting-DST transition is
                //    intrepreted as 3:30am DT
                // 2) 5:00pm during DST is intrepreted as 5:00pm DT
                // 3) 1:30am during ending-DST transition is interpreted
                //    as 1:30am DT/0:30am ST (before transition)
                if (zi instanceof ZoneInfo) {
                    zoneOffset = ((ZoneInfo)zi).getOffsetsByWall(ms, offsets);
                } else {
                    zoneOffset = zi.getOffset(ms - zi.getRawOffset());
                }
            }
        }
        ms -= zoneOffset;
        getCalendarDate(ms, date);
        return ms;
    }

    protected long getTimeOfDay(CalendarDate date) {
        long fraction = date.getTimeOfDay();
        if (fraction != CalendarDate.TIME_UNDEFINED) {
            return fraction;
        }
        fraction = getTimeOfDayValue(date);
        date.setTimeOfDay(fraction);
        return fraction;
    }

    public long getTimeOfDayValue(CalendarDate date) {
        long fraction = date.getHours();
        fraction *= 60;
        fraction += date.getMinutes();
        fraction *= 60;
        fraction += date.getSeconds();
        fraction *= 1000;
        fraction += date.getMillis();
        return fraction;
    }

    public CalendarDate setTimeOfDay(CalendarDate cdate, int fraction) {
        if (fraction < 0) {
            throw new IllegalArgumentException();
        }
        boolean normalizedState = cdate.isNormalized();
        int time = fraction;
        int hours = time / HOUR_IN_MILLIS;
        time %= HOUR_IN_MILLIS;
        int minutes = time / MINUTE_IN_MILLIS;
        time %= MINUTE_IN_MILLIS;
        int seconds = time / SECOND_IN_MILLIS;
        time %= SECOND_IN_MILLIS;
        cdate.setHours(hours);
        cdate.setMinutes(minutes);
        cdate.setSeconds(seconds);
        cdate.setMillis(time);
        cdate.setTimeOfDay(fraction);
        if (hours < 24 && normalizedState) {
            // If this time of day setting doesn't affect the date,
            // then restore the normalized state.
            cdate.setNormalized(normalizedState);
        }
        return cdate;
    }

    /**
     * Returns 7 in this default implementation.
     *
     * @return 7
     */
    public int getWeekLength() {
        return 7;
    }

    protected abstract boolean isLeapYear(CalendarDate date);

    public CalendarDate getNthDayOfWeek(int nth, int dayOfWeek, CalendarDate date) {
        CalendarDate ndate = (CalendarDate) date.clone();
        normalize(ndate);
        long fd = getFixedDate(ndate);
        long nfd;
        if (nth > 0) {
            nfd = 7 * nth + getDayOfWeekDateBefore(fd, dayOfWeek);
        } else {
            nfd = 7 * nth + getDayOfWeekDateAfter(fd, dayOfWeek);
        }
        getCalendarDateFromFixedDate(ndate, nfd);
        return ndate;
    }

    /**
     * Returns a date of the given day of week before the given fixed
     * date.
     *
     * @param fixedDate the fixed date
     * @param dayOfWeek the day of week
     * @return the calculated date
     */
    static long getDayOfWeekDateBefore(long fixedDate, int dayOfWeek) {
        return getDayOfWeekDateOnOrBefore(fixedDate - 1, dayOfWeek);
    }

    /**
     * Returns a date of the given day of week that is closest to and
     * after the given fixed date.
     *
     * @param fixedDate the fixed date
     * @param dayOfWeek the day of week
     * @return the calculated date
     */
    static long getDayOfWeekDateAfter(long fixedDate, int dayOfWeek) {
        return getDayOfWeekDateOnOrBefore(fixedDate + 7, dayOfWeek);
    }

    /**
     * Returns a date of the given day of week on or before the given fixed
     * date.
     *
     * @param fixedDate the fixed date
     * @param dayOfWeek the day of week
     * @return the calculated date
     */
    // public for java.util.GregorianCalendar
    public static long getDayOfWeekDateOnOrBefore(long fixedDate, int dayOfWeek) {
        long fd = fixedDate - (dayOfWeek - 1);
        if (fd >= 0) {
            return fixedDate - (fd % 7);
        }
        return fixedDate - CalendarUtils.mod(fd, 7);
    }

    /**
     * Returns the fixed date calculated with the specified calendar
     * date. If the specified date is not normalized, its date fields
     * are normalized.
     *
     * @param date a <code>CalendarDate</code> with which the fixed
     * date is calculated
     * @return the calculated fixed date
     * @see AbstractCalendar.html#fixed_date
     */
    protected abstract long getFixedDate(CalendarDate date);

    /**
     * Calculates calendar fields from the specified fixed date. This
     * method stores the calculated calendar field values in the specified
     * <code>CalendarDate</code>.
     *
     * @param date a <code>CalendarDate</code> to stored the
     * calculated calendar fields.
     * @param fixedDate a fixed date to calculate calendar fields
     * @see AbstractCalendar.html#fixed_date
     */
    protected abstract void getCalendarDateFromFixedDate(CalendarDate date,
                                                         long fixedDate);

    public boolean validateTime(CalendarDate date) {
        int t = date.getHours();
        if (t < 0 || t >= 24) {
            return false;
        }
        t = date.getMinutes();
        if (t < 0 || t >= 60) {
            return false;
        }
        t = date.getSeconds();
        // TODO: Leap second support.
        if (t < 0 || t >= 60) {
            return false;
        }
        t = date.getMillis();
        if (t < 0 || t >= 1000) {
            return false;
        }
        return true;
    }


    int normalizeTime(CalendarDate date) {
        long fraction = getTimeOfDay(date);
        long days = 0;

        if (fraction >= DAY_IN_MILLIS) {
            days = fraction / DAY_IN_MILLIS;
            fraction %= DAY_IN_MILLIS;
        } else if (fraction < 0) {
            days = CalendarUtils.floorDivide(fraction, DAY_IN_MILLIS);
            if (days != 0) {
                fraction -= DAY_IN_MILLIS * days; // mod(fraction, DAY_IN_MILLIS)
            }
        }
        if (days != 0) {
            date.setTimeOfDay(fraction);
        }
        date.setMillis((int)(fraction % 1000));
        fraction /= 1000;
        date.setSeconds((int)(fraction % 60));
        fraction /= 60;
        date.setMinutes((int)(fraction % 60));
        date.setHours((int)(fraction / 60));
        return (int)days;
    }
}
