// mod register;
mod split_register;
mod memory_register;
mod register_error;

pub use split_register::SplitRegister;
pub use memory_register::MemoryRegister;
pub use register_error::RegisterError;
use rust_decimal::Decimal;

/// P101 operating register (A, M, R) containing
/// up to 22 digits, decimal point and sign.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Register {
    value: Decimal,
}

impl Register {
    /// Creates a new register initializing it to zero
    /// (the "reset" condition).
    pub fn new() -> Register {
        Register {
            value: Decimal::new(0, 0),
        }
    }

    pub fn with_value(value: Decimal) -> Register {
        Register {
            value
        }
    }

    /// Returns the register value.
    pub fn read(&self) -> Decimal {
    	self.value
    }

    /// Set the register value.
    pub fn write(&mut self, value: Decimal) -> Result<(), RegisterError> {
        // TODO: Vale la pena di controllare l'overflow?
        self.value = value;
        Ok(())
    }
}

impl Default for Register {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use rust_decimal::Decimal;
    use super::Register;

    #[test]
    pub fn register_is_initialized_to_zero() {
        let r = Register::new();
        let d = Decimal::new(0, 0);

        assert_eq!(d, r.value);
    }

    #[test]
    pub fn register_stores_the_written_value() {
        let mut r = Register::new();
        let d1 = Decimal::new(1, 0);
        let d1_1 = Decimal::new(1, 0);

        r.write(d1).unwrap();
        assert_eq!(d1, r.value);

        r.write(d1_1).unwrap();
        assert_eq!(d1_1, r.value);
    }

    #[test]
    pub fn read_the_register_value() {
        let d1_1 = Decimal::new(1, 0);

        let r = Register {
            value: d1_1,
        };

        assert_eq!(d1_1, r.value);
    }
}
