use std::{fmt::Debug, mem::transmute};

use crate::memory_manager::type_traits::TryToUsize;


fn add_offset_impl(address: usize, offset_select : i32, offset_value : i32, id:i32) -> usize{
     assert!(offset_select == 1 || offset_select == 2 || offset_select == 4 || offset_value == 0, "offset_select not a bit field");
     let offset_value = (offset_select & id) * offset_value;
     if offset_value > 0 {
        address + offset_value as usize
     } else {
         address - offset_value as usize
     }
}


pub fn add_offset_rd(address: impl TryToUsize, offset_select : i32, offset_value : i32) -> usize
{
    let address = address.try_into().expect("address can not be negative");
    add_offset_impl(address, offset_select, offset_value, 4)
}

pub fn add_offset_r1(address: impl TryToUsize, offset_select : i32, offset_value : i32) -> usize
{
    let address = address.try_into().expect("address can not be negative");
    add_offset_impl(address, offset_select, offset_value, 1)
}

pub fn add_offset_r2(address: impl TryToUsize, offset_select : i32, offset_value : i32) -> usize
{
    let address = address.try_into().expect("address can not be negative");
    add_offset_impl(address, offset_select, offset_value, 2)
}


pub fn pack_float_in_i32(val : impl TryInto<f32>) -> i32 {
    let val = val.try_into().unwrap_or_else( |x| panic!("Cannot parse into f32"));
     f32::to_bits(val).cast_signed()
}
