from ctypes import Structure, c_char, c_int32, c_float, c_ubyte
from typing import Tuple


class StructureEq(Structure):
    def __eq__(self, other):
        for fld in self._fields_:
            if getattr(self, fld[0]) != getattr(other, fld[0]):
                return False
        return True

    def __ne__(self, other):
        for fld in self._fields_:
            if getattr(self, fld[0]) != getattr(other, fld[0]):
                return True
        return False


class Color(StructureEq):
    _fields_ = [
        ('r', c_ubyte),
        ('g', c_ubyte),
        ('b', c_ubyte),
        ('a', c_ubyte),
    ]

    def __iter__(self):
        yield self.r
        yield self.g
        yield self.b
        yield self.a

    def __eq__(self, other):
        return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a

    def __repr__(self):
        return repr(tuple(self))

    def normalized(self) -> Tuple:
        return (
            self.r / 255.0,
            self.g / 255.0,
            self.b / 255.0,
            self.a / 255.0
        )


class Vector2(StructureEq):
    _fields_ = [
        ('x', c_float),
        ('y', c_float),
    ]

    def __iter__(self):
        yield self.x
        yield self.y

    def __repr__(self):
        return repr(tuple(self))


class Vector3(StructureEq):
    _fields_ = [
        ('x', c_float),
        ('y', c_float),
        ('z', c_float),
    ]

    def __iter__(self):
        yield self.x
        yield self.y
        yield self.z

    def __repr__(self):
        return repr(tuple(self))

    @classmethod
    def zero(cls):
        return Vector3(0, 0, 0)


class Quaternion(StructureEq):
    _fields_ = [
        ('x', c_float),
        ('y', c_float),
        ('z', c_float),
        ('w', c_float),
    ]

    def __iter__(self):
        yield self.w
        yield self.x
        yield self.y
        yield self.z

    def __repr__(self):
        return repr(tuple(self))

    @classmethod
    def identity(cls):
        return Quaternion(0, 0, 0, 1)


class PsxBone(StructureEq):
    _fields_ = [
        ('name', c_char * 64),
        ('flags', c_int32),
        ('children_count', c_int32),
        ('parent_index', c_int32),
        ('rotation', Quaternion),
        ('location', Vector3),
        ('length', c_float),
        ('size', Vector3)
    ]


class Section(StructureEq):
    _fields_ = [
        ('name', c_char * 20),
        ('type_flags', c_int32),
        ('data_size', c_int32),
        ('data_count', c_int32)
    ]

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        self.type_flags = 1999801


__all__ = [
    'Color',
    'Vector2',
    'Vector3',
    'Quaternion',
    'PsxBone',
    'Section'
]

def __dir__():
    return __all__
