module ecs_utils.math.vector;

struct vec2
{
    union
    {
        struct
        {
            float x;
            float y;
        }
        float[2] data;
    }

    vec2 opBinary(string op)(vec2 v)
    {
        static if (op == "+") return vec2(x + v.x, y + v.y);
        else static if (op == "-") return vec2(x - v.x, y - v.y);
        else static if (op == "*") return vec2(x * v.x, y * v.y);
        else static if (op == "/") return vec2(x / v.x, y / v.y);
        else static assert(0, "Operator "~op~" not implemented");
    }

    vec2 opBinary(string op)(float v)
    {
        static if (op == "+") return vec2(x + v, y + v);
        else static if (op == "-") return vec2(x - v, y - v);
        else static if (op == "*") return vec2(x * v, y * v);
        else static if (op == "/") return vec2(x / v, y / v);
        else static assert(0, "Operator "~op~" not implemented");
    }

    ivec2 opCast()
    {
        return ivec2(cast(int)x,cast(int)y);
    }

    void opOpAssign(string op)(vec2 v)
    {
        static if (op == "+")
        {
            x += v.x;
            y += v.y;
        }
        else static if (op == "-")
        {
            x -= v.x;
            y -= v.y;
        }
        else static if (op == "*")
        {
            x *= v.x;
            y *= v.y;
        }
        else static if (op == "/")
        {
            x /= v.x;
            y /= v.y;
        }
        else static assert(0, "Operator "~op~" not implemented");
    }
}

struct vec4
{
    union
    {
        struct
        {
            float x;
            float y;
            float z;
            float w;
        }
        float[4] data;
    }

    vec4 opBinary(string op)(float v)
    {
        static if (op == "+") return vec4(x + v, y + v, z + v, w + v);
        else static if (op == "-") return vec4(x - v, y - v, z - v, w - v);
        else static if (op == "*") return vec4(x * v, y * v, z * v, w * v);
        else static if (op == "/") return vec4(x / v, y / v, z / v, w / v);
        else static assert(0, "Operator "~op~" not implemented");
    }
}

struct ivec2
{
    union
    {
        struct
        {
            int x;
            int y;
        }
        int[2] data;
    }

    ivec2 opBinary(string op, T)(T v)
    {
        static if (op == "+") return ivec2(x + v, y + v);
        else static if (op == "-") return ivec2(x - v, y - v);
        else static if (op == "*") return ivec2(x * v, y * v);
        else static if (op == "/") return ivec2(x / v, y / v);
        else static assert(0, "Operator "~op~" not implemented");
    }

    vec2 opCast()
    {
        return vec2(x,y);
    }
}

struct ivec4
{
    union
    {
        struct
        {
            int x;
            int y;
            int z;
            int w;
        }
        int[4] data;
    }
}