#![allow(dead_code)]

mod bfsk;
mod complex;
pub mod fft;
mod filtering;
mod iq;
mod nco;
mod units;
mod windows;
mod ted;
mod math;

use cpal::Data;
use eframe::egui;

const BAUD_RATE: u32 = 1000;

enum TransceiverState
{
    Idle,
    Receiving,
    Transmitting,
}

enum Frame
{
    Data(Vec<u8>),
    Ack
}

impl Frame
{
    pub fn bytes(&self) -> Vec<u8>
    {
        let mut output_bytes = vec![];
        
        // Initial training sequence
        output_bytes.append(&mut vec![0b01010101; 64]);

        // Preamble byte
        output_bytes.push(0xD8);

        // Command
        match self
        {
            Frame::Data(x) =>
            {
                let mut checksum = 0u8;
                x.iter().for_each(|x| checksum ^= x);
                
                assert!(x.len() < 65536, "Data size over MTU");
                let len_u16 = x.len() as u16;
                output_bytes.push((len_u16 & 0xFF).try_into().unwrap());
                output_bytes.push(((len_u16 >> 8) & 0xFF).try_into().unwrap());

                output_bytes.extend(x.iter());

                output_bytes.push(checksum);
            }
            Frame::Ack =>
            {
                output_bytes.push(0xC4);
            }
        }

        // SEND EOT
        output_bytes.extend(std::iter::repeat_n(4, 32));
        output_bytes
    }
}

fn main() {
    let native_options = eframe::NativeOptions::default();
    let _ = eframe::run_native(
        "Egui",
        native_options,
        Box::new(|cc| Ok(Box::new(EguiApp::new(cc)))),
    );
}


//#[derive(Default)]
struct EguiApp {
}

impl EguiApp {
    fn new(
        _cc: &eframe::CreationContext<'_>,
    ) -> Self {

        Self {

        }
    }
}

impl eframe::App for EguiApp {
    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |_ui| {
        });
    }
}

fn byte_to_bits(byte: u8) -> Vec<bool> {
    vec![
        byte & 1 == 1,
        (byte >> 1) & 1 == 1,
        (byte >> 2) & 1 == 1,
        (byte >> 3) & 1 == 1,
        (byte >> 4) & 1 == 1,
        (byte >> 5) & 1 == 1,
        (byte >> 6) & 1 == 1,
        (byte >> 7) & 1 == 1,
    ]
}

fn bits_to_byte(bits: &[bool]) -> u8 {
    bits[0] as u8
        | (bits[1] as u8) << 1
        | (bits[2] as u8) << 2
        | (bits[3] as u8) << 3
        | (bits[4] as u8) << 4
        | (bits[5] as u8) << 5
        | (bits[6] as u8) << 6
        | (bits[7] as u8) << 7
}
