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

from io import BytesIO
import struct
import sys

from . import *
from .Vector3 import Vector3


class Inertia(object):
    msg_name = "geometry_msgs.Inertia"

    __slots__ = ["m", "com", "ixx", "ixy", "ixz", "iyy", "iyz", "izz"]

    __typenames__ = [
        "double",
        "Vector3",
        "double",
        "double",
        "double",
        "double",
        "double",
        "double",
    ]

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

    m: "double"
    com: Vector3
    ixx: "double"
    ixy: "double"
    ixz: "double"
    iyy: "double"
    iyz: "double"
    izz: "double"

    def __init__(
        self, m=0.0, com=Vector3(), ixx=0.0, ixy=0.0, ixz=0.0, iyy=0.0, iyz=0.0, izz=0.0
    ):
        # LCM Type: double
        self.m = m
        # LCM Type: Vector3
        self.com = com
        # LCM Type: double
        self.ixx = ixx
        # LCM Type: double
        self.ixy = ixy
        # LCM Type: double
        self.ixz = ixz
        # LCM Type: double
        self.iyy = iyy
        # LCM Type: double
        self.iyz = iyz
        # LCM Type: double
        self.izz = izz

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

    def _encode_one(self, buf):
        buf.write(struct.pack(">d", self.m))
        assert self.com._get_packed_fingerprint() == Vector3._get_packed_fingerprint()
        self.com._encode_one(buf)
        buf.write(
            struct.pack(
                ">dddddd", self.ixx, self.ixy, self.ixz, self.iyy, self.iyz, self.izz
            )
        )

    @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.m = struct.unpack(">d", buf.read(8))[0]
        self.com = cls._get_field_type("com")._decode_one(buf)
        self.ixx, self.ixy, self.ixz, self.iyy, self.iyz, self.izz = struct.unpack(
            ">dddddd", buf.read(48)
        )
        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 = (
            0xBEAA1A2A4C70B2E0 + Vector3._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]
