------------------------
--[[UTIL Functions]]--
------------------------
--Global functions used by all classes are wrapped in UTIL
--deal with it.

local UTIL = {}
 
function UTIL.Class(tableIn,template)
        tableIn = tableIn or {}
        local mt = {
        __metatable = UTIL.DeepCopy(template);
        __index     = UTIL.DeepCopy(template);
        }
        return setmetatable(tableIn, mt)
end
function UTIL.MakeClass(...)
        local arg = {...}
        assert(#arg>0, 'ERROR: class needs 1 argument or more')
        local members = arg[1]
        for i=2,#arg,1 do
                if type(arg[i])=='table' then
                        for key,val in pairs(arg[i]) do
                                if not members[key] then
                                        members[key] = val
                                end
                        end
                end
        end
        local function New(init)
                return UTIL.Class(init or {},members)
        end
        local function Copy(obj, ...)
                local newobj = obj:New(unpack(arg))
                for n,v in pairs(obj) do newobj[n] = v end
                return newobj
        end
        members.New  = New
        members.Copy = Copy
        return mt
end
 
function UTIL.DeepCopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[UTIL.DeepCopy(orig_key)] = UTIL.DeepCopy(orig_value)
        end
        setmetatable(copy, UTIL.DeepCopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

function UTIL.Instantiate(guiType)
	return function(data)
		local obj = Instance.new(guiType)
		for k, v in pairs(data) do
			if type(k) == 'number' then
				v.Parent = obj
			else
				obj[k] = v
			end
		end
		return obj
	end
end 

function UTIL.RetroRegister(func,...)
	func()
	for _,i in ipairs({...}) do
		i:connect(func)
	end
end
