#![no_std]
#![no_main]

use max7219::*;
use panic_halt as _;

const DIGITS: [[u8;8]; 10] = [
    [0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00],  // 0030 (zero)
    [0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00],  // 0031 (one)
    [0x78, 0xcc, 0x0c, 0x38, 0x60, 0xc4, 0xfc, 0x00],  // 0032 (two)
    [0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00],  // 0033 (three)
    [0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00],  // 0034 (four)
    [0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00],  // 0035 (five)
    [0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00],  // 0036 (six)
    [0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00],  // 0037 (seven)
    [0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00],  // 0038 (eight)
    [0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00]   // 0039 (nine)
]; 
 
fn flip_bits(mut b: u8) -> u8 {
    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
    return b;
}

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);
    let data = pins.d3.into_output().downgrade();
    let sck = pins.d5.into_output().downgrade();
    let cs = pins.d4.into_output().downgrade();

    let mut display = MAX7219::from_pins(2, data, cs, sck).unwrap();
    display.power_on().unwrap();

    loop {
        for i in 0..99
        {
            let right_digit = i % 10;
            let left_digit = i / 10;
    
            let mut data: [u8; 8] = DIGITS[left_digit];
            for i in 0..8 {
                data[i] = flip_bits(DIGITS[left_digit][i]);
            }
            display.write_raw(0, &data).unwrap();
    
            let mut data: [u8; 8] = DIGITS[right_digit];
            for i in 0..8 {
                data[i] = flip_bits(DIGITS[right_digit][i]);
            }
            display.write_raw(1, &data).unwrap();

            arduino_hal::delay_ms(250 as u16);
        }
    }
}