//! 24 bits memory location that pretends to be a [`Label`].

use super::label::Label;
use std::fmt::{Debug, Formatter, Result as FmtResult};

// FIXME Maybe make it the `Position(u32)` tuple struct?
/// A generic memory location.
///
/// As the Mega Drive can't address more than 24 bits, the held memory location isn't expected to be
/// greater than `0xffffff`, but nothing prevents it to be.
///
/// When debug-formatted, `Position` will pretend to be a [`Label`]. If the label doesn't exist, it
/// will pretend to be the `LabelXXXXXX` label where `XXXXXX` is the uppercase hexadecimal
/// representation of the memory location. While abusing the debug formatter isn't semantically
/// correct, it is enough for the use case of this program, which is to discover and extract data
/// from Monster World IV.
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Position {
    pos: u32,
}

impl Position {
    pub fn new(pos: u32) -> Position {
        Position { pos }
    }

    pub fn position(&self) -> u32 {
        self.pos
    }
}

impl Debug for Position {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        if let Ok(label) = Label::try_from(self.position()) {
            write!(f, "{:?}", label)
        } else {
            write!(f, "Label{:06X}", self.position())
        }
    }
}
