/* UtilLib - Copyright (c) 2012 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.primitives;


/**
 * DecimalLong représente un nombre à deux décimales, autrement dit le format
 * utilisé pour les valeurs monétaires. La règle d'arrondi est la suivante : on
 * prend la troisième décimale, si sa valeur est >=5 on arrondit au supérieur.
 *
 * @author Vincent Calame
 */
public class DecimalLong {

    private DecimalLong() {
    }

    public static long toDecimalLong(int value) {
        return value * 100;
    }

    public static long toDecimalLong(long value) {
        return value * 100;
    }

    public static long toDecimalLong(float f) {
        return toDecimalLong((double) f);
    }

    public static long toDecimalLong(double d) {
        boolean neg = false;
        if (d < 0) {
            neg = true;
            d = -d;
        }
        d = d * 100;
        long lg = (long) Math.floor(d);
        if ((d - lg) >= 0.5) {
            lg = lg + 1;
        }
        if (neg) {
            lg = -lg;
        }
        return lg;
    }

    public static Decimal toDecimal(long l) {
        long partieEntiere = l / 100;
        int partieDecimale = (int) (l % 100);
        byte zeroLength = 0;
        if (partieDecimale == 0) {
            zeroLength = 2;
        } else if (Math.abs(partieDecimale) < 10) {
            zeroLength = 1;
        }
        return new Decimal(partieEntiere, zeroLength, partieDecimale);
    }

    public static long toDecimalLong(Decimal decimal) {
        long lg = decimal.getPartieEntiere() * 100;
        int partieDecimale = decimal.getPartieDecimale();
        if (partieDecimale == 0) {
            return lg;
        }
        byte zeroLength = decimal.getZeroLength();
        if (zeroLength > 2) {
            return lg;
        }
        boolean neg = false;
        if (lg < 0) {
            lg = -lg;
            neg = true;
        }
        if (partieDecimale < 0) {
            partieDecimale = -partieDecimale;
        }
        String s = String.valueOf(partieDecimale);
        int length = s.length();
        int premierChiffre = ((int) s.charAt(0)) - 48;
        int deuxiemeChiffre = 0;
        if (length > 1) {
            deuxiemeChiffre = ((int) s.charAt(1)) - 48;
        }
        int troisiemeChiffre = 0;
        if (length > 2) {
            troisiemeChiffre = ((int) s.charAt(2)) - 48;
        }
        switch (zeroLength) {
            case 2:
                if (premierChiffre >= 5) {
                    lg = lg + 1;
                }
                break;
            case 1:
                lg = lg + premierChiffre;
                if (deuxiemeChiffre >= 5) {
                    lg = lg + 1;
                }
                break;
            case 0:
                lg = lg + premierChiffre * 10 + deuxiemeChiffre;
                if (troisiemeChiffre >= 5) {
                    lg = lg + 1;
                }
                break;
        }
        if (neg) {
            lg = -lg;
        }
        return lg;
    }

    public static String toString(long decimalLong, char decimalSeparator) {
        Decimal decimal = toDecimal(decimalLong);
        return decimal.toStringWithBlank(decimalSeparator);
    }

}
