use p101_is::{Instruction, Register, Origin, ConditionalOrigin};
use crate::alu::Digit;

pub trait AluProvider {
    fn update_memory(&mut self, program: Vec<Instruction>) -> Result<(), String>;
    
    fn read_instruction(&self, address: usize) -> Option<Instruction>;

    fn copy_decimal(&mut self) -> Result<(), String>;
    
    fn copy_to_a(&mut self, operand: Register) -> Result<(), String>;
    
    fn copy_m(&mut self, operand: Register) -> Result<(), String>;
    
    fn print(&mut self, operand: Register) -> Result<(), String>;
    
    fn newline(&mut self) -> Result<(), String>;
    
    fn reset(&mut self, operand: Register) -> Result<(), String>;
    
    fn swap_a(&mut self, operand: Register) -> Result<(), String>;
    
    fn dr_exchange(&mut self) -> Result<(), String>;
    
    fn add(&mut self, operand: Register) -> Result<(), String>;
    
    fn subtract(&mut self, operand: Register) -> Result<(), String>;
    
    fn multiply(&mut self, operand: Register) -> Result<(), String>;
    
    fn divide(&mut self, operand: Register) -> Result<(), String>;
    
    fn abs(&mut self) -> Result<(), String>;

    fn sqr(&mut self, operand: Register) -> Result<(), String>;

    fn label(&mut self) -> Result<(), String>;

    fn jump(&mut self, origin: Origin) -> Result<(), String>;

    fn conditional_jump(&mut self, origin: ConditionalOrigin) -> Result<(), String>;

    fn cai_start(&mut self) -> Result<(), String>;

    fn read_ip(&mut self) -> usize;
    
    fn increment_ip(&mut self, step: usize) -> Result<(), String>;

    fn clear_entry(&mut self) -> Result<(), String>;

    fn clear_m(&mut self) -> Result<(), String>;

    fn write_to_m(&mut self, value: Digit) -> Result<(), String>;

    fn entering_decimals(&mut self, value: bool);

    fn invert_sign(&mut self);

    fn clear_memory(&mut self);

    fn get_provider_name(&self) -> &'static str;

    fn start_stop(&mut self) -> Result<(), String>;
}
