package com.milaboratory.core.motif;

import com.milaboratory.util.BitArray;

import static com.milaboratory.core.motif.LongArrayBitHelper.resetBitLittleEndian;
import static com.milaboratory.core.motif.LongArrayBitHelper.upDivideBy64;
import static com.milaboratory.util.ArraysUtils.deepClone;

final class BitapData {
    final int size;
    final int segmentCount;
    final long[][] patternMask;
    final long[][] reversePatternMask;

    BitapData(int size, long[][] patternMask, long[][] reversePatternMask) {
        if (patternMask.length != reversePatternMask.length)
            throw new IllegalArgumentException();
        if (patternMask[0].length != reversePatternMask[0].length)
            throw new IllegalArgumentException();

        this.size = size;
        this.segmentCount = upDivideBy64(size);

        if (patternMask[0].length != segmentCount)
            throw new IllegalArgumentException();

        this.patternMask = patternMask;
        this.reversePatternMask = reversePatternMask;
    }

    /** Basically transforms bitap data, so that it contains 'N' letters in positions where exactMask has zeros. */
    BitapData toSecondary(BitArray exactMask) {
        if (exactMask.size() != size)
            throw new IllegalArgumentException();

        long[][] newPatternMask = deepClone(patternMask);
        long[][] newReversePatternMask = deepClone(reversePatternMask);

        for (int p = 0; p < size; ++p)
            if (!exactMask.get(p))
                for (int l = 0; l < patternMask.length; ++l) {
                    resetBitLittleEndian(newPatternMask[l], p);
                    resetBitLittleEndian(newReversePatternMask[l], size - p - 1);
                }
        return new BitapData(size, newPatternMask, newReversePatternMask);
    }
}
