/*   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;
import java.math.BigInteger;

/**
 * Used to build {@link GDuration GDurations}.
 */ 
public class GDurationBuilder 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 GDurationBuilder representing zero seconds.
     */
    public GDurationBuilder()
    {
        _sign = +1;
        _fs = GDate._zero;
    }

    /**
     * Constructs a GDuration from a lexical
     * representation.
     */
    public GDurationBuilder(String s)
    {
        this(new GDuration(s));
    }

    /**
     * Constructs a GDurationBuilder 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 GDurationBuilder(
            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 GDurationBuilder from another GDurationBuilderSpecification.
     */
    public GDurationBuilder(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 GDurationBuilder with the same value
     * as this one.
     */
    public Object clone()
    {
        return new GDurationBuilder(this);
    }

    /**
     * Builds a GDuration from this GDurationBuilder.
     */
    public GDuration toGDuration()
    {
        return new GDuration(this);
    }

    /**
     * Adds to this duration.  Does a fieldwise add, with no
     * normalization.
     */
    public void addGDuration(GDurationSpecification duration)
    {
        int sign = _sign * duration.getSign();
        _add(duration, sign);
    }

    /**
     * Subtracts from this duration.  Does a fieldwise subtraction,
     * with no normalization.
     */
    public void subtractGDuration(GDurationSpecification duration)
    {
        int sign = -_sign * duration.getSign();
        _add(duration, sign);
    }

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

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

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

    /**
     * Sets the sign.
     */
    public final void setSign(int sign)
    {
        if (sign != 1 && sign != -1)
            throw new IllegalArgumentException();
        _sign = sign;
    }

    /**
     * Sets the year component.
     */
    public void setYear(int year)
        { _CY = year; }

    /**
     * Sets the month component.
     */
    public void setMonth(int month)
        { _M = month; }

    /**
     * Sets the day component.
     */
    public void setDay(int day)
        { _D = day;  }

    /**
     * Sets the hour component.
     */
    public void setHour(int hour)
        { _h = hour;  }

    /**
     * Sets the minute component.
     */
    public void setMinute(int minute)
        { _m = minute; }

    /**
     * Sets the second component.
     */
    public void setSecond(int second)
        { _s = second; }

    /**
     * Sets the fraction-of-second component.
     */
    public void setFraction(BigDecimal fraction)
        { _fs = fraction == null ? GDate._zero : fraction; }

    /**
     * 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.
     * This value does not necessarily reflect the
     * true direction of the duration if the duration
     * is not normalized or not normalizable.
     */
    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);
    }


    /**
     * Normalize a duration value. This ensures that months,
     * hours, minutes, seconds, and fractions are positive and
     * within the ranges 0..11, 0..23, 0..59, etc. Negative
     * durations are indicated by a negative sign rather
     * than negative components.
     * <p>
     * Most duration specifications can be normalized to
     * valid durations with all positive components, but
     * not all of them can.
     * <p>
     * The only situations which cannot be normalized are
     * where the year/month and the day/hour/minute/second
     * offsets are of opposite sign. Days cannot be carried
     * into months since the length of a Gregorian month is
     * variable depending on when the duration is applied.
     * In these cases, this method normalizes the components
     * so that "day" is the only negative component.
     */
    public void normalize()
    {
        _normalizeImpl(true);
    }

    /**
     * fQuotient(a, b) = the greatest integer less than or equal to a/b
     */
    private static final long _fQuotient(long a, int b)
    {
        if ((a < 0) == (b < 0))
            return a / b;

        return -((b - a - 1) / b);
    }

    /**
     * modulo(a, b) = a - fQuotient(a,b)*b
     */
    private static final int _mod(long a, int b, long quotient)
    {
        return (int)(a - quotient*b) ;
    }


    /**
     * Private implemenation of normalize. The flag is
     * to facilitate this method calling itself without
     * danger of infinite recursion.
     */
    private void _normalizeImpl(boolean adjustSign)
    {
        long temp;

        // months to years
        if (_M < 0 || _M > 11)
        {
            temp = _M;
            long ycarry = _fQuotient(temp, 12);
            _M = _mod(temp, 12, ycarry);
            _CY += ycarry;
        }

        long carry = 0;

        // fractions to seconds
        if (_fs != null && (_fs.signum() < 0 || _fs.compareTo(GDate._one) >= 0))
        {
            BigDecimal bdcarry = _fs.setScale(0, BigDecimal.ROUND_FLOOR);
            _fs = _fs.subtract(bdcarry);
            carry = bdcarry.intValue();
        }

        if (carry != 0 || _s < 0 || _s > 59 || _m < 0 || _m > 50 || _h < 0 || _h > 23)
        {
            // seconds
            temp = _s + carry;
            carry = _fQuotient(temp, 60);
            _s = _mod(temp, 60, carry);

            // minutes
            temp = _m + carry;
            carry = _fQuotient(temp, 60);
            _m = _mod(temp, 60, carry);

            // hours
            temp = _h + carry;
            carry = _fQuotient(temp, 24);
            _h = _mod(temp, 24, carry);
            _D += carry;
        }

        if (_CY == 0 && _M == 0 && _D == 0 && _h == 0 && _m == 0 && _s == 0 && (_fs == null || _fs.signum() == 0))
            _sign = 1;

        if (adjustSign && (_D < 0 || _CY < 0))
        {
            int sign = (_D <= 0 && (_CY < 0 || _CY == 0 && _M == 0)) ? -_sign : _getTotalSignSlowly();
            if (sign == 2)
                sign = (_CY < 0) ? -_sign : _sign;
            if (sign == 0)
                sign = 1;
            if (sign != _sign)
            {
                _sign = sign;
                _CY = -_CY;
                _M = -_M;
                _D = -_D;
                _h = -_h;
                _m = -_m;
                _s = -_s;
                if (_fs != null)
                    _fs = _fs.negate();
            }
            _normalizeImpl(false);
        }
    }


    /* package */ static boolean isValidDuration(GDurationSpecification spec)
    {
        if (!(spec.getSign() == 1 || spec.getSign() == -1))
            return false;

        return (spec.getYear() >= 0 && spec.getMonth() >= 0 && spec.getDay() >= 0 &&
                spec.getHour() >= 0 && spec.getMinute() >= 0  && spec.getSecond() >= 0 &&
                spec.getFraction().signum() >= 0);
    }

    /**
     * Comparison to another GDuration.
     * <ul>
     * <li>Returns -1 if this < duration. (less-than)
     * <li>Returns 0 if this == duration. (equal)
     * <li>Returns 1 if this > duration. (greater-than)
     * <li>Returns 2 if this <> 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);
    }

    /* package */ static int compareDurations(GDurationSpecification d1, GDurationSpecification d2)
    {
        // first do an all-fields check
        if (d1.getFraction().signum() == 0 && d2.getFraction().signum() == 0)
        {
            int s1 = d1.getSign();
            int s2 = d2.getSign();
            long month1 = s1 * ((long)d1.getYear() * 12 + d1.getMonth());
            long month2 = s2 * ((long)d2.getYear() * 12 + d2.getMonth());
            long sec1 = s1 * ((((long)d1.getDay() * 24 + d1.getHour()) * 60 + d1.getMinute()) * 60 + d1.getSecond());
            long sec2 = s2 * ((((long)d2.getDay() * 24 + d2.getHour()) * 60 + d2.getMinute()) * 60 + d2.getSecond());
            if (month1 == month2)
            {
                if (sec1 == sec2)
                    return 0;
                if (sec1 < sec2)
                    return -1;
                if (sec1 > sec2)
                    return 1;
            }
            if (month1 < month2 && sec1 - sec2 < 28 * 24 * 60 * 60)
                return -1;
            if (month1 > month2 && sec2 - sec1 < 28 * 24 * 60 * 60)
                return 1;
        }

        // the answer isn't obvious, so then do a total-sign check
        GDurationBuilder diff = new GDurationBuilder(d1);
        diff.subtractGDuration(d2);
        return diff._getTotalSignSlowly();
    }

    /**
     * Per schema spec, comparison of durations is simply done
     * by calculating adding the duration to these four dates and
     * comparing the results. If the results are ambiguous, the
     * answer is "incomparable".
     */
    private static final GDate[] _compDate = new GDate[]
    {
        new GDate(1696, 9, 1, 0, 0, 0, null, 0, 0, 0),
        new GDate(1697, 2, 1, 0, 0, 0, null, 0, 0, 0),
        new GDate(1903, 3, 1, 0, 0, 0, null, 0, 0, 0),
        new GDate(1903, 7, 1, 0, 0, 0, null, 0, 0, 0)
    };


    /**
     * This returns the total sign of the duration, +1
     * if the duration moves forward in time, -1 if the
     * duration moves backwards in time, 0 if the duration
     * is zero-length, and 2 if the duration may be positive
     * or negative depending on the date.
     *
     * (For example, one month minus 30 days is indeterminate).
     */
    private int _getTotalSignSlowly()
    {
        int pos = 0;
        int neg = 0;
        int zer = 0;

        GDateBuilder enddate = new GDateBuilder();
        for (int i = 0; i < _compDate.length; i++)
        {
            enddate.setGDate(_compDate[i]);
            enddate.addGDuration(this);
            switch (enddate.compareToGDate(_compDate[i]))
            {
                case -1:
                    neg++; break;
                case 0:
                    zer++; break;
                case 1:
                    pos++; break;
            }
        }

        if (pos == _compDate.length)
            return +1;
        if (neg == _compDate.length)
            return -1;
        if (zer == _compDate.length)
            return 0;
        return 2;
    }

    /* package */ static String formatDuration(GDurationSpecification duration)
    {
        // Sign+P:      (-)?P
        // Year:        (?:(\d+)Y)?
        // Month:       (?:(\d+)M)?
        // Day:         (?:(\d+)D)?
        // Time:        (?:(T)
        // Hours:          (?:(\d+)H)?
        // Minutes:        (?:(\d+)M)?
        // Seconds:        (?:(\d+(?:\.\d*)?|(?:.\d+)S)?

        StringBuilder message = new StringBuilder(30);

        if (duration.getSign() < 0)
            message.append('-');

        message.append('P');

        if (duration.getYear() != 0)
        {
            message.append(duration.getYear());
            message.append('Y');
        }

        if (duration.getMonth() != 0)
        {
            message.append(duration.getMonth());
            message.append('M');
        }

        if (duration.getDay() != 0)
        {
            message.append(duration.getDay());
            message.append('D');
        }

        if (duration.getHour() != 0 || duration.getMinute() != 0 || duration.getSecond() != 0 ||
             (duration.getFraction().signum() != 0))
        {
            message.append('T');
        }

        if (duration.getHour() != 0)
        {
            message.append(duration.getHour());
            message.append('H');
        }

        if (duration.getMinute() != 0)
        {
            message.append(duration.getMinute());
            message.append('M');
        }

        if (duration.getFraction().signum() != 0)
        {
            BigDecimal s = duration.getFraction();
            if (duration.getSecond() != 0)
                s = s.add(BigDecimal.valueOf(duration.getSecond()));
            // todo when upgrade to 1.5  message.append(s.stripTrailingZeros().toPlainString());
            message.append(stripTrailingZeros(toPlainString(s)));
            message.append('S');
        }
        else if (duration.getSecond() != 0)
        {
            message.append(duration.getSecond());
            message.append('S');
        }
        else if (message.length() <= 2)
            // Specify zero seconds if everything was 0
            message.append("T0S");

        return message.toString();
    }

    public static String toPlainString(BigDecimal bd)
    {
        BigInteger intVal = bd.unscaledValue();
        int scale = bd.scale();
        String intValStr = intVal.toString();
        if (scale == 0)
            return intValStr;

        boolean isNegative = (intValStr.charAt(0) == '-');

        int point = intValStr.length() - scale - (isNegative ? 1 : 0);

        StringBuilder sb = new StringBuilder(intValStr.length() + 2 + (point <= 0 ? (-point + 1) : 0));
        if (point <= 0)
        {
            // prepend zeros and a decimal point.
            if (isNegative) sb.append('-');
            sb.append('0').append('.');
            while (point < 0)
            {
                sb.append('0');
                point++;
            }
            sb.append(intValStr.substring(isNegative ? 1 : 0));
        }
        else if (point < intValStr.length())
        {
            // No zeros needed
            sb.append(intValStr);
            sb.insert(point + (isNegative ? 1 : 0), '.');
        }
        else
        {
            // append zeros if not 0
            sb.append(intValStr);
            if (!intVal.equals(BigInteger.ZERO))
                for (int i = intValStr.length(); i < point; i++)
                    sb.append('0');
        }
        return sb.toString();
    }

    public static String stripTrailingZeros(String s)
    {
        boolean seenDot = false;
        int i = s.length() - 1;
        int zeroIndex = i;

        while(i>=0)
        {
            if (s.charAt(i)!='0')
                break;
            i--;
            zeroIndex--;
        }
        while(i>=0)
        {
            if (s.charAt(i)=='E')
                return s;
            if (s.charAt(i)=='.')
            {
                seenDot = true;
                break;
            }
            i--;
        }
        
        return seenDot? s.substring(0, zeroIndex+1) : s;
    }
}
