-- Define 'Vector2' class with shared methods and metamethods
--- @class Vector2
--- @field x number
--- @field y number
local Vector2 = {} -- Declare Vector2 as a local table first



--- Calculate the dot product of two vectors
--- @param v0 Vector2
--- @param v1 Vector2
--- @return number
Vector2.dot = function(v0, v1)
    return v0.x * v1.x + v0.y * v1.y
end

--- Calculate the add of two vectors
--- @param v0 Vector2
--- @param v1 Vector2
--- @return Vector2
Vector2.__add = function(v0, v1)
    return Vector2.new(v0.x + v1.x, v0.y + v1.y)
end


--- Calculate the sub of two vectors
--- @param v0 Vector2
--- @param v1 Vector2
--- @return Vector2
Vector2.__sub = function(v0, v1)
    return Vector2.new(v0.x - v1.x, v0.y - v1.y)
end

--- Calcuate the length of a vector2
--- @param v Vector2
--- @return number
Vector2.__len = function(v)
    return math.sqrt(v.x * v.x + v.y * v.y)
end


--- Vector2 to string
--- @param v Vector2
--- @return string
Vector2.__tostring = function(v)
    return string.format("Vector2(%g, %g)", v.x, v.y)
end

Vector2.add = function(self, other_vec)
    self.x = self.x + other_vec.x
    self.y = self.y + other_vec.y
    return self
end

Vector2.__index = Vector2 -- Enable shared methods via __index

--- Constructor
--- @param x number
--- @param y number
--- @return Vector2
function Vector2.new(x, y)
    return setmetatable(
        {x = x or 0, y = y or 0}, -- Initialize x and y with defaults
        Vector2 -- Assign metatable
    )
end

return Vector2 -- Return the Vector2 table