/*   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;
    }

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

}