import ctypes
from .enums import (RwsSubmode, SpotSelection, AcmSubmode, GmSubmode, Expand,
                   RangeScale, BarsNum, ScanWidth, VelocityScale)
import Grifo_E_1553lib.data_types.enum_map as em

em.ENUM_MAP.update({
    "rws_submode_selection" : RwsSubmode,
    "spot_function_selection" : SpotSelection,
    "acm_submode_selection" : AcmSubmode,
    "gm_submode_selection" : GmSubmode,
    "expand_function_selection" : Expand,
    "range_scale_selection" : RangeScale,
    "number_of_bars_selection" : BarsNum,
    "azimuth_scan_width_selection" : ScanWidth,
    "velocity_scale_selection" : VelocityScale,
})

class _RdrFunAndParam1Str(ctypes.LittleEndianStructure):
    _pack_ = 1
    _fields_ = [
        ("spare" , ctypes.c_uint16,1),
        ("velocity_scale_selection" , ctypes.c_uint16,1),
        ("azimuth_scan_width_selection" , ctypes.c_uint16,2),
        ("number_of_bars_selection" , ctypes.c_uint16,2),
        ("range_scale_selection" , ctypes.c_uint16,2),
        ("expand_function_selection" , ctypes.c_uint16,2),
        ("gm_submode_selection" , ctypes.c_uint16,1),
        ("acm_submode_selection" , ctypes.c_uint16,3),
        ("spot_function_selection" , ctypes.c_uint16,1),
        ("rws_submode_selection" , ctypes.c_uint16,1)
    ]

class RdrFunAndParam1(ctypes.Union):
    _fields_ = [
        ("raw", ctypes.c_uint16),
        ("str", _RdrFunAndParam1Str)
    ]

    # Bitfield accessors for rws_submode
    def get_rws_submode(self):
        return RwsSubmode((self.raw >> (15-0)) & 0x01)

    def set_rws_submode(self, value):
        self.raw &= ~(0x01 << (15-0))
        self.raw |= (value << (15-0))

    # Bitfield accessors for spot
    def get_spot(self):
        return SpotSelection((self.raw >> (15-1)) & 0x01)

    def set_spot(self, value):
        self.raw &= ~(0x01 << (15-1))
        self.raw |= (value << (15-1))

    # Bitfield accessors for acm_submode
    def get_acm_submode(self):
        return AcmSubmode((self.raw >> (15-4)) & 0x07)

    def set_acm_submode(self, value):
        self.raw &= ~(0x07 << (15-4))
        self.raw |= (value << (15-4))

    # Bitfield accessors for gm_submode
    def get_gm_submode(self):
        return GmSubmode((self.raw >> (15-5)) & 0x01)

    def set_gm_submode(self, value):
        self.raw &= ~(0x01 << (15-5))
        self.raw |= (value << (15-5))

    # Bitfield accessors for expand
    def get_expand(self):
        return Expand((self.raw >> (15-7)) & 0x03)

    def set_expand(self, value):
        self.raw &= ~(0x03 << (15-7))
        self.raw |= (value << (15-7))

    # Bitfield accessors for range_scale
    def get_range_scale(self):
        return RangeScale((self.raw >> (15-9)) & 0x03)

    def set_range_scale(self, value):
        self.raw &= ~(0x03 << (15-9))
        self.raw |= (value << (15-9))

    # Bitfield accessors for bars_num
    def get_bars_num(self):
        return BarsNum((self.raw >> (15-11)) & 0x03)

    def set_bars_num(self, value):
        self.raw &= ~(0x03 << (15-11))
        self.raw |= (value << (15-11))

    # Bitfield accessors for scan_width
    def get_scan_width(self):
        return ScanWidth((self.raw >> (15-13)) & 0x03)

    def set_scan_width(self, value):
        self.raw &= ~(0x03 << (15-13))
        self.raw |= (value << (15-13))

    # Bitfield accessors for velocity_scale
    def get_velocity_scale(self):
        return VelocityScale((self.raw >> (15-14)) & 0x01)

    def set_velocity_scale(self, value):
        self.raw &= ~(0x01 << (15-14))
        self.raw |= (value << (15-14))

    # Bitfield accessors for spare
    def get_spare(self):
        return (self.raw >> 0) & 0x01

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