import ctypes
from .enums import RdrModes, DesControl, IbitRequest, StbySelection, SarExecSelection,SpotSelection, SilenceSelection, SarExecSelection,TransferFeatureBug
import Grifo_E_1553lib.data_types.enum_map as em

em.ENUM_MAP.update({
    "master_mode": RdrModes,
    "des_ctrl": DesControl,
    "ibit": IbitRequest,
    "sar_type": SarExecSelection,
    "stby" :StbySelection,
    "stop_powerup" : SpotSelection,
    "silence": SilenceSelection,
    "sar_type" : SarExecSelection,
    "transfer_feature_bug" : TransferFeatureBug
})


class _RdrModeCommandWordStr(ctypes.LittleEndianStructure):
    _pack_ = 1
    _fields_ = [
        # LSB -> MSB ordering for LittleEndianStructure
        ("spare_0_1", ctypes.c_uint16, 2),
        ("sar_type", ctypes.c_uint16, 1),
        ("silence", ctypes.c_uint16, 1),
        ("reserved11", ctypes.c_uint16, 1),
        ("stop_powerup", ctypes.c_uint16, 1),
        ("freeze", ctypes.c_uint16, 1),
        ("stby", ctypes.c_uint16, 1),
        ("ibit", ctypes.c_uint16, 1),
        ("des_ctrl", ctypes.c_uint16, 3),
        ("master_mode", ctypes.c_uint16, 4),
    ]

class RdrModeCommandWord(ctypes.Union):
    _pack_ = 1
    _fields_ = [
        ("raw", ctypes.c_uint16),
        ("str", _RdrModeCommandWordStr)
        
    ]

    # Getter/setter wrappers using raw bit masks (MSB=15..LSB=0)
    def get_master_mode(self):
        return RdrModes((self.raw >> 12) & 0x0F)

    def set_master_mode(self, value):
        self.raw = (self.raw & ~(0x0F << 12)) | ((int(value) & 0x0F) << 12)

    def get_des_ctrl(self):
        return DesControl((self.raw >> 9) & 0x07)

    def set_des_ctrl(self, value):
        self.raw = (self.raw & ~(0x07 << 9)) | ((int(value) & 0x07) << 9)

    def get_ibit(self):
        return IbitRequest((self.raw >> 8) & 0x01)

    def set_ibit(self, value):
        self.raw = (self.raw & ~(0x01 << 8)) | ((int(value) & 0x01) << 8)

    def get_stby(self):
        return StbySelection((self.raw >> 7) & 0x01)

    def set_stby(self, value):
        self.raw = (self.raw & ~(0x01 << 7)) | ((int(value) & 0x01) << 7)

    def get_freeze(self):
        return (self.raw >> 6) & 0x01

    def set_freeze(self, value):
        self.raw = (self.raw & ~(0x01 << 6)) | ((int(value) & 0x01) << 6)

    def get_stop_powerup(self):
        return SpotSelection((self.raw >> 5) & 0x01)

    def set_stop_powerup(self, value):
        self.raw = (self.raw & ~(0x01 << 5)) | ((int(value) & 0x01) << 5)

    def get_reserved11(self):
        return (self.raw >> 4) & 0x01

    def set_reserved11(self, value):
        self.raw = (self.raw & ~(0x01 << 4)) | ((int(value) & 0x01) << 4)
    def get_silence(self):
        return SilenceSelection((self.raw >> 3) & 0x01)

    def set_silence(self, value):
        self.raw = (self.raw & ~(0x01 << 3)) | ((int(value) & 0x01) << 3)

    def get_sar_type(self):
        return SarExecSelection((self.raw >> 2) & 0x01)

    def set_sar_type(self, value):
        self.raw = (self.raw & ~(0x01 << 2)) | ((int(value) & 0x01) << 2)

    def get_spare(self):
        return (self.raw >> 0) & 0x03

    def set_spare(self, value):
        self.raw = (self.raw & ~0x03) | (int(value) & 0x03)