use super::sector;

#[macro_export]
macro_rules! read_write_bit_getter_setter {
    ($value:expr, $bit:expr, $name:expr) => {
        paste::item! {
            pub fn [< is_ $name >](&self) -> bool {
                (self.$value.read() & (1 << $bit)) != 0
            }

            pub fn [< set_ $name >](&mut self) {
                self.$value.write(self.$value.read() | (1 << $bit));
            }

            pub fn [< clear_ $name >](&mut self) {
                self.$value.write(self.$value.read() & !(1 << $bit));
            }        
        }
    };
}

pub fn convert_ascii_to_str(bytes: &[u8]) -> Option<&str> {
    if let Ok(str) = std::str::from_utf8(bytes) {
        Some(str)
    }

    else {
        None
    }
}

pub fn force_convert_ascii_to_str(bytes: &[u8]) -> &str {
    if let Some(str) = convert_ascii_to_str(bytes) {
        str
    }

    else {
        "<invalid UTF8 string>"
    }
}

pub const fn xa_audio_interleave_count(files: usize) -> usize {
    match files {
        0..=4  => 4,
        5..=8  => 8,
        9..=16 => 16,
        _      => 32
    }
}

pub const fn sector_count_audio(audio_samples: usize) -> usize {
    multiple_of_round_up(audio_samples, sector::Audio::DATA_SIZE)
}

pub const fn sector_count_mode2_form1(data_size: usize) -> usize {
    multiple_of_round_up(data_size, sector::Mode2Form1::DATA_SIZE)
}

pub const fn sector_count_mode2_form2(data_size: usize) -> usize {
    multiple_of_round_up(data_size, sector::Mode2Form2::DATA_SIZE)
}

pub const fn round_bytes_mode2_form1(data_size: usize) -> usize {
    multiple_of_round_up(data_size, sector::Mode2Form1::DATA_SIZE)*sector::Mode2Form1::DATA_SIZE
}

const fn multiple_of_round_up(size: usize, unit: usize) -> usize {
    (size + (unit - 1))/unit
}