--------- ---------- ---------- ---------- ---------- 
-- Name: table.Inherit( Table, Base )
-- Desc: Copies any missing data from Base to Table
---------- ---------- ---------- ---------- ---------- 
function table.inherit( Table, Base )
	for k, v in pairs( Base ) do
		if ( Table[k] == nil ) then	Table[k] = v end
	end
	
	return Table
end

---------- ---------- ---------- ---------- ---------- 
-- Name: table.HasValue( Table, Value )
-- Desc: Checks if Table has value Value
---------- ---------- ---------- ---------- ---------- 
function table.hasValue( Table, Value )
	for k,v in pairs( Table ) do
		if ( v == Value ) then return true end
	end
	
	return false
end

function table.clear(t)
	for a, _ in pairs(t) do
		t[a] = nil
	end
end


---------- ---------- ---------- ---------- ---------- 
-- Name: table.Count( Table )
-- Desc: Returns the number of keys in a table
---------- ---------- ---------- ---------- ---------- 
function table.count( Table )
	local i = 0
	
	for k in pairs( Table ) do
		i = i + 1
	end
	
	return i
end


local defaultCheck = function(obj)
	return obj._remove == true
end

function table.removeListIf(tab, check, onRemove)
	local at, goal, check = 1, #tab, check or defaultCheck
	while at <= goal do
		local obj = tab[at]
		if check(obj) then
			table.remove(tab, at)
			if onRemove then
				onRemove(obj)
			end
			goal = goal -1
		else
			at = at +1
		end
	end
end

function table.removeCompletelyIf(tab, check)
	if #tab > 0 or next(tab) then
		local check = check or defaultCheck
		local removed = true
		local maxNums = #tab
		local numTries = 0
		while removed and numTries <= maxNums do
			removed = false
			numTries = numTries +1
			for index, obj in pairs(tab) do
				if check(obj) then
					table.remove(tab, index)
					removed = true
					break
				end
			end
		end
	end
end

function table.findUnique(tab)
	local unique = {}
	for index, check in pairs(tab) do
		local foundMatch = false
		for indexB, reallyUnique in pairs(unique) do
			if check == reallyUnique then
				foundMatch = true
				break
			end
		end
		if not foundMatch then
			table.insert(unique, check)
		end
	end
	return unique
end

function table.join(strings, del)
	local t = ""
	for index, str in ipairs(strings) do
		if string.len(t) > 0 then
			t = t..del
		end
		t = t..str
	end
	return t
end

function table.contains(tab, val)
	for index, v in pairs(tab) do
		if v == val then
			return true
		end
	end
	return false
end

function table.insertUnique(tab, obj, at)
	for index, val in pairs(tab) do
		if val == obj then
			return false
		end
	end	
	if at then
		table.insert(tab, at, obj)
	else
		table.insert(tab, obj)
	end
	return true
end

function table.removeUnique(tab, obj)
	for index, val in pairs(tab) do
		if val == obj then
			table.remove(tab, index)
			return true
		end
	end
	return false
end



function table.calculate_total_pool(pool)
	local total = 0
	for index, val in pairs(pool) do
		total = total + val
	end
	return total
end

function table.roll_pool(pool, total)
	local roll = math.random()*total
	for index, val in pairs(pool) do
		if roll > val then
			roll = roll - val
		else
			return index
		end
	end
end


local _shallow_copy
_shallow_copy = function(object, lookup_table)
	if type(object) ~= "table" then
		return object
	elseif lookup_table[object] then
		return lookup_table[object]
	end
	local new_table = {}
	lookup_table[object] = new_table
	for index, value in pairs(object) do
		if type(value) ~= "table" then
			new_table[_shallow_copy(index, lookup_table)] = _shallow_copy(value, lookup_table)
		else
			new_table[_shallow_copy(index, lookup_table)] = value
		end
	end
	return setmetatable(new_table, getmetatable(object))
end
local lookup_table = {}
function table.shallowCopy(object)
    local result = _shallow_copy(object, lookup_table)
	table.clear(lookup_table)
	return result
end