use core::cmp::Ordering;
use core::fmt;
#[cfg(feature = "logging")]
use log::error;
use super::{tri_data_structure::TriDataStructure, tri_iterator::TriIterator};
use crate::{VertexNode, utils::types::HedgeIteratorIdx};
#[derive(Clone)]
pub struct HedgeIterator<'a> {
pub tds: &'a TriDataStructure,
pub idx: HedgeIteratorIdx,
}
impl<'a> HedgeIterator<'a> {
pub const fn new(tds: &'a TriDataStructure, idx: HedgeIteratorIdx) -> Self {
Self { tds, idx }
}
pub fn starting_node(&self) -> VertexNode {
self.tds.hedge_starting_nodes[self.idx]
}
pub fn is_conceptual(&self) -> bool {
self.starting_node().is_conceptual() || self.end_node().is_conceptual()
}
pub fn is_sound(&self) -> bool {
let mut sound = true;
let starting_node = self.starting_node();
let end_node = self.end_node();
#[allow(unused)]
let mut check = |condition: bool, error_msg: &str| {
if !condition {
#[cfg(feature = "logging")]
error!("{self}: {error_msg}");
sound = false;
}
};
check(self.next().starting_node() == end_node, "Wrong next hedge");
check(self.prev().end_node() == starting_node, "Wrong prev hedge");
check(
self.twin().starting_node() == end_node && self.twin().end_node() == starting_node,
"Wrong twin hedge",
);
sound
}
pub fn end_node(&self) -> VertexNode {
match (self.idx % 3).cmp(&2) {
Ordering::Equal => self.tds.hedge_starting_nodes[self.idx - 2],
Ordering::Greater | Ordering::Less => self.tds.hedge_starting_nodes[self.idx + 1], }
}
pub fn next(&self) -> HedgeIterator<'a> {
match (self.idx % 3).cmp(&2) {
Ordering::Equal => Self::new(self.tds, self.idx - 2),
Ordering::Greater | Ordering::Less => Self::new(self.tds, self.idx + 1),
}
}
pub fn twin(&self) -> HedgeIterator<'a> {
Self::new(self.tds, self.tds.hedge_twins[self.idx])
}
pub fn prev(&self) -> HedgeIterator<'a> {
match (self.idx % 3).cmp(&0) {
Ordering::Equal => Self::new(self.tds, self.idx + 2),
Ordering::Greater | Ordering::Less => Self::new(self.tds, self.idx - 1),
}
}
pub const fn tri(&self) -> TriIterator<'a> {
TriIterator::new(self.tds, self.idx / 3)
}
}
impl fmt::Display for HedgeIterator<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Edge {}: {} -> {}",
self.idx,
self.starting_node(),
self.end_node()
)
}
}