import numpy as np
from konabot.plugins.marchtoy.texture import COLORS

class Formatter:
    @staticmethod
    def float4(m: np.ndarray) -> str:
        if m.shape != (4, 4):
            m = np.identity(4)
        v_0 = ", ".join([str(x) for x in m[:, 0]])
        v_1 = ", ".join([str(x) for x in m[:, 1]])
        v_2 = ", ".join([str(x) for x in m[:, 2]])
        v_3 = ", ".join([str(x) for x in m[:, 3]])
        return f"float4x4(float4({v_0}), float4({v_1}), float4({v_2}), float4({v_3}))"
    
    @staticmethod
    def vec4(m: np.ndarray) -> str:
        if m.shape != (4, 4):
            m = np.identity(4)
        v_0 = ", ".join([str(x) for x in m[:, 0]])
        v_1 = ", ".join([str(x) for x in m[:, 1]])
        v_2 = ", ".join([str(x) for x in m[:, 2]])
        v_3 = ", ".join([str(x) for x in m[:, 3]])
        return f"mat4(vec4({v_0}), vec4({v_1}), vec4({v_2}), vec4({v_3}))"

"""
TODO: 除零出现 nan 情况的单独处理
"""
class ArgParser:
    @staticmethod
    def as_float(args: list[str], default: float = 0.0) -> float:
        try:
            if len(args) >= 1:
                x = float(args[0])
                return x
        except:
            raise Exception(f"cannot parse {args}")
        return default

    @staticmethod
    def as_vec2(
        args: list[str], default: np.ndarray = np.array((0.0, 0.0))
    ) -> np.ndarray:
        try:
            if len(args) == 1:
                x = float(args[0])
                return np.array((x, x))
            elif len(args) == 2:
                x = float(args[0])
                y = float(args[1])
                return np.array((x, y))
        except:
            raise Exception(f"cannot parse {args}")
        return default

    @staticmethod
    def as_vec3(
        args: list[str], default: np.ndarray = np.array((0.0, 0.0, 0.0))
    ) -> np.ndarray:
        try:
            if len(args) == 1:
                x = float(args[0])
                return np.array((x, x, x))
            elif len(args) == 3:
                x = float(args[0])
                y = float(args[1])
                z = float(args[2])
                return np.array((x, y, z))
        except:
            raise Exception(f"cannot parse {args}")
        return default

    @staticmethod
    def as_vec4(
        args: list[str], default: np.ndarray = np.array((0.0, 0.0, 0.0, 0.0))
    ) -> np.ndarray:
        try:
            if len(args) == 1:
                x = float(args[0])
                return np.array((x, x, x, x))
            elif len(args) == 4:
                x = float(args[0])
                y = float(args[1])
                z = float(args[2])
                w = float(args[3])
                return np.array((x, y, z, w))
        except:
            raise Exception(f"cannot parse {args}")
        return default

    @staticmethod
    def as_literal_color(args: list[str], default=np.array((1.0, 1.0, 1.0, 1.0))):
        if len(args) == 1 and args[0] in COLORS:
            return np.array(COLORS[args[0]])
        return default
