/*   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 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;
        _fs = GDate._zero;
    }

    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 unsigned integer, i.e., an integer that conforms to the pattern [0-9]+
        // {was: 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)
        {
            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 (!GDate.isDigit(ch))
                throw new IllegalArgumentException("illegal duration at char[" + start + "]: '" + ch + "'");
            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;
            }

            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");
            }
        }

        if ( seen == SEEN_NOTHING )
            throw new IllegalArgumentException("duration must contain at least one number and its designator: " + str);
    }

    /**
     * Constructs a GDuration with the specified sign,
     * year, month, day, hours, minutes, seconds, and optional
     * fractional seconds.
     * @param sign +1 for a positive duration, -1 for a negative duration
     * @throws java.lang.IllegalArgumentException if the sign is not 1 or -1
     */
    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 &lt; duration. (less-than)
     * <li>Returns 0 if this == duration. (equal)
     * <li>Returns 1 if this &gt; duration. (greater-than)
     * <li>Returns 2 if this &lt;&gt; duration. (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);
    }

}
