#include <iomanip>

#include <Rcpp.h>

#include "types.h"

// [[Rcpp::export(name = "print.mvbinary", rng = false)]]
void print_mvbinary(const MVBinary& binary, int nrLines = 10) {
    // Divider bits
    constexpr uint32_t div = 0x88888888;

    // Get nr of element to be printed
    nrLines = nrLines < binary.size() ? nrLines : binary.size();

    // from first to nr lines print binary events to console
    for (int i = 0; i < nrLines; ++i) {
        uint32_t val = binary[i];
        Rcpp::Rcout << std::setw(12) << std::right << val << ": ";
        for (uint32_t j = 0; j < binary.dim(); ++j) {
            Rcpp::Rcout << ((val & (1 << j)) ? '1' : '.');
            if (div & (1 << j)) {
                Rcpp::Rcout << ' ';
            }
        }
        Rcpp::Rcout << '\n';
    }

    // report skipped entries (if any)
    if (nrLines < binary.size()) {
        Rcpp::Rcout << "[ skipping " << (binary.size() - nrLines) << " lines ]\n";
    }

    Rcpp::Rcout << std::flush;
}

// [[Rcpp::export(rng = false)]]
void printBits(const Rcpp::IntegerVector& ints) {
    // Value with only the left most bit set
    constexpr uint32_t lmb = 1UL << 31;

    for (uint32_t val : ints) {
        Rcpp::Rcout << std::setw(12) << std::right << val << ": ";
        for (int j = 0; j < 8; ++j) {
            for (int k = 0; k < 4; ++k) {
                Rcpp::Rcout << ((val & lmb) ? '1' : '.');
                val <<= 1;
            }
            Rcpp::Rcout << ' ';
        }
        Rcpp::Rcout << '\n';
    }
    Rcpp::Rcout << std::flush;
}
