/*
* 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.math.BigDecimal;

/**
 * Represents an XML Schema-compatible duration.
 * <p>
 * A duration is made up of a number of years, months, days, hours,
 * minutes, seconds, and fractions of seconds. See the
 * XML Schema specification
 * <a target="_blank" href="http://www.w3.org/TR/xmlschema-2/#duration">section on xs:duration</a>
 * for details on the rules for
 * <a target="_blank" href="http://www.w3.org/TR/xmlschema-2/#duration-order">comparing durations</a> and
 * <a target="_blank" href="http://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes">adding durations to dates</a>.
 */
public final class GDuration implements GDurationSpecification, java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    
    private int _sign;
    private int _CY;
    private int _M;
    private int _D;
    private int _h;
    private int _m;
    private int _s;
    private BigDecimal _fs;

    /**
     * Constructs an empty GDuration representing zero seconds.
     */
    public GDuration()
    {
        _sign = +1;
    }

    private static final int SEEN_NOTHING = 0;
    private static final int SEEN_YEAR = 1;
    private static final int SEEN_MONTH = 2;
    private static final int SEEN_DAY = 3;
    private static final int SEEN_HOUR = 4;
    private static final int SEEN_MINUTE = 5;
    private static final int SEEN_SECOND = 6;

    /**
     * Constructs a GDuration from a lexical
     * representation. The lexical space contains the
     * union of the lexical spaces of all the schema
     * date/time types (except for duration).
     */
    public GDuration(CharSequence str)
    {
        // Form:        -PnYnMnDTnHnMnS
        // (where each n may be preceded by a - for us, and the whole may be -)

        // first trim XML whitespace
        int len = str.length();
        int start = 0;
        while (len > 0 && GDate.isSpace(str.charAt(len - 1)))
            len -= 1;
        while (start < len && GDate.isSpace(str.charAt(start)))
            start += 1;

        _sign = 1;
        boolean tmark = false;

        if (start < len && str.charAt(start) == '-')
        {
            _sign = -1;
            start += 1;
        }

        if (start >= len || str.charAt(start) != 'P')
            throw new IllegalArgumentException("duration must begin with P");

        start += 1;

        int seen = SEEN_NOTHING;
        _fs = GDate._zero;

        for (;start < len; start += 1)
        {
            boolean negval = false;
            char ch = str.charAt(start);
            if (ch == 'T')
            {
                if (tmark)
                    throw new IllegalArgumentException("duration must have no more than one T'");
                if (seen > SEEN_DAY)
                    throw new IllegalArgumentException("T in duration must precede time fields");
                seen = SEEN_DAY;
                tmark = true;
                start += 1;
                if (start >= len)
                    throw new IllegalArgumentException("illegal duration");
                ch = str.charAt(start);
            }
            if (ch == '-')
            {
                negval = true;
                if (start == len)
                    throw new IllegalArgumentException("illegal duration");
                start += 1;
                ch = str.charAt(start);
            }
            if (!GDate.isDigit(ch))
                throw new IllegalArgumentException("illegal duration");
            int value = GDate.digitVal(ch);
            for (;;)
            {
                start += 1;
                ch = (start < len) ? str.charAt(start) : '\0';
                if (!GDate.isDigit(ch))
                    break;
                value = value * 10 + GDate.digitVal(ch);
            }
            if (ch == '.')
            {
                int i = start;
                do i += 1;
                while (i < len && GDate.isDigit(ch = str.charAt(i)));
                _fs = new BigDecimal(str.subSequence(start, i).toString());
                if (i >= len || ch != 'S')
                    throw new IllegalArgumentException("illegal duration");
                start = i;
            }
            if (negval)
                value = -value;
            switch (seen)
            {
                case SEEN_NOTHING:
                    if (ch == 'Y')
                    {
                        seen = SEEN_YEAR;
                        _CY = value;
                        break;
                    } // fallthrough
                case SEEN_YEAR:
                    if (ch == 'M')
                    {
                        seen = SEEN_MONTH;
                        _M = value;
                        break;
                    } // fallthrough
                case SEEN_MONTH:
                    if (ch == 'D')
                    {
                        seen = SEEN_DAY;
                        _D = value;
                        break;
                    } // fallthrough
                case SEEN_DAY:
                    if (ch == 'H')
                    {
                        if (!tmark)
                            throw new IllegalArgumentException("time in duration must follow T");
                        seen = SEEN_HOUR;
                        _h = value;
                        break;
                    } // fallthrough
                case SEEN_HOUR:
                    if (ch == 'M')
                    {
                        if (!tmark)
                            throw new IllegalArgumentException("time in duration must follow T");
                        seen = SEEN_MINUTE;
                        _m = value;
                        break;
                    } // fallthrough
                case SEEN_MINUTE:
                    if (ch == 'S')
                    {
                        if (!tmark)
                            throw new IllegalArgumentException("time in duration must follow T");
                        seen = SEEN_SECOND;
                        _s = value;
                        break;
                    } // fallthrough
                default:
                    throw new IllegalArgumentException("duration must specify Y M D T H M S in order");
            }
        }
    }

    /**
     * Constructs a GDuration with the specified sign,
     * year, month, day, hours, minutes, seconds, and optional
     * fractional seconds.
     */
    public GDuration(
            int sign,
            int year,
            int month,
            int day,
            int hour,
            int minute,
            int second,
            BigDecimal fraction)
    {
        if (sign != 1 && sign != -1)
            throw new IllegalArgumentException();
        _sign = sign;
        _CY = year;
        _M = month;
        _D = day;
        _h = hour;
        _m = minute;
        _s = second;
        _fs = fraction == null ? GDate._zero : fraction;
    }

    /**
     * Constructs a GDuration from another GDurationSpecification.
     */
    public GDuration(GDurationSpecification gDuration)
    {
        _sign = gDuration.getSign();
        _CY = gDuration.getYear();
        _M = gDuration.getMonth();
        _D = gDuration.getDay();
        _h = gDuration.getHour();
        _m = gDuration.getMinute();
        _s = gDuration.getSecond();
        _fs = gDuration.getFraction();
    }

    /**
     * Builds another GDate with the same value
     * as this one.
     */
    public Object clone()
    {
        return new GDuration(this);
    }

    /**
     * All GDuration instances return true.
     */
    public final boolean isImmutable()
    {
        return true;
    }

    /**
     * Returns the sign of the duration: +1 is forwards
     * and -1 is backwards in time.
     */
    public final int getSign()
        { return _sign; }

    /**
     * Gets the year component.
     */
    public final int getYear()
        { return _CY;  }

    /**
     * Gets the month-of-year component.
     */
    public final int getMonth()
        { return _M;  }

    /**
     * Gets the day-of-month component.
     */
    public final int getDay()
        { return _D; }

    /**
     * Gets the hour-of-day component.
     */
    public final int getHour()
        { return _h; }

    /**
     * Gets the minute-of-hour component.
     */
    public final int getMinute()
        { return _m; }

    /**
     * Gets the second-of-minute component.
     */
    public final int getSecond()
        { return _s; }


    /**
     * Gets the fraction-of-second. Range from 0 (inclusive) to 1 (exclusive).
     */
    public BigDecimal getFraction()
        { return _fs; }

    /**
     * Returns true if all of the individual components
     * of the duration are nonnegative.
     */
    public boolean isValid()
    {
        return GDurationBuilder.isValidDuration(this);
    }

    /**
     * Comparison to another GDuration.
     * <ul>
     * <li>Returns -1 if this < date. (less-than)
     * <li>Returns 0 if this == date. (equal)
     * <li>Returns 1 if this > date. (greater-than)
     * <li>Returns 2 if this <> date. (incomparable)
     * </ul>
     * Two instances are incomparable if they have different amounts
     * of information.
     */
    public final int compareToGDuration(GDurationSpecification duration)
    {
        return GDurationBuilder.compareDurations(this, duration);
    }

    /**
     * The natural string representation of the duration.
     * <p>
     * Any components that are zero are omitted. Note that if the duration
     * is invalid, i.e., it has negative components, those negative
     * components are serialized out here. To check for validity, use
     * the isValid() method; and to normalize most durations to a valid
     * form use the normalize() method.
     */
    public String toString()
    {
        return GDurationBuilder.formatDuration(this);
    }

    /**
     * Returns a new GDuration which is the sum of this one and the
     * supplied duration.  Does a fieldwise addition, with no normalization.
     */
    public GDuration add(GDurationSpecification duration)
    {
        int sign = _sign * duration.getSign();
        return _add(duration, sign);
    }

    /**
     * Returns a new GDuration which is the result of subtracting
     * the supplied duration from this one.  Does a fieldwise
     * subtraction, with no normalization.
     */
    public GDuration subtract(GDurationSpecification duration)
    {
        int sign = -_sign * duration.getSign();
        return _add(duration, sign);
    }

    private GDuration _add(GDurationSpecification duration, int sign)
    {
        GDuration result = new GDuration(this);
        result._CY += sign * duration.getYear();
        result._M += sign * duration.getMonth();
        result._D += sign * duration.getDay();
        result._h += sign * duration.getHour();
        result._m += sign * duration.getMinute();
        result._s += sign * duration.getSecond();

        if (duration.getFraction().signum() == 0)
            return result;

        if (result._fs.signum() == 0 && sign == 1)
            result._fs = duration.getFraction();
        else
            result._fs = sign > 0 ?
                    result._fs.add(duration.getFraction()) :
                    result._fs.subtract(duration.getFraction());
        return result;
    }

    /**
     * Two GDurations are equal if all their fields are equal.
     * The equals function does not apply normalizatin.
     */
    public boolean equals(Object obj)
    {
        if (obj == this)
            return true;
        if (!(obj instanceof GDuration))
            return false;

        GDuration duration = (GDuration)obj;
        return (_sign == duration.getSign() &&
                _CY == duration.getYear() &&
                _M == duration.getMonth() &&
                _D == duration.getDay() &&
                _h == duration.getHour() &&
                _m == duration.getMinute() &&
                _s == duration.getSecond() &&
                _fs.equals(duration.getFraction()));
    }

    public int hashCode()
    {
        return (_s +
                _m * (60 + 7) +
                _h * (60 * 60 + 7) +
                _D * (60 * 60 * 24 + 7) +
                _M * (60 * 60 * 24 * 31 + 7) +
                _CY *(60 * 60 * 24 * 372 + 7) +
                _sign * 11917049);
    }

}