/* UtilLib - Copyright (c) 2005-2006 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;


/**
 *
 * @author  Vincent Calame
 */
public class BitmaskCounter {

    int[] counts = new int[32];
    int noemptybitmask = 0;

    public BitmaskCounter() {
    }

    public BitmaskCounter(BitmaskCounter maskCounter) {
        this.noemptybitmask = maskCounter.noemptybitmask;
        System.arraycopy(maskCounter.counts, 0, counts, 0, 32);
    }

    public boolean isEmpty() {
        return (noemptybitmask == 0);
    }

    /**
     * Équivalent de ((bitmask & getNoEmptyBitmask()) == 0)
     */
    public boolean isEmptyForBitmask(int bitmask) {
        return ((bitmask & noemptybitmask) == 0);
    }

    public int getNoEmptyBitmask() {
        return noemptybitmask;
    }

    /**
     * est égal à ~getNoEmptyBitmask
     */
    public int getEmptyBitmask() {
        return (~noemptybitmask);
    }

    public int getCountAt(byte rang) {
        return counts[rang];
    }

    public int getCount(int bitmask) {
        if ((noemptybitmask & bitmask) == 0) {
            return 0;
        }
        int count = 0;
        for (int i = 0; i < 32; i++) {
            int puissance = BitmaskUtils.getBitValue(i);
            if ((bitmask & puissance) != 0) {
                count = count + counts[i];
            }
        }
        return count;
    }

    public void increaseCount(int bitmask) {
        if (bitmask == 0) {
            return;
        }
        for (int i = 0; i < 32; i++) {
            int puissance = BitmaskUtils.getBitValue(i);
            if ((bitmask & puissance) != 0) {
                counts[i]++;
            }
        }
        noemptybitmask = noemptybitmask | bitmask;
    }

    public void decreaseCount(int bitmask) {
        if (bitmask == 0) {
            return;
        }
        for (int i = 0; i < 32; i++) {
            int puissance = BitmaskUtils.getBitValue(i);
            if ((bitmask & puissance) != 0) {
                counts[i]--;
                if (counts[i] <= 0) {
                    counts[i] = 0;
                    noemptybitmask = (noemptybitmask & (~puissance));
                }
            }
        }
    }

}
