/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation.  All rights 
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer. 
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:  
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowledgment may appear in the software itself,
*    if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must 
*    not be used to endorse or promote products derived from this
*    software without prior written permission. For written 
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache 
*    XMLBeans", nor may "Apache" appear in their name, without prior 
*    written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems 
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/

package org.apache.xmlbeans;

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

/**
 * 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
{
    /**
     * 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: 0000 is 1 BC and -0001 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);
    }
    
    private XmlCalendar(TimeZone tz, GDateSpecification date)
    {
        super(tz);
        setGregorianChange(_beginningOfTime); // proleptic
        clear();
        
        if (date.hasYear())
        {
            int y = date.getYear();
            if (y > 0)
            {
                set(Calendar.ERA, GregorianCalendar.AD);
            }
            else
            {
                set(Calendar.ERA, GregorianCalendar.BC);
                y = 1 - y;
            }
            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.
     */ 
    public XmlCalendar()
    {
        setGregorianChange(_beginningOfTime); // proleptic
        clear();
    }
    
    private static int defaultYear = Integer.MIN_VALUE;
    private static final int DEFAULT_DEFAULT_YEAR = 0; 
    
    /**
     * Returns the default year that is used when no year is specified.
     */ 
    public static int getDefaultYear()
    {
        if (defaultYear == Integer.MIN_VALUE)
        {
            try
            {
                String yearstring = System.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);
        }
    }
        
    private static Date _beginningOfTime = new Date(Long.MIN_VALUE);
    
    /**
     * 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
    }

}
