"""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 geometry_msgs
from lcm_msgs import std_msgs


class InteractiveMarkerFeedback(object):
    msg_name = "visualization_msgs.InteractiveMarkerFeedback"

    __slots__ = [
        "header",
        "client_id",
        "marker_name",
        "control_name",
        "event_type",
        "pose",
        "menu_entry_id",
        "mouse_point",
        "mouse_point_valid",
    ]

    __typenames__ = [
        "std_msgs.Header",
        "string",
        "string",
        "string",
        "byte",
        "geometry_msgs.Pose",
        "int32_t",
        "geometry_msgs.Point",
        "boolean",
    ]

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

    header: std_msgs.Header
    client_id: "string"
    marker_name: "string"
    control_name: "string"
    event_type: "byte"
    pose: geometry_msgs.Pose
    menu_entry_id: "int32_t"
    mouse_point: geometry_msgs.Point
    mouse_point_valid: "boolean"

    KEEP_ALIVE = 0
    POSE_UPDATE = 1
    MENU_SELECT = 2
    BUTTON_CLICK = 3
    MOUSE_DOWN = 4
    MOUSE_UP = 5

    def __init__(
        self,
        header=std_msgs.Header(),
        client_id="",
        marker_name="",
        control_name="",
        event_type=0,
        pose=geometry_msgs.Pose(),
        menu_entry_id=0,
        mouse_point=geometry_msgs.Point(),
        mouse_point_valid=False,
    ):
        # LCM Type: std_msgs.Header
        self.header = header
        # LCM Type: string
        self.client_id = client_id
        # LCM Type: string
        self.marker_name = marker_name
        # LCM Type: string
        self.control_name = control_name
        # LCM Type: byte
        self.event_type = event_type
        # LCM Type: geometry_msgs.Pose
        self.pose = pose
        # LCM Type: int32_t
        self.menu_entry_id = menu_entry_id
        # LCM Type: geometry_msgs.Point
        self.mouse_point = mouse_point
        # LCM Type: boolean
        self.mouse_point_valid = mouse_point_valid

    def lcm_encode(self):
        buf = BytesIO()
        buf.write(InteractiveMarkerFeedback._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)
        __client_id_encoded = self.client_id.encode("utf-8")
        buf.write(struct.pack(">I", len(__client_id_encoded) + 1))
        buf.write(__client_id_encoded)
        buf.write(b"\0")
        __marker_name_encoded = self.marker_name.encode("utf-8")
        buf.write(struct.pack(">I", len(__marker_name_encoded) + 1))
        buf.write(__marker_name_encoded)
        buf.write(b"\0")
        __control_name_encoded = self.control_name.encode("utf-8")
        buf.write(struct.pack(">I", len(__control_name_encoded) + 1))
        buf.write(__control_name_encoded)
        buf.write(b"\0")
        buf.write(struct.pack(">B", self.event_type))
        assert (
            self.pose._get_packed_fingerprint()
            == geometry_msgs.Pose._get_packed_fingerprint()
        )
        self.pose._encode_one(buf)
        buf.write(struct.pack(">i", self.menu_entry_id))
        assert (
            self.mouse_point._get_packed_fingerprint()
            == geometry_msgs.Point._get_packed_fingerprint()
        )
        self.mouse_point._encode_one(buf)
        buf.write(struct.pack(">b", self.mouse_point_valid))

    @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)
        __client_id_len = struct.unpack(">I", buf.read(4))[0]
        self.client_id = buf.read(__client_id_len)[:-1].decode("utf-8", "replace")
        __marker_name_len = struct.unpack(">I", buf.read(4))[0]
        self.marker_name = buf.read(__marker_name_len)[:-1].decode("utf-8", "replace")
        __control_name_len = struct.unpack(">I", buf.read(4))[0]
        self.control_name = buf.read(__control_name_len)[:-1].decode("utf-8", "replace")
        self.event_type = struct.unpack(">B", buf.read(1))[0]
        self.pose = cls._get_field_type("pose")._decode_one(buf)
        self.menu_entry_id = struct.unpack(">i", buf.read(4))[0]
        self.mouse_point = cls._get_field_type("mouse_point")._decode_one(buf)
        self.mouse_point_valid = bool(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 = (
            0xD44E20643FB0D4F7
            + std_msgs.Header._get_hash_recursive(newparents)
            + geometry_msgs.Pose._get_hash_recursive(newparents)
            + geometry_msgs.Point._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]
