"""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 . import *
from .Marker import Marker


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

    __slots__ = [
        "markers_length",
        "name",
        "orientation",
        "orientation_mode",
        "interaction_mode",
        "always_visible",
        "markers",
        "independent_marker_orientation",
        "description",
    ]

    __typenames__ = [
        "int32_t",
        "string",
        "geometry_msgs.Quaternion",
        "byte",
        "byte",
        "boolean",
        "Marker",
        "boolean",
        "string",
    ]

    __dimensions__ = [
        None,
        None,
        None,
        None,
        None,
        None,
        ["markers_length"],
        None,
        None,
    ]

    markers_length: "int32_t"
    name: "string"
    orientation: geometry_msgs.Quaternion
    orientation_mode: "byte"
    interaction_mode: "byte"
    always_visible: "boolean"
    markers: Marker
    independent_marker_orientation: "boolean"
    description: "string"

    INHERIT = 0
    FIXED = 1
    VIEW_FACING = 2
    NONE = 0
    MENU = 1
    BUTTON = 2
    MOVE_AXIS = 3
    MOVE_PLANE = 4
    ROTATE_AXIS = 5
    MOVE_ROTATE = 6
    MOVE_3D = 7
    ROTATE_3D = 8
    MOVE_ROTATE_3D = 9

    def __init__(
        self,
        markers_length=0,
        name="",
        orientation=geometry_msgs.Quaternion(),
        orientation_mode=0,
        interaction_mode=0,
        always_visible=False,
        markers=[],
        independent_marker_orientation=False,
        description="",
    ):
        # LCM Type: int32_t
        self.markers_length = markers_length
        # LCM Type: string
        self.name = name
        # LCM Type: geometry_msgs.Quaternion
        self.orientation = orientation
        # LCM Type: byte
        self.orientation_mode = orientation_mode
        # LCM Type: byte
        self.interaction_mode = interaction_mode
        # LCM Type: boolean
        self.always_visible = always_visible
        # LCM Type: Marker[markers_length]
        self.markers = markers
        # LCM Type: boolean
        self.independent_marker_orientation = independent_marker_orientation
        # LCM Type: string
        self.description = description

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

    def _encode_one(self, buf):
        buf.write(struct.pack(">i", self.markers_length))
        __name_encoded = self.name.encode("utf-8")
        buf.write(struct.pack(">I", len(__name_encoded) + 1))
        buf.write(__name_encoded)
        buf.write(b"\0")
        assert (
            self.orientation._get_packed_fingerprint()
            == geometry_msgs.Quaternion._get_packed_fingerprint()
        )
        self.orientation._encode_one(buf)
        buf.write(
            struct.pack(
                ">BBb",
                self.orientation_mode,
                self.interaction_mode,
                self.always_visible,
            )
        )
        for i0 in range(self.markers_length):
            assert (
                self.markers[i0]._get_packed_fingerprint()
                == Marker._get_packed_fingerprint()
            )
            self.markers[i0]._encode_one(buf)
        buf.write(struct.pack(">b", self.independent_marker_orientation))
        __description_encoded = self.description.encode("utf-8")
        buf.write(struct.pack(">I", len(__description_encoded) + 1))
        buf.write(__description_encoded)
        buf.write(b"\0")

    @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.markers_length = struct.unpack(">i", buf.read(4))[0]
        __name_len = struct.unpack(">I", buf.read(4))[0]
        self.name = buf.read(__name_len)[:-1].decode("utf-8", "replace")
        self.orientation = cls._get_field_type("orientation")._decode_one(buf)
        self.orientation_mode, self.interaction_mode = struct.unpack(">BB", buf.read(2))
        self.always_visible = bool(struct.unpack("b", buf.read(1))[0])
        self.markers = []
        for i0 in range(self.markers_length):
            self.markers.append(cls._get_field_type("markers")._decode_one(buf))
        self.independent_marker_orientation = bool(struct.unpack("b", buf.read(1))[0])
        __description_len = struct.unpack(">I", buf.read(4))[0]
        self.description = buf.read(__description_len)[:-1].decode("utf-8", "replace")
        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 = (
            0x9E1DB7D7740DA609
            + geometry_msgs.Quaternion._get_hash_recursive(newparents)
            + Marker._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]
