/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans;

import org.apache.xmlbeans.impl.util.SuppressForbidden;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * An XML Schema compatible subclass of {@link java.util.GregorianCalendar GregorianCalendar}.
 * XmlCalendar modifies several key details in the behavior of
 * GregorianCalendar to make it more useful when dealing with XML dates.
 * <p>
 * It is easy to convert between XmlCalendar and {@link GDate}, or to
 * parse or emit an XmlCalendar using a standard XML Schema
 * lexical representation.
 * <ol>
 * <li>
 * To match XML Schema dates, this XmlCalendar is a fully proleptic
 * Gregorian calendar by default, which means that Gregorian calendar
 * rules are applied backwards in time as if they had always been in
 * effect, actual historical circumstances concerning the observance
 * of the 1582 decree of Pope Gregory XIII notwithstanding.
 * </li>
 * <li>
 * In order to better support partially-specified dates for XML Schema,
 * this implementation provides a stable get(field) method
 * that does not modify the instance if you are acessing a field right
 * after it was explicitly set: a set followed by a get will always
 * return the same thing and will not fill in any other fields. However,
 * if you get a field that was not explicitly set, then all the fields
 * are still automatically filled and normalized for you, just like a
 * regular GregorianCalendar. If you wish to force the completion and
 * defaulting of all the fields (without hunting to get one that happens
 * to be unset), you can always do so by calling getTime().
 * </li>
 * <li>
 * When a year is unspecified and needs to be filled in automatically
 * (for example when using a .get or .getTime method as discussed above),
 * the year is defaulted to year 0 (also known as 1 BC).  This is different
 * from {@link GregorianCalendar}, which chooses 1970. The reason 0 is preferable
 * is that it is a leap year and so it permits the date --2-29 to be specified
 * stably. A different default year can be chosen via the static method
 * {@link #setDefaultYear(int) XmlCalendar.setDefaultYear()}, or by setting the
 * system property "user.defaultyear". If you do change this value, you should
 * pick another leap year such as 2000 and avoid non-leap years such as 1900.
 * </li>
 * <li>
 * When constructing an XmlCalendar from an XML Schema
 * formatted date or time string or GDate object, the timezone
 * for the calendar is taken from the string if it is present, or
 * taken to be {@link java.util.TimeZone#getDefault() TimeZone.getDefault()} if not.
 * <p>
 *     For example, the XML timezone "Z" is translated to "GMT";
 *     the XML timezone "+05:00" is translated to "GMT+05:00".
 * </p>
 * </li>
 * <li>
 * Finally, this implementation provides a String constructor and a
 * toString() method that comply with the XML Schema conventions
 * for formatting a date. If only a subset of fields have been
 * explicitly set, toString() produces a string with the proper subset
 * of information.
 * </li>
 * </ol>
 */
public class XmlCalendar extends GregorianCalendar
{
    private static int defaultYear = Integer.MIN_VALUE;
    private static final int DEFAULT_DEFAULT_YEAR = 0;
    private static final Date _beginningOfTime = new Date(Long.MIN_VALUE);




    /**
     * Constructs an XmlCalendar for a standard XML
     * schema formatted date string.
     *
     * The parser accepts any of the following formats:
     *
     * YYYY-MM-DDThh:mm:ss          - dateTime
     * YYYY-MM-DD                   - date
     *            hh:mm:ss          - time
     * YYYY                         - gYear
     *    --MM                      - gMonth
     *      ---DD                   - gDay
     *
     * The parser actually accepts all 16 combinations of subsets of
     * fields (Y, M, D, T) using the same scheme, even for combinations
     * that are not defined as types in the schema spec, such as
     * year, day, and time:
     *
     * YYYY--DDThh:mm:ss            - [everything but month specified]
     *
     * In the string, each field must be padded to its full width, for
     * example, January must be --01, not just --1.
     *
     * In particular, a year must be padded to at least four digits, so
     * "98" is not a valid year, although "1998" and "0098" are both valid
     * years, unambiguously 19 centuries separated from each other.  A year
     * may also be preceded by a minus symbol: -0001 is 1 BC and -0002 is
     * 2 BC.
     *
     * Finally a timezone is always allowed (yet optional) at the end.
     * Timezones must be either "Z" (UTC, which we translate to GMT),
     * or simple offsets from UTC in the range "-14:00" to "+14:00",
     * for example: "14:30:00-05:00" specifies 2:30 PM in the
     * afternoon at UTC-05:00, which is the same as EST.
     *
     * If a timezone is not specified, the default TimeZone is used.
     */
    public XmlCalendar(String xmlSchemaDateString)
    {
        this(new GDate(xmlSchemaDateString)); // use GDate to parse
    }

    /**
     * Constructs an XmlCalendar from a GDate.
     *
     * If the instance is not completed, you can round-trip to an
     * equivalent GDate by writing "new GDate(new XmlCalendar(gdate))".
     * However, if you access any of the unset fields of the calendar, all
     * the fields will be automatically filled in, so partial dates
     * without timezones or other fields will not round-trip after access.
     */
    public XmlCalendar(GDateSpecification date)
    {
        this(GDate.timeZoneForGDate(date), date);
    }

    @SuppressForbidden("Locale is not known and we don't have a general class to set the default locale")
    private XmlCalendar(TimeZone tz, GDateSpecification date)
    {
        super(tz);
        setGregorianChange(_beginningOfTime); // proleptic
        clear();

        if (date.hasYear())
        {
            int y = date.getYear(); // is never 0
            if (y > 0)
            {
                set(Calendar.ERA, GregorianCalendar.AD);
            }
            else // y < 0
            {
                set(Calendar.ERA, GregorianCalendar.BC);
                //y = 1 - y;
                y = -y; // no need to add 1
            }
            set(Calendar.YEAR, y);
        }
        if (date.hasMonth())
            set(Calendar.MONTH, date.getMonth() - 1); // note!!
        if (date.hasDay())
            set(Calendar.DAY_OF_MONTH, date.getDay());
        if (date.hasTime())
        {
            set(Calendar.HOUR_OF_DAY, date.getHour());
            set(Calendar.MINUTE, date.getMinute());
            set(Calendar.SECOND, date.getSecond());
            if (date.getFraction().scale() > 0)
                set(Calendar.MILLISECOND, date.getMillisecond());
        }
        if (date.hasTimeZone())
        {
            set(Calendar.ZONE_OFFSET, date.getTimeZoneSign() * 1000 * 60 * (date.getTimeZoneHour() * 60 + date.getTimeZoneMinute()));
            set(Calendar.DST_OFFSET, 0); // note!!  if we don't do this, then GregorianCalendar will pick up DST from the time zone
        }
    }

    /**
     * Constructs an XmlCalendar from a Date.
     *
     * The default TimeZone is used for computing the various fields.
     */
    public XmlCalendar(Date date)
    {
        this(TimeZone.getDefault(), new GDate(date));
        complete();
    }

    /**
     * Constructs an XmlCalendar with the specified year, month, day,
     * hours, minutes, seconds, and optional fractional seconds, in
     * the default timezone.
     */
    public XmlCalendar(
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            BigDecimal fraction)
    {
        this(TimeZone.getDefault(), new GDate(year, month, day, hour, minute, second, fraction));
    }

    /**
     * Constructs an XmlCalendar with the specified year, month, day,
     * hours, minutes, seconds, and optional fractional seconds, in
     * the specified timezone.
     */
    public XmlCalendar(
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            BigDecimal fraction,
            int tzSign,
            int tzHour,
            int tzMinute)
    {
        this(new GDate(year, month, day, hour, minute, second, fraction, tzSign, tzHour, tzMinute));
    }


    /**
     * Gets the value for a given time field.
     *
     * Unlike the GregorianCalendar implementation, the get() does not
     * force a complete of all fields.  If you wish to force a completion
     * of all the fields, call getTime() first.
     */
    public int get(int field)
    {
        if (!isSet(field) || isTimeSet)
            return super.get(field); // forces a complete
        else
            return internalGet(field); // does not force a complete.
    }

    /**
     * Constructs an empty instance with no fields set.
     */
    @SuppressForbidden("Locale is not known and we don't have a general class to set the default locale")
    public XmlCalendar()
    {
        setGregorianChange(_beginningOfTime); // proleptic
        clear();
    }

    /**
     * Returns the default year that is used when no year is specified.
     */
    public static int getDefaultYear()
    {
        if (defaultYear == Integer.MIN_VALUE)
        {
            try
            {
                String yearstring = SystemProperties.getProperty("user.defaultyear");
                if (yearstring != null)
                    defaultYear = Integer.parseInt(yearstring);
                else
                    defaultYear = DEFAULT_DEFAULT_YEAR;
            }
            catch (Throwable t)
            {
                defaultYear = DEFAULT_DEFAULT_YEAR;
            }
        }
        return defaultYear;
    }

    /**
     * Sets the default year to be used when no year is specified.
     */
    public static void setDefaultYear(int year)
    {
        defaultYear = year;
    }

    /**
     * Overrides GregorianCalendar.computeTime to apply a different
     * default year.  (It must be a leap year.)
     */
    protected void computeTime()
    {
        boolean unsetYear = !isSet(YEAR);
        if (unsetYear)
            set(YEAR, getDefaultYear());
        try
        {
            super.computeTime();
        }
        finally
        {
            if (unsetYear)
                clear(YEAR);
        }
    }

    /**
     * Prints the XmlCalendar using a standard XML Schema
     * format, as described in XmlCalendar(String s).
     */
    public String toString()
    {
        return (new GDate(this)).toString(); // use GDate to print
    }
}
