-- lx-bundle:true

local Object = {}
Object.__index = Object

-- Default constructor hook for subclasses
-- Accept varargs so __call can forward constructor args without type errors
function Object:new(...) end

-- Creates a subclass that inherits metamethods and links to its super class
function Object:extend()
	local cls = {}
	for k, v in pairs(self) do
		if k:find("__") == 1 then
			cls[k] = v
		end
	end
	cls.__index = cls
	cls.super = self
	setmetatable(cls, self)
	return cls
end

-- Mixes in function members from one or more classes if not already defined
function Object:implement(...)
	for _, cls in pairs({ ... }) do
		for k, v in pairs(cls) do
			if self[k] == nil and type(v) == "function" then
				self[k] = v
			end
		end
	end
end

-- Returns true if this object inherits from the given class
function Object:is(T)
	local mt = getmetatable(self)
	while mt do
		if mt == T then
			return true
		end
		mt = getmetatable(mt)
	end
	return false
end

-- Returns a default printable name for object instances
function Object:__tostring()
	return "Object"
end

-- Instantiates an object and forwards arguments to its constructor
function Object:__call(...)
	local obj = setmetatable({}, self)
	obj:new(...)
	return obj
end

return Object
