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

from io import BytesIO
import struct
import sys

from lcm_msgs import std_msgs
from . import *
from .NavSatStatus import NavSatStatus


class NavSatFix(object):
    msg_name = "sensor_msgs.NavSatFix"

    __slots__ = [
        "header",
        "status",
        "latitude",
        "longitude",
        "altitude",
        "position_covariance",
        "position_covariance_type",
    ]

    __typenames__ = [
        "std_msgs.Header",
        "NavSatStatus",
        "double",
        "double",
        "double",
        "double",
        "byte",
    ]

    __dimensions__ = [None, None, None, None, None, [9], None]

    header: std_msgs.Header
    status: NavSatStatus
    latitude: "double"
    longitude: "double"
    altitude: "double"
    position_covariance: "double"
    position_covariance_type: "byte"

    COVARIANCE_TYPE_UNKNOWN = 0
    COVARIANCE_TYPE_APPROXIMATED = 1
    COVARIANCE_TYPE_DIAGONAL_KNOWN = 2
    COVARIANCE_TYPE_KNOWN = 3

    def __init__(
        self,
        header=std_msgs.Header(),
        status=NavSatStatus(),
        latitude=0.0,
        longitude=0.0,
        altitude=0.0,
        position_covariance=[0.0 for dim0 in range(9)],
        position_covariance_type=0,
    ):
        # LCM Type: std_msgs.Header
        self.header = header
        # LCM Type: NavSatStatus
        self.status = status
        # LCM Type: double
        self.latitude = latitude
        # LCM Type: double
        self.longitude = longitude
        # LCM Type: double
        self.altitude = altitude
        # LCM Type: double[9]
        self.position_covariance = position_covariance
        # LCM Type: byte
        self.position_covariance_type = position_covariance_type

    def lcm_encode(self):
        buf = BytesIO()
        buf.write(NavSatFix._get_packed_fingerprint())
        self._encode_one(buf)
        return buf.getvalue()

    def _encode_one(self, buf):
        assert (
            self.header._get_packed_fingerprint()
            == std_msgs.Header._get_packed_fingerprint()
        )
        self.header._encode_one(buf)
        assert (
            self.status._get_packed_fingerprint()
            == NavSatStatus._get_packed_fingerprint()
        )
        self.status._encode_one(buf)
        buf.write(struct.pack(">ddd", self.latitude, self.longitude, self.altitude))
        buf.write(struct.pack(">9d", *self.position_covariance[:9]))
        buf.write(struct.pack(">B", self.position_covariance_type))

    @classmethod
    def lcm_decode(cls, data: bytes):
        if hasattr(data, "read"):
            buf = data
        else:
            buf = BytesIO(data)
        if buf.read(8) != cls._get_packed_fingerprint():
            raise ValueError("Decode error")
        return cls._decode_one(buf)

    @classmethod
    def _decode_one(cls, buf):
        self = cls()
        self.header = cls._get_field_type("header")._decode_one(buf)
        self.status = cls._get_field_type("status")._decode_one(buf)
        self.latitude, self.longitude, self.altitude = struct.unpack(
            ">ddd", buf.read(24)
        )
        self.position_covariance = struct.unpack(">9d", buf.read(72))
        self.position_covariance_type = struct.unpack(">B", buf.read(1))[0]
        return self

    @classmethod
    def _get_field_type(cls, field_name):
        """Get the type for a field from annotations."""
        annotation = cls.__annotations__.get(field_name)
        if annotation is None:
            return None
        if isinstance(annotation, str):
            module = sys.modules[cls.__module__]
            if hasattr(module, annotation):
                return getattr(module, annotation)
            return None
        return annotation

    @classmethod
    def _get_hash_recursive(cls, parents):
        if cls in parents:
            return 0
        newparents = parents + [cls]
        tmphash = (
            0x4A84D20526D9067A
            + std_msgs.Header._get_hash_recursive(newparents)
            + NavSatStatus._get_hash_recursive(newparents)
        ) & 0xFFFFFFFFFFFFFFFF
        tmphash = (
            ((tmphash << 1) & 0xFFFFFFFFFFFFFFFF) + (tmphash >> 63)
        ) & 0xFFFFFFFFFFFFFFFF
        return tmphash

    _packed_fingerprint = None

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

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