/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.commons.math.dfp;

/** Subclass of {@link Dfp} which hides the radix-10000 artifacts of the superclass.
 * This should give outward appearances of being a decimal number with DIGITS*4-3
 * decimal digits. This class can be subclassed to appear to be an arbitrary number
 * of decimal digits less than DIGITS*4-3.
 * @version $Revision: 1003892 $ $Date: 2010-10-02 23:28:56 +0200 (sam. 02 oct. 2010) $
 * @since 2.2
 */
public class DfpDec extends Dfp {

    /** Makes an instance with a value of zero.
     * @param factory factory linked to this instance
     */
    protected DfpDec(final DfpField factory) {
        super(factory);
    }

    /** Create an instance from a byte value.
     * @param factory factory linked to this instance
     * @param x value to convert to an instance
     */
    protected DfpDec(final DfpField factory, byte x) {
        super(factory, x);
    }

    /** Create an instance from an int value.
     * @param factory factory linked to this instance
     * @param x value to convert to an instance
     */
    protected DfpDec(final DfpField factory, int x) {
        super(factory, x);
    }

    /** Create an instance from a long value.
     * @param factory factory linked to this instance
     * @param x value to convert to an instance
     */
    protected DfpDec(final DfpField factory, long x) {
        super(factory, x);
    }

    /** Create an instance from a double value.
     * @param factory factory linked to this instance
     * @param x value to convert to an instance
     */
    protected DfpDec(final DfpField factory, double x) {
        super(factory, x);
        round(0);
    }

    /** Copy constructor.
     * @param d instance to copy
     */
    public DfpDec(final Dfp d) {
        super(d);
        round(0);
    }

    /** Create an instance from a String representation.
     * @param factory factory linked to this instance
     * @param s string representation of the instance
     */
    protected DfpDec(final DfpField factory, final String s) {
        super(factory, s);
        round(0);
    }

    /** Creates an instance with a non-finite value.
     * @param factory factory linked to this instance
     * @param sign sign of the Dfp to create
     * @param nans code of the value, must be one of {@link #INFINITE},
     * {@link #SNAN},  {@link #QNAN}
     */
    protected DfpDec(final DfpField factory, final byte sign, final byte nans) {
        super(factory, sign, nans);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance() {
        return new DfpDec(getField());
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final byte x) {
        return new DfpDec(getField(), x);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final int x) {
        return new DfpDec(getField(), x);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final long x) {
        return new DfpDec(getField(), x);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final double x) {
        return new DfpDec(getField(), x);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final Dfp d) {

        // make sure we don't mix number with different precision
        if (getField().getRadixDigits() != d.getField().getRadixDigits()) {
            getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
            final Dfp result = newInstance(getZero());
            result.nans = QNAN;
            return dotrap(DfpField.FLAG_INVALID, "newInstance", d, result);
        }

        return new DfpDec(d);

    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final String s) {
        return new DfpDec(getField(), s);
    }

    /** {@inheritDoc} */
    @Override
    public Dfp newInstance(final byte sign, final byte nans) {
        return new DfpDec(getField(), sign, nans);
    }

    /** Get the number of decimal digits this class is going to represent.
     * Default implementation returns {@link #getRadixDigits()}*4-3. Subclasses can
     * override this to return something less.
     * @return number of decimal digits this class is going to represent
     */
    protected int getDecimalDigits() {
        return getRadixDigits() * 4 - 3;
    }

    /** {@inheritDoc} */
    @Override
    protected int round(int in) {

        int msb = mant[mant.length-1];
        if (msb == 0) {
            // special case -- this == zero
            return 0;
        }

        int cmaxdigits = mant.length * 4;
        int lsbthreshold = 1000;
        while (lsbthreshold > msb) {
            lsbthreshold /= 10;
            cmaxdigits --;
        }


        final int digits = getDecimalDigits();
        final int lsbshift = cmaxdigits - digits;
        final int lsd = lsbshift / 4;

        lsbthreshold = 1;
        for (int i = 0; i < lsbshift % 4; i++) {
            lsbthreshold *= 10;
        }

        final int lsb = mant[lsd];

        if (lsbthreshold <= 1 && digits == 4 * mant.length - 3) {
            return super.round(in);
        }

        int discarded = in;  // not looking at this after this point
        final int n;
        if (lsbthreshold == 1) {
            // look to the next digit for rounding
            n = (mant[lsd-1] / 1000) % 10;
            mant[lsd-1] %= 1000;
            discarded |= mant[lsd-1];
        } else {
            n = (lsb * 10 / lsbthreshold) % 10;
            discarded |= lsb % (lsbthreshold/10);
        }

        for (int i = 0; i < lsd; i++) {
            discarded |= mant[i];    // need to know if there are any discarded bits
            mant[i] = 0;
        }

        mant[lsd] = lsb / lsbthreshold * lsbthreshold;

        final boolean inc;
        switch (getField().getRoundingMode()) {
            case ROUND_DOWN:
                inc = false;
                break;

            case ROUND_UP:
                inc = (n != 0) || (discarded != 0); // round up if n!=0
                break;

            case ROUND_HALF_UP:
                inc = n >= 5;  // round half up
                break;

            case ROUND_HALF_DOWN:
                inc = n > 5;  // round half down
                break;

            case ROUND_HALF_EVEN:
                inc = (n > 5) ||
                      (n == 5 && discarded != 0) ||
                      (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 1);  // round half-even
                break;

            case ROUND_HALF_ODD:
                inc = (n > 5) ||
                      (n == 5 && discarded != 0) ||
                      (n == 5 && discarded == 0 && ((lsb / lsbthreshold) & 1) == 0);  // round half-odd
                break;

            case ROUND_CEIL:
                inc = (sign == 1) && (n != 0 || discarded != 0);  // round ceil
                break;

            case ROUND_FLOOR:
            default:
                inc = (sign == -1) && (n != 0 || discarded != 0);  // round floor
                break;
        }

        if (inc) {
            // increment if necessary
            int rh = lsbthreshold;
            for (int i = lsd; i < mant.length; i++) {
                final int r = mant[i] + rh;
                rh = r / RADIX;
                mant[i] = r % RADIX;
            }

            if (rh != 0) {
                shiftRight();
                mant[mant.length-1]=rh;
            }
        }

        // Check for exceptional cases and raise signals if necessary
        if (exp < MIN_EXP) {
            // Gradual Underflow
            getField().setIEEEFlagsBits(DfpField.FLAG_UNDERFLOW);
            return DfpField.FLAG_UNDERFLOW;
        }

        if (exp > MAX_EXP) {
            // Overflow
            getField().setIEEEFlagsBits(DfpField.FLAG_OVERFLOW);
            return DfpField.FLAG_OVERFLOW;
        }

        if (n != 0 || discarded != 0) {
            // Inexact
            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
            return DfpField.FLAG_INEXACT;
        }
        return 0;
    }

    /** {@inheritDoc} */
    @Override
    public Dfp nextAfter(Dfp x) {

        final String trapName = "nextAfter";

        // make sure we don't mix number with different precision
        if (getField().getRadixDigits() != x.getField().getRadixDigits()) {
            getField().setIEEEFlagsBits(DfpField.FLAG_INVALID);
            final Dfp result = newInstance(getZero());
            result.nans = QNAN;
            return dotrap(DfpField.FLAG_INVALID, trapName, x, result);
        }

        boolean up = false;
        Dfp result;
        Dfp inc;

        // if this is greater than x
        if (this.lessThan(x)) {
            up = true;
        }

        if (equals(x)) {
            return newInstance(x);
        }

        if (lessThan(getZero())) {
            up = !up;
        }

        if (up) {
            inc = power10(log10() - getDecimalDigits() + 1);
            inc = copysign(inc, this);

            if (this.equals(getZero())) {
                inc = power10K(MIN_EXP-mant.length-1);
            }

            if (inc.equals(getZero())) {
                result = copysign(newInstance(getZero()), this);
            } else {
                result = add(inc);
            }
        } else {
            inc = power10(log10());
            inc = copysign(inc, this);

            if (this.equals(inc)) {
                inc = inc.divide(power10(getDecimalDigits()));
            } else {
                inc = inc.divide(power10(getDecimalDigits() - 1));
            }

            if (this.equals(getZero())) {
                inc = power10K(MIN_EXP-mant.length-1);
            }

            if (inc.equals(getZero())) {
                result = copysign(newInstance(getZero()), this);
            } else {
                result = subtract(inc);
            }
        }

        if (result.classify() == INFINITE && this.classify() != INFINITE) {
            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
            result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result);
        }

        if (result.equals(getZero()) && this.equals(getZero()) == false) {
            getField().setIEEEFlagsBits(DfpField.FLAG_INEXACT);
            result = dotrap(DfpField.FLAG_INEXACT, trapName, x, result);
        }

        return result;
    }

}
