/*
 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.util.calendar;

import java.lang.Cloneable;
import java.util.Locale;
import java.util.TimeZone;

/**
 * The <code>CalendarDate</code> class represents a specific instant
 * in time by calendar date and time fields that are multiple cycles
 * in different time unites. The semantics of each calendar field is
 * given by a concrete calendar system rather than this
 * <code>CalendarDate</code> class that holds calendar field values
 * without interpreting them. Therefore, this class can be used to
 * represent an amount of time, such as 2 years and 3 months.
 *
 * <p>A <code>CalendarDate</code> instance can be created by calling
 * the <code>newCalendarDate</code> or <code>getCalendarDate</code>
 * methods in <code>CalendarSystem</code>. A
 * <code>CalendarSystem</code> instance is obtained by calling one of
 * the factory methods in <code>CalendarSystem</code>. Manipulations
 * of calendar dates must be handled by the calendar system by which
 * <code>CalendarDate</code> instances have been created.
 *
 * <p>Some calendar fields can be modified through method calls. Any
 * modification of a calendar field brings the state of a
 * <code>CalendarDate</code> to <I>not normalized</I>. The
 * normalization must be performed to make all the calendar fields
 * consistent with a calendar system.
 *
 * <p>The <code>protected</code> methods are intended to be used for
 * implementing a concrete calendar system, not for general use as an
 * API.
 *
 * @see CalendarSystem
 * @author Masayoshi Okutsu
 * @since 1.5
 */
public abstract class CalendarDate implements Cloneable {
    public static final int FIELD_UNDEFINED = Integer.MIN_VALUE;
    public static final long TIME_UNDEFINED = Long.MIN_VALUE;

    private Era era;
    private int year;
    private int month;
    private int dayOfMonth;
    private int dayOfWeek = FIELD_UNDEFINED;
    private boolean leapYear;

    private int hours;
    private int minutes;
    private int seconds;
    private int millis;         // fractional part of the second
    private long fraction;      // time of day value in millisecond

    private boolean normalized;

    private TimeZone zoneinfo;
    private int zoneOffset;
    private int daylightSaving;
    private boolean forceStandardTime;

    private Locale locale;

    protected CalendarDate() {
        this(TimeZone.getDefault());
    }

    protected CalendarDate(TimeZone zone) {
        zoneinfo = zone;
    }

    public Era getEra() {
        return era;
    }

    /**
     * Sets the era of the date to the specified era. The default
     * implementation of this method accepts any Era value, including
     * <code>null</code>.
     *
     * @exception NullPointerException if the calendar system for this
     * <code>CalendarDate</code> requires eras and the specified era
     * is null.
     * @exception IllegalArgumentException if the specified
     * <code>era</code> is unknown to the calendar
     * system for this <code>CalendarDate</code>.
     */
    public CalendarDate setEra(Era era) {
        if (this.era == era) {
            return this;
        }
        this.era = era;
        normalized = false;
        return this;
    }

    public int getYear() {
        return year;
    }

    public CalendarDate setYear(int year) {
        if (this.year != year) {
            this.year = year;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addYear(int n) {
        if (n != 0) {
            year += n;
            normalized = false;
        }
        return this;
    }

    /**
     * Returns whether the year represented by this
     * <code>CalendarDate</code> is a leap year. If leap years are
     * not applicable to the calendar system, this method always
     * returns <code>false</code>.
     *
     * <p>If this <code>CalendarDate</code> hasn't been normalized,
     * <code>false</code> is returned. The normalization must be
     * performed to retrieve the correct leap year information.
     *
     * @return <code>true</code> if this <code>CalendarDate</code> is
     * normalized and the year of this <code>CalendarDate</code> is a
     * leap year, or <code>false</code> otherwise.
     * @see BaseCalendar#isGregorianLeapYear
     */
    public boolean isLeapYear() {
        return leapYear;
    }

    void setLeapYear(boolean leapYear) {
        this.leapYear = leapYear;
    }

    public int getMonth() {
        return month;
    }

    public CalendarDate setMonth(int month) {
        if (this.month != month) {
            this.month = month;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addMonth(int n) {
        if (n != 0) {
            month += n;
            normalized = false;
        }
        return this;
    }

    public int getDayOfMonth() {
        return dayOfMonth;
    }

    public CalendarDate setDayOfMonth(int date) {
        if (dayOfMonth != date) {
            dayOfMonth = date;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addDayOfMonth(int n) {
        if (n != 0) {
            dayOfMonth += n;
            normalized = false;
        }
        return this;
    }

    /**
     * Returns the day of week value. If this CalendarDate is not
     * normalized, {@link #FIELD_UNDEFINED} is returned.
     *
     * @return day of week or {@link #FIELD_UNDEFINED}
     */
    public int getDayOfWeek() {
        if (!isNormalized()) {
            dayOfWeek = FIELD_UNDEFINED;
        }
        return dayOfWeek;
    }

    public int getHours() {
        return hours;
    }

    public CalendarDate setHours(int hours) {
        if (this.hours != hours) {
            this.hours = hours;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addHours(int n) {
        if (n != 0) {
            hours += n;
            normalized = false;
        }
        return this;
    }

    public int getMinutes() {
        return minutes;
    }

    public CalendarDate setMinutes(int minutes) {
        if (this.minutes != minutes) {
            this.minutes = minutes;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addMinutes(int n) {
        if (n != 0) {
            minutes += n;
            normalized = false;
        }
        return this;
    }

    public int getSeconds() {
        return seconds;
    }

    public CalendarDate setSeconds(int seconds) {
        if (this.seconds != seconds) {
            this.seconds = seconds;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addSeconds(int n) {
        if (n != 0) {
            seconds += n;
            normalized = false;
        }
        return this;
    }

    public int getMillis() {
        return millis;
    }

    public CalendarDate setMillis(int millis) {
        if (this.millis != millis) {
            this.millis = millis;
            normalized = false;
        }
        return this;
    }

    public CalendarDate addMillis(int n) {
        if (n != 0) {
            millis += n;
            normalized = false;
        }
        return this;
    }

    public long getTimeOfDay() {
        if (!isNormalized()) {
            return fraction = TIME_UNDEFINED;
        }
        return fraction;
    }

    public CalendarDate setDate(int year, int month, int dayOfMonth) {
        setYear(year);
        setMonth(month);
        setDayOfMonth(dayOfMonth);
        return this;
    }

    public CalendarDate addDate(int year, int month, int dayOfMonth) {
        addYear(year);
        addMonth(month);
        addDayOfMonth(dayOfMonth);
        return this;
    }

    public CalendarDate setTimeOfDay(int hours, int minutes, int seconds, int millis) {
        setHours(hours);
        setMinutes(minutes);
        setSeconds(seconds);
        setMillis(millis);
        return this;
    }

    public CalendarDate addTimeOfDay(int hours, int minutes, int seconds, int millis) {
        addHours(hours);
        addMinutes(minutes);
        addSeconds(seconds);
        addMillis(millis);
        return this;
    }

    protected void setTimeOfDay(long fraction) {
        this.fraction = fraction;
    }

    public boolean isNormalized() {
        return normalized;
    }


    public boolean isStandardTime() {
        return forceStandardTime;
    }

    public void setStandardTime(boolean standardTime) {
        forceStandardTime = standardTime;
    }

    public boolean isDaylightTime() {
        if (isStandardTime()) {
            return false;
        }
        return daylightSaving != 0;
    }

    protected void setLocale(Locale loc) {
        locale = loc;
    }

    public TimeZone getZone() {
        return zoneinfo;
    }

    public CalendarDate setZone(TimeZone zoneinfo) {
        this.zoneinfo = zoneinfo;
        return this;
    }

    /**
     * Returns whether the specified date is the same date of this
     * <code>CalendarDate</code>. The time of the day fields are
     * ignored for the comparison.
     */
    public boolean isSameDate(CalendarDate date) {
        return getDayOfWeek() == date.getDayOfWeek()
            && getMonth() == date.getMonth()
            && getYear() == date.getYear()
            && getEra() == date.getEra();
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof CalendarDate)) {
            return false;
        }
        CalendarDate that = (CalendarDate) obj;
        if (isNormalized() != that.isNormalized()) {
            return false;
        }
        boolean hasZone = zoneinfo != null;
        boolean thatHasZone = that.zoneinfo != null;
        if (hasZone != thatHasZone) {
            return false;
        }
        if (hasZone && !zoneinfo.equals(that.zoneinfo)) {
            return false;
        }
        return (getEra() == that.getEra()
                && year == that.year
                && month == that.month
                && dayOfMonth == that.dayOfMonth
                && hours == that.hours
                && minutes == that.minutes
                && seconds == that.seconds
                && millis == that.millis
                && zoneOffset == that.zoneOffset);
    }

    public int hashCode() {
        // a pseudo (local standard) time stamp value in milliseconds
        // from the Epoch, assuming Gregorian calendar fields.
        long hash = ((((((long)year - 1970) * 12) + (month - 1)) * 30) + dayOfMonth) * 24;
        hash = ((((((hash + hours) * 60) + minutes) * 60) + seconds) * 1000) + millis;
        hash -= zoneOffset;
        int normalized = isNormalized() ? 1 : 0;
        int era = 0;
        Era e = getEra();
        if (e != null) {
            era = e.hashCode();
        }
        int zone = zoneinfo != null ? zoneinfo.hashCode() : 0;
        return (int) hash * (int)(hash >> 32) ^ era ^ normalized ^ zone;
    }

    /**
     * Returns a copy of this <code>CalendarDate</code>. The
     * <code>TimeZone</code> object, if any, is not cloned.
     *
     * @return a copy of this <code>CalendarDate</code>
     */
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen
            throw new InternalError();
        }
    }

    /**
     * Converts calendar date values to a <code>String</code> in the
     * following format.
     * <pre>
     *     yyyy-MM-dd'T'HH:mm:ss.SSSz
     * </pre>
     *
     * @see java.text.SimpleDateFormat
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        CalendarUtils.sprintf0d(sb, year, 4).append('-');
        CalendarUtils.sprintf0d(sb, month, 2).append('-');
        CalendarUtils.sprintf0d(sb, dayOfMonth, 2).append('T');
        CalendarUtils.sprintf0d(sb, hours, 2).append(':');
        CalendarUtils.sprintf0d(sb, minutes, 2).append(':');
        CalendarUtils.sprintf0d(sb, seconds, 2).append('.');
        CalendarUtils.sprintf0d(sb, millis, 3);
        if (zoneOffset == 0) {
            sb.append('Z');
        } else if (zoneOffset != FIELD_UNDEFINED) {
            int offset;
            char sign;
            if (zoneOffset > 0) {
                offset = zoneOffset;
                sign = '+';
            } else {
                offset = -zoneOffset;
                sign = '-';
            }
            offset /= 60000;
            sb.append(sign);
            CalendarUtils.sprintf0d(sb, offset / 60, 2);
            CalendarUtils.sprintf0d(sb, offset % 60, 2);
        } else {
            sb.append(" local time");
        }
        return sb.toString();
    }

    protected void setDayOfWeek(int dayOfWeek) {
        this.dayOfWeek = dayOfWeek;
    }

    protected void setNormalized(boolean normalized) {
        this.normalized = normalized;
    }

    public int getZoneOffset() {
        return zoneOffset;
    }

    protected void setZoneOffset(int offset) {
        zoneOffset = offset;
    }

    public int getDaylightSaving() {
        return daylightSaving;
    }

    protected void setDaylightSaving(int daylightSaving) {
        this.daylightSaving = daylightSaving;
    }
}
