import ctypes
from .enums import BullsEyeIdentifier
import Grifo_E_1553lib.data_types.enum_map as em

em.ENUM_MAP.update({
    "bulls_eye_identifier" : BullsEyeIdentifier
})

class _GraphicOrderStr(ctypes.LittleEndianStructure):
    _pack_ = 1
    _fields_ = [
        ("spare", ctypes.c_uint16, 5),              
        ("bulls_eye_identifier", ctypes.c_uint16, 2),    
        ("attack_steering_cue", ctypes.c_uint16, 1),  
        ("allowable_steering_error_circle", ctypes.c_uint16, 1),       
        ("time-to-go_to_cursor", ctypes.c_uint16, 1),         
        ("intercept_zones_and_target_tip", ctypes.c_uint16, 1),       
        ("break_away_cue", ctypes.c_uint16, 1),             
        ("intercept_flight_director", ctypes.c_uint16, 1),               
        ("waypoint_3", ctypes.c_uint16, 1),               
        ("waypoint_2", ctypes.c_uint16, 1),           
        ("waypoint_1", ctypes.c_uint16, 1),        
    ]

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

    def get_waypoint_01_flag(self):
        return (self.raw >> 15) & 0x01

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

    def get_waypoint_02_flag(self):
        return (self.raw >> 14) & 0x01

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

    def get_waypoint_03_flag(self):
        return (self.raw >> 13) & 0x01

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

    def get_intercept_flight_director(self):
        return (self.raw >> 12) & 0x01

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

    def get_break_away_cue(self):
        return (self.raw >> 11) & 0x01

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

    def get_intercept_zones_and_target_tip(self):
        return (self.raw >> 10) & 0x01

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

    def get_time_to_go_to_cursor(self):
        return (self.raw >> 9) & 0x01

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

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

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

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

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

    # Bitfield accessors for bulls_eye_identifier
    def get_bulls_eye_identifier(self):
        return BullsEyeIdentifier((self.raw >> 5) & 0x03)

    def set_bulls_eye_identifier(self, value):
        self.raw &= ~(0x03 << 5)
        self.raw |= (value << 5)

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

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