use std::{fs::File, io::Read, time::Duration};

const WIDTH: usize = 160;
const HEIGHT: usize = 120;

fn main()
{
    let mut data = vec![];
    File::open("v.bin").unwrap().read_to_end(&mut data).unwrap();

    let mut k = 0;
    print!("\x1B[40m\x1B[37m");
    for frame in data.chunks((WIDTH * HEIGHT) / 8)
    {
        print!("\x1B[H");
        for j in 0..(HEIGHT / 4)
        {
            for i in 0..(WIDTH / 2)
            {
                let offset = retrieve_braille_bits(frame, i, j);
                let char = char::from_u32(0x2800 + offset as u32).unwrap();
                print!("{}", char);
            }
            println!();
        }
        std::thread::sleep(Duration::from_millis(50));
    }
}

fn data_index(data: &[u8], x: usize, y: usize) -> bool
{
    let bit_index = x + y * WIDTH;
    let byte_index = bit_index / 8;
    let shift_index = 7 - bit_index % 8;
    ((data[byte_index] >> shift_index) & 1) != 0
}

fn retrieve_braille_bits(data: &[u8], bx: usize, by: usize) -> u8
{
    let bitmap = [0, 1, 2, 6, 3, 4, 5, 7];
    let mut offset = 0u8;
    for i in 0..2
    {
        for j in 0..4
        {
            let pixel = data_index(data, bx * 2 + i, by * 4 + j);
            if pixel
            {
                offset |= 1 << bitmap[j + 4 * i];
            }
        }
    }
    offset
}

fn bit_to_bytes(byte: u8) -> [bool; 8]
{
    [
        ((byte >> 7) & 1) != 0,
        ((byte >> 6) & 1) != 0,
        ((byte >> 5) & 1) != 0,
        ((byte >> 4) & 1) != 0,
        ((byte >> 3) & 1) != 0,
        ((byte >> 2) & 1) != 0,
        ((byte >> 1) & 1) != 0,
        (byte & 1) != 0,
    ]
}
