from ..message_base import MessageBase
from ..constants import Subaddress, TrackAccuracy, NormFactorXY, NormFactorZ
from ..fields import BitField, EnumField, ScaledField

class MsgB5(MessageBase):
    """
    Message B5: Tracked Target Message
    
    ID: B5
    Direction: RT -> BC (Transmit)
    Subaddress: 15
    Rate: 50 Hz
    Document Ref: 7.2.5
    
    Contains detailed tracking data for the Primary Tracked Target (e.g. HPT in STT).
    Structure overlaps with B4 for Words 01-24, adds Antenna Position in 25-26.
    """
    SUBADDRESS = Subaddress.TX_TRACKED
    IS_TRANSMIT = True

    # --- Word 01: Track Validity and Status Word #1 (Ref 7.2.5.1) ---
    range_valid = BitField(word_index=0, start_bit=0, width=1)
    pos_xyz_valid = BitField(word_index=0, start_bit=1, width=1)
    range_rate_valid = BitField(word_index=0, start_bit=2, width=1)
    velocity_valid = BitField(word_index=0, start_bit=3, width=1)
    accel_valid = BitField(word_index=0, start_bit=4, width=1)
    aspect_angle_valid = BitField(word_index=0, start_bit=5, width=1)
    cas_mach_valid = BitField(word_index=0, start_bit=6, width=1)
    ant_pos_valid = BitField(word_index=0, start_bit=7, width=1) # Specific to B5
    display_coords_valid = BitField(word_index=0, start_bit=8, width=1)
    
    pos_accuracy = EnumField(word_index=0, start_bit=9, width=2, enum_cls=TrackAccuracy)
    vel_accuracy = EnumField(word_index=0, start_bit=11, width=2, enum_cls=TrackAccuracy)
    acc_accuracy = EnumField(word_index=0, start_bit=13, width=2, enum_cls=TrackAccuracy)
    # Bit 15 Spare

    # --- Word 02: Track Validity and Status Word #2 (Ref 7.2.5.2) ---
    reacquisition = BitField(word_index=1, start_bit=0, width=1)
    target_coast = BitField(word_index=1, start_bit=1, width=1)
    hoj_active = BitField(word_index=1, start_bit=2, width=1)
    aoj_active = BitField(word_index=1, start_bit=3, width=1)
    
    norm_factor_x = EnumField(word_index=1, start_bit=4, width=3, enum_cls=NormFactorXY)
    norm_factor_y = EnumField(word_index=1, start_bit=7, width=3, enum_cls=NormFactorXY)
    norm_factor_z = EnumField(word_index=1, start_bit=10, width=2, enum_cls=NormFactorZ)
    
    target_moving_ftt = BitField(word_index=1, start_bit=12, width=1)
    swap_hpt_flag = BitField(word_index=1, start_bit=13, width=1)
    single_pt_rejected = BitField(word_index=1, start_bit=14, width=1)
    # Bit 15 Spare

    # --- Word 03: Time Tag (Ref 7.2.5.3) ---
    time_tag = ScaledField(word_index=2, start_bit=0, width=16, lsb_value=64.0)

    # --- Word 04: Target Range (Ref 7.2.5.4) ---
    target_range = ScaledField(word_index=3, start_bit=0, width=16, lsb_value=8.0)

    # --- Word 05: Normalized Target Position X (Ref 7.2.5.5) ---
    norm_pos_x = ScaledField(word_index=4, start_bit=0, width=16, lsb_value=1.0, signed=True)

    # --- Word 06: Normalized Target Position Y (Ref 7.2.5.6) ---
    norm_pos_y = ScaledField(word_index=5, start_bit=0, width=16, lsb_value=1.0, signed=True)

    # --- Word 07: Normalized Target Position Z (Ref 7.2.5.7) ---
    norm_pos_z = ScaledField(word_index=6, start_bit=0, width=16, lsb_value=1.0, signed=True)

    # --- Word 08: Target Range Rate (Ref 7.2.5.8) ---
    range_rate = ScaledField(word_index=7, start_bit=0, width=16, lsb_value=1.0, signed=True)

    # --- Word 09: Target Velocity Magnitude (Ref 7.2.5.9) ---
    vel_magnitude = ScaledField(word_index=8, start_bit=0, width=16, lsb_value=0.0625)

    # --- Word 10-12: Target Velocity X, Y, Z (Ref 7.2.5.10 - 12) ---
    vel_x = ScaledField(word_index=9, start_bit=0, width=16, lsb_value=0.125, signed=True)
    vel_y = ScaledField(word_index=10, start_bit=0, width=16, lsb_value=0.125, signed=True)
    vel_z = ScaledField(word_index=11, start_bit=0, width=16, lsb_value=0.125, signed=True)

    # --- Word 13: Target Acceleration Magnitude (Ref 7.2.5.13) ---
    acc_magnitude = ScaledField(word_index=12, start_bit=0, width=16, lsb_value=0.015625)

    # --- Word 14-16: Target Acceleration X, Y, Z (Ref 7.2.5.14 - 16) ---
    acc_x = ScaledField(word_index=13, start_bit=0, width=16, lsb_value=0.03125, signed=True)
    acc_y = ScaledField(word_index=14, start_bit=0, width=16, lsb_value=0.03125, signed=True)
    acc_z = ScaledField(word_index=15, start_bit=0, width=16, lsb_value=0.03125, signed=True)

    # --- Word 17: Target Aspect/Track Angle (Ref 7.2.5.17) ---
    # Semicircles, 2's comp
    aspect_angle = ScaledField(word_index=16, start_bit=0, width=16, lsb_value=3.05176e-5, signed=True)

    # --- Word 18: Target CAS (Ref 7.2.5.18) ---
    target_cas = ScaledField(word_index=17, start_bit=0, width=16, lsb_value=3.0518e-2)

    # --- Word 19: Target Mach Number (Ref 7.2.5.19) ---
    target_mach = ScaledField(word_index=18, start_bit=0, width=16, lsb_value=2.4414e-4)

    # --- Word 20: Target X Display Coordinate (Ref 7.2.5.20) ---
    display_x = BitField(word_index=19, start_bit=0, width=10)

    # --- Word 21: Target Y Display Coordinate (Ref 7.2.5.21) ---
    display_y = BitField(word_index=20, start_bit=0, width=10)

    # --- Word 22-24: Standard Deviation Position X, Y, Z (Ref 7.2.5.22 - 24) ---
    std_dev_x = ScaledField(word_index=21, start_bit=0, width=16, lsb_value=0.42725)
    std_dev_y = ScaledField(word_index=22, start_bit=0, width=16, lsb_value=0.42725)
    std_dev_z = ScaledField(word_index=23, start_bit=0, width=16, lsb_value=0.42725)

    # --- Word 25: Antenna Azimuth Position (Ref 7.2.5.25) ---
    # Semicircles, 2's comp
    ant_azimuth = ScaledField(word_index=24, start_bit=0, width=16, lsb_value=3.05176e-5, signed=True)

    # --- Word 26: Antenna Elevation Position (Ref 7.2.5.26) ---
    # Semicircles, 2's comp
    ant_elevation = ScaledField(word_index=25, start_bit=0, width=16, lsb_value=3.05176e-5, signed=True)