"""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 Marker(object):
    msg_name = "visualization_msgs.Marker"

    __slots__ = [
        "points_length",
        "colors_length",
        "header",
        "ns",
        "id",
        "type",
        "action",
        "pose",
        "scale",
        "color",
        "lifetime",
        "frame_locked",
        "points",
        "colors",
        "text",
        "mesh_resource",
        "mesh_use_embedded_materials",
    ]

    __typenames__ = [
        "int32_t",
        "int32_t",
        "std_msgs.Header",
        "string",
        "int32_t",
        "int32_t",
        "int32_t",
        "geometry_msgs.Pose",
        "geometry_msgs.Vector3",
        "std_msgs.ColorRGBA",
        "std_msgs.Duration",
        "boolean",
        "geometry_msgs.Point",
        "std_msgs.ColorRGBA",
        "string",
        "string",
        "boolean",
    ]

    __dimensions__ = [
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        None,
        ["points_length"],
        ["colors_length"],
        None,
        None,
        None,
    ]

    points_length: "int32_t"
    colors_length: "int32_t"
    header: std_msgs.Header
    ns: "string"
    id: "int32_t"
    type: "int32_t"
    action: "int32_t"
    pose: geometry_msgs.Pose
    scale: geometry_msgs.Vector3
    color: std_msgs.ColorRGBA
    lifetime: std_msgs.Duration
    frame_locked: "boolean"
    points: geometry_msgs.Point
    colors: std_msgs.ColorRGBA
    text: "string"
    mesh_resource: "string"
    mesh_use_embedded_materials: "boolean"

    ARROW = 0
    CUBE = 1
    SPHERE = 2
    CYLINDER = 3
    LINE_STRIP = 4
    LINE_LIST = 5
    CUBE_LIST = 6
    SPHERE_LIST = 7
    POINTS = 8
    TEXT_VIEW_FACING = 9
    MESH_RESOURCE = 10
    TRIANGLE_LIST = 11
    ADD = 0
    MODIFY = 0
    DELETE = 2
    DELETEALL = 3

    def __init__(
        self,
        points_length=0,
        colors_length=0,
        header=std_msgs.Header(),
        ns="",
        id=0,
        type=0,
        action=0,
        pose=geometry_msgs.Pose(),
        scale=geometry_msgs.Vector3(),
        color=std_msgs.ColorRGBA(),
        lifetime=std_msgs.Duration(),
        frame_locked=False,
        points=[],
        colors=[],
        text="",
        mesh_resource="",
        mesh_use_embedded_materials=False,
    ):
        # LCM Type: int32_t
        self.points_length = points_length
        # LCM Type: int32_t
        self.colors_length = colors_length
        # LCM Type: std_msgs.Header
        self.header = header
        # LCM Type: string
        self.ns = ns
        # LCM Type: int32_t
        self.id = id
        # LCM Type: int32_t
        self.type = type
        # LCM Type: int32_t
        self.action = action
        # LCM Type: geometry_msgs.Pose
        self.pose = pose
        # LCM Type: geometry_msgs.Vector3
        self.scale = scale
        # LCM Type: std_msgs.ColorRGBA
        self.color = color
        # LCM Type: std_msgs.Duration
        self.lifetime = lifetime
        # LCM Type: boolean
        self.frame_locked = frame_locked
        # LCM Type: geometry_msgs.Point[points_length]
        self.points = points
        # LCM Type: std_msgs.ColorRGBA[colors_length]
        self.colors = colors
        # LCM Type: string
        self.text = text
        # LCM Type: string
        self.mesh_resource = mesh_resource
        # LCM Type: boolean
        self.mesh_use_embedded_materials = mesh_use_embedded_materials

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

    def _encode_one(self, buf):
        buf.write(struct.pack(">ii", self.points_length, self.colors_length))
        assert (
            self.header._get_packed_fingerprint()
            == std_msgs.Header._get_packed_fingerprint()
        )
        self.header._encode_one(buf)
        __ns_encoded = self.ns.encode("utf-8")
        buf.write(struct.pack(">I", len(__ns_encoded) + 1))
        buf.write(__ns_encoded)
        buf.write(b"\0")
        buf.write(struct.pack(">iii", self.id, self.type, self.action))
        assert (
            self.pose._get_packed_fingerprint()
            == geometry_msgs.Pose._get_packed_fingerprint()
        )
        self.pose._encode_one(buf)
        assert (
            self.scale._get_packed_fingerprint()
            == geometry_msgs.Vector3._get_packed_fingerprint()
        )
        self.scale._encode_one(buf)
        assert (
            self.color._get_packed_fingerprint()
            == std_msgs.ColorRGBA._get_packed_fingerprint()
        )
        self.color._encode_one(buf)
        assert (
            self.lifetime._get_packed_fingerprint()
            == std_msgs.Duration._get_packed_fingerprint()
        )
        self.lifetime._encode_one(buf)
        buf.write(struct.pack(">b", self.frame_locked))
        for i0 in range(self.points_length):
            assert (
                self.points[i0]._get_packed_fingerprint()
                == geometry_msgs.Point._get_packed_fingerprint()
            )
            self.points[i0]._encode_one(buf)
        for i0 in range(self.colors_length):
            assert (
                self.colors[i0]._get_packed_fingerprint()
                == std_msgs.ColorRGBA._get_packed_fingerprint()
            )
            self.colors[i0]._encode_one(buf)
        __text_encoded = self.text.encode("utf-8")
        buf.write(struct.pack(">I", len(__text_encoded) + 1))
        buf.write(__text_encoded)
        buf.write(b"\0")
        __mesh_resource_encoded = self.mesh_resource.encode("utf-8")
        buf.write(struct.pack(">I", len(__mesh_resource_encoded) + 1))
        buf.write(__mesh_resource_encoded)
        buf.write(b"\0")
        buf.write(struct.pack(">b", self.mesh_use_embedded_materials))

    @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.points_length, self.colors_length = struct.unpack(">ii", buf.read(8))
        self.header = cls._get_field_type("header")._decode_one(buf)
        __ns_len = struct.unpack(">I", buf.read(4))[0]
        self.ns = buf.read(__ns_len)[:-1].decode("utf-8", "replace")
        self.id, self.type, self.action = struct.unpack(">iii", buf.read(12))
        self.pose = cls._get_field_type("pose")._decode_one(buf)
        self.scale = cls._get_field_type("scale")._decode_one(buf)
        self.color = cls._get_field_type("color")._decode_one(buf)
        self.lifetime = cls._get_field_type("lifetime")._decode_one(buf)
        self.frame_locked = bool(struct.unpack("b", buf.read(1))[0])
        self.points = []
        for i0 in range(self.points_length):
            self.points.append(cls._get_field_type("points")._decode_one(buf))
        self.colors = []
        for i0 in range(self.colors_length):
            self.colors.append(cls._get_field_type("colors")._decode_one(buf))
        __text_len = struct.unpack(">I", buf.read(4))[0]
        self.text = buf.read(__text_len)[:-1].decode("utf-8", "replace")
        __mesh_resource_len = struct.unpack(">I", buf.read(4))[0]
        self.mesh_resource = buf.read(__mesh_resource_len)[:-1].decode(
            "utf-8", "replace"
        )
        self.mesh_use_embedded_materials = 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 = (
            0x707E24D8BC038BD3
            + std_msgs.Header._get_hash_recursive(newparents)
            + geometry_msgs.Pose._get_hash_recursive(newparents)
            + geometry_msgs.Vector3._get_hash_recursive(newparents)
            + std_msgs.ColorRGBA._get_hash_recursive(newparents)
            + std_msgs.Duration._get_hash_recursive(newparents)
            + geometry_msgs.Point._get_hash_recursive(newparents)
            + std_msgs.ColorRGBA._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]
