"""LCM type definitions
This file automatically generated by lcm.
DO NOT MODIFY BY HAND!!!!
"""

"""
kearfott_t.lcm
lcm definition that matches the binary data output message
generated by the PCDAS software that interfaces the kearfott
INS with the rest of the OI subsystem. 
 Copyright 2019 MBARI

"""

from io import BytesIO
import struct

import oi

class kearfott_t(object):

    __slots__ = ["time_unix_sec", "count_publish", "sender_id", "cycles_uint", "mode", "monitor", "latitude_rad", "longitude_rad", "northing_m", "easting_m", "depth_m", "bheight_m", "roll_rad", "pitch_rad", "heading_rad", "vbodyx_ms", "vbodyy_ms", "vbodyz_ms", "accelx_ms2", "accely_ms2", "accelz_ms2", "prate_rads", "qrate_rads", "rrate_rads", "utcTime", "sampleTime", "num_doubles", "doubles"]

    __typenames__ = ["double", "int64_t", "string", "int16_t", "byte", "byte", "double", "double", "double", "double", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "float", "int16_t", "oi.double_t"]

    __dimensions__ = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ["num_doubles"]]

    def __init__(self):
        self.time_unix_sec = 0.0
        """
        Time since Unix Epoch
        LCM Type: double
        """

        self.count_publish = 0
        """
        LCM publish count
        LCM Type: int64_t
        """

        self.sender_id = ""
        """
        Self identifier for sender.
        LCM Type: string
        """

        self.cycles_uint = 0
        """
        Start Message Specific data items.
        LCM Type: int16_t
        """

        self.mode = 0
        """
        incrementing counter
         
          Note: D3 - MODE – SYSTEM MODE - CODED HEXIDECIMAL definition (Figure 19)
          MODE SYSTEM MODE
          00H = IDLE
          01H = COARSE STATIONARY ALIGN
          02H = FINE STATIONARY ALIGN - NOT COMPLETE
          03H = FINE STATIONARY ALIGN - COMPLETE
          04H = COARSE GPS ALIGN
          05H = FINE GPS ALIGN - NOT COMPLETE
          06H = FINE GPS ALIGN - COMPLETE
          07H = DOPPLER/EM LOG ALIGN - NOT COMPLETE
          08H = SPARE
          09H = AIDED NAVIGATION
          0AH = NO/GO (SYSTEM FAILURE)
          NOTE: All other states are invalid.
        
        LCM Type: byte
        """

        self.monitor = 0
        """
        Status Byte
          NAVIGATION MONITOR BINARY *   DISCRETES
          BIT # DEFINITION
          7 DEPTH LOOP OPEN > 1 MINUTE TRUE 1, FALSE 0
          6 GPS DATA PROCESSED TRUE 1, FALSE 0
          5 GPS DATA REJECTED TRUE 1, FALSE 0
          4 DOPPLER/EM-LOG DATA PROCESSED TRUE 1, FALSE 0
          3 DOPPLER/EM-LOG DATA REJECTED TRUE 1, FALSE 0
          2 ZUPT PROCESSED TRUE 1, FALSE 0
          1 ALIGN WITHOUT POSITION TRUE 1, FALSE 0
          0 VALID DVL HEIGHT TRUE 1, FALSE 0
        
        LCM Type: byte
        """

        self.latitude_rad = 0.0
        """
        Mode Status Byte
        LCM Type: double
        """

        self.longitude_rad = 0.0
        """
        radians, positive is north
        LCM Type: double
        """

        self.northing_m = 0.0
        """
        radians, positive is east
        LCM Type: double
        """

        self.easting_m = 0.0
        """
        meters from current datum
        LCM Type: double
        """

        self.depth_m = 0.0
        """
        meters from current datum
        LCM Type: float
        """

        self.bheight_m = 0.0
        """
        meters
        LCM Type: float
        """

        self.roll_rad = 0.0
        """
        meters, altitude
        LCM Type: float
        """

        self.pitch_rad = 0.0
        """
        radians
        LCM Type: float
        """

        self.heading_rad = 0.0
        """
        radians
        LCM Type: float
        """

        self.vbodyx_ms = 0.0
        """
        radians
        LCM Type: float
        """

        self.vbodyy_ms = 0.0
        """
        m/s 
        LCM Type: float
        """

        self.vbodyz_ms = 0.0
        """
        m/s
        LCM Type: float
        """

        self.accelx_ms2 = 0.0
        """
        m/s
        LCM Type: float
        """

        self.accely_ms2 = 0.0
        """
        m/s^2
        LCM Type: float
        """

        self.accelz_ms2 = 0.0
        """
        m/s^2
        LCM Type: float
        """

        self.prate_rads = 0.0
        """
        m/s^2
        LCM Type: float
        """

        self.qrate_rads = 0.0
        """
        rad/s
        LCM Type: float
        """

        self.rrate_rads = 0.0
        """
        rad/s
        LCM Type: float
        """

        self.utcTime = 0.0
        """
        rad/s
        LCM Type: float
        """

        self.sampleTime = 0.0
        """ LCM Type: float """
        self.num_doubles = 0
        """ LCM Type: int16_t """
        self.doubles = []
        """ LCM Type: oi.double_t[num_doubles] """

    def encode(self):
        buf = BytesIO()
        buf.write(kearfott_t._get_packed_fingerprint())
        self._encode_one(buf)
        return buf.getvalue()

    def _encode_one(self, buf):
        buf.write(struct.pack(">dq", self.time_unix_sec, self.count_publish))
        __sender_id_encoded = self.sender_id.encode('utf-8')
        buf.write(struct.pack('>I', len(__sender_id_encoded)+1))
        buf.write(__sender_id_encoded)
        buf.write(b"\0")
        buf.write(struct.pack(">hBBddddffffffffffffffffh", self.cycles_uint, self.mode, self.monitor, self.latitude_rad, self.longitude_rad, self.northing_m, self.easting_m, self.depth_m, self.bheight_m, self.roll_rad, self.pitch_rad, self.heading_rad, self.vbodyx_ms, self.vbodyy_ms, self.vbodyz_ms, self.accelx_ms2, self.accely_ms2, self.accelz_ms2, self.prate_rads, self.qrate_rads, self.rrate_rads, self.utcTime, self.sampleTime, self.num_doubles))
        for i0 in range(self.num_doubles):
            assert self.doubles[i0]._get_packed_fingerprint() == oi.double_t._get_packed_fingerprint()
            self.doubles[i0]._encode_one(buf)

    @staticmethod
    def decode(data: bytes):
        if hasattr(data, 'read'):
            buf = data
        else:
            buf = BytesIO(data)
        if buf.read(8) != kearfott_t._get_packed_fingerprint():
            raise ValueError("Decode error")
        return kearfott_t._decode_one(buf)

    @staticmethod
    def _decode_one(buf):
        self = kearfott_t()
        self.time_unix_sec, self.count_publish = struct.unpack(">dq", buf.read(16))
        __sender_id_len = struct.unpack('>I', buf.read(4))[0]
        self.sender_id = buf.read(__sender_id_len)[:-1].decode('utf-8', 'replace')
        self.cycles_uint, self.mode, self.monitor, self.latitude_rad, self.longitude_rad, self.northing_m, self.easting_m, self.depth_m, self.bheight_m, self.roll_rad, self.pitch_rad, self.heading_rad, self.vbodyx_ms, self.vbodyy_ms, self.vbodyz_ms, self.accelx_ms2, self.accely_ms2, self.accelz_ms2, self.prate_rads, self.qrate_rads, self.rrate_rads, self.utcTime, self.sampleTime, self.num_doubles = struct.unpack(">hBBddddffffffffffffffffh", buf.read(102))
        self.doubles = []
        for i0 in range(self.num_doubles):
            self.doubles.append(oi.double_t._decode_one(buf))
        return self

    @staticmethod
    def _get_hash_recursive(parents):
        if kearfott_t in parents: return 0
        newparents = parents + [kearfott_t]
        tmphash = (0xb3fe10b7f94bb7a6+ oi.double_t._get_hash_recursive(newparents)) & 0xffffffffffffffff
        tmphash  = (((tmphash<<1)&0xffffffffffffffff) + (tmphash>>63)) & 0xffffffffffffffff
        return tmphash
    _packed_fingerprint = None

    @staticmethod
    def _get_packed_fingerprint():
        if kearfott_t._packed_fingerprint is None:
            kearfott_t._packed_fingerprint = struct.pack(">Q", kearfott_t._get_hash_recursive([]))
        return kearfott_t._packed_fingerprint

    def get_hash(self):
        """Get the LCM hash of the struct"""
        return struct.unpack(">Q", kearfott_t._get_packed_fingerprint())[0]

