use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;
use super::wsjt77::{pack_grid4, pack28};
use crate::core::MessageCodec;
pub trait WsjtApCompatible: MessageCodec + sealed::Sealed {}
mod sealed {
pub trait Sealed {}
}
impl sealed::Sealed for super::Wsjt77Message {}
impl WsjtApCompatible for super::Wsjt77Message {}
#[cfg(feature = "q65")]
impl sealed::Sealed for super::Q65Message {}
#[cfg(feature = "q65")]
impl WsjtApCompatible for super::Q65Message {}
#[derive(Debug, Clone, Default)]
pub struct ApHint {
pub call1: Option<String>,
pub call2: Option<String>,
pub grid: Option<String>,
pub report: Option<String>,
}
impl ApHint {
pub fn new() -> Self {
Self::default()
}
pub fn with_call1(mut self, call: &str) -> Self {
self.call1 = Some(call.to_string());
self
}
pub fn with_call2(mut self, call: &str) -> Self {
self.call2 = Some(call.to_string());
self
}
pub fn with_grid(mut self, grid: &str) -> Self {
self.grid = Some(grid.to_string());
self
}
pub fn with_report(mut self, rpt: &str) -> Self {
self.report = Some(rpt.to_string());
self
}
pub fn has_info(&self) -> bool {
self.call1.is_some() || self.call2.is_some()
}
pub fn build_bits(&self, n_codeword: usize) -> (Vec<u8>, Vec<u8>) {
let mut mask = vec![0u8; n_codeword];
let mut values = vec![0u8; n_codeword];
let mut set_call_bits = |call: &str, start: usize| {
if let Some(n28) = pack28(call) {
for i in 0..28 {
let bit = ((n28 >> (27 - i)) & 1) as u8;
mask[start + i] = 1;
values[start + i] = bit;
}
mask[start + 28] = 1;
values[start + 28] = 0;
}
};
if let Some(ref c1) = self.call1 {
set_call_bits(c1, 0);
}
if let Some(ref c2) = self.call2 {
set_call_bits(c2, 29);
}
if let Some(ref grid) = self.grid
&& let Some(igrid) = pack_grid4(grid)
{
mask[58] = 1;
values[58] = 0; for i in 0..15 {
let bit = ((igrid >> (14 - i)) & 1) as u8;
mask[59 + i] = 1;
values[59 + i] = bit;
}
}
if let Some(ref rpt) = self.report {
let igrid_val: Option<u32> = match rpt.as_str() {
"RRR" => Some(32_400 + 2),
"RR73" => Some(32_400 + 3),
"73" => Some(32_400 + 4),
_ => None,
};
if let Some(igrid) = igrid_val {
mask[58] = 1;
values[58] = 0;
for i in 0..15 {
let bit = ((igrid >> (14 - i)) & 1) as u8;
mask[59 + i] = 1;
values[59 + i] = bit;
}
}
}
if self.has_info() {
mask[74] = 1;
values[74] = 0;
mask[75] = 1;
values[75] = 0;
mask[76] = 1;
values[76] = 1;
}
(mask, values)
}
pub fn locked_bits(&self, n_codeword: usize) -> usize {
let (mask, _) = self.build_bits(n_codeword);
mask.iter().filter(|&&m| m != 0).count()
}
}