-- Purely for table returning functions.

local function OpenTable(inval)
	return Select(IsTableToBool(inval),inval,{})
end

local function OpenTableLocation(intbl,location)
	return OpenTable(intbl)[location]
end

local function RecursiveOpenTableLocation(intbl,location,...) 
        if NotNilToBool(location) then
                return RecursiveOpenTableLocation(OpenTableLocation(intbl,location),...)
        else
                return intbl
        end
end

local function ReplaceTableValue(intbl,value,location,nextval,...)
	if  NotNilToBool(nextval) then
		intbl[location] = ReplaceTableValue(OpenTable(OpenTableLocation(intbl,location)),value,nextval,...)
	elseif NotNilToBool(location) then
--		printnote("RTV    ReplaceTableValue " .. tostring(intbl),"<",value,"@",location)
		intbl[location] = value
	end
	return intbl
end

local function ConcatenateTables(intbl,intbl2,index)
--	printnote("CT     ConcatenateTables " .. tostring(intbl),intbl2,index)
	if NilToBool(index) then index = 1 end
	if NilToBool(intbl) then intbl = {} end
	if NotNilToBool(intbl2[index]) or NotNilToBool(intbl2[index+1]) then
		return ConcatenateTables(ReplaceTableValue(intbl,intbl2[index],ArgsLength(intbl)+1),intbl2,index+1)
	else
		return intbl
	end
end

local function RecursiveTableAdd(intbl,inval,...)
	if NotNilToBool(inval) then
		return RecursiveTableAdd(ReplaceTableValue(intbl,inval,(ArgsLength(TableUnpack(intbl)))+1),...)
	end
	return intbl
end

local function ApplyEntryToTable(intbl,inval,location,...)
	if NotNilToBool(location) then
		return ApplyEntryToTable(ReplaceTableValue(intbl,inval,ValueUnpack(location)),inval,...)
	else
		return intbl	
	end
end

local function ApplyEntriesToTable(intbl,commands,...)
--	printnote("RTVWV  ApplyEntriesToTable " .. tostring(intbl),commands,...)
	if NotNilToBool(commands) then
		return ApplyEntriesToTable(ApplyEntryToTable(intbl,TableUnpack(commands)),...)
	else
		return intbl
	end
end

local function ApplyTemplateToTable(intbl,valtbl)
--	printnote("RTVWVT ApplyTemplateToTable " .. tostring(intbl),valtbl)
	return ApplyEntriesToTable(intbl,TableUnpack(valtbl))
end

local function FillTemplate(count,intbl,inval,nextval,...)
	if NotNilToBool(inval) and NotNilToBool(count) then
		intbl = ReplaceTableValue(intbl,inval,count,1)
	end
	if NotNilToBool(nextval) then
		return FillTemplate(count+1,intbl,nextval,...)
	end
	return intbl
end

local function RecursiveDuplicateTable(intbl,outtbl,increment,maptbl)
	if IsTableToBool(intbl) then
		increment = MatchReplace(increment,1)
		outtbl = MatchReplace(outtbl,EmptyTable())
		maptbl = MatchReplace(maptbl,EmptyTable())
		maptbl[intbl] = MatchReplace(maptbl[intbl],outtbl)
		if NotNilToBool(intbl[increment]) or NotNilToBool(intbl[increment + 1]) then
			if IsTableToBool(intbl[increment]) then
				local duplicate
				if NilToBool(maptbl[intbl[increment] ]) then
					duplicate = RecursiveDuplicateTable(intbl[increment],nil,nil,maptbl)
					maptbl[intbl[increment] ] = duplicate
				else
					duplicate = maptbl[intbl[increment] ]
				end
				intbl[increment] = duplicate
			end
			return RecursiveDuplicateTable(intbl,ReplaceTableValue(outtbl,intbl[increment],increment),increment+1,maptbl)
		else
			return outtbl
		end
	else
		return EmptyTable()
	end
end

local function ValueToTable(inval)
	if NotToBool(IsTableToBool(inval)) then
		return {inval}
	end
	return inval
end

local function ValuePack(inval,with)
	if IsTableToBool(inval) then
		return RecursiveTableAdd(inval,with)
	elseif NilToBool(inval) then
		return with
	else
		return {inval,with}
	end
end

local function TableFold(intbl,snipstart,snipstop,start,stop)
	local outtbl = {}
	start = MatchReplace(start,1)
	stop = MatchReplace(stop,TableLength(intbl))
	snipstart = MatchReplace(snipstart,start-1)
	snipstop = MatchReplace(snipstop,snipstart)
	if snipstart > snipstop then
		snipstart,snipstop = SwitchVariables(snipstart,snipstop)
	end
	for i=start,stop do
		if i < snipstart or i > snipstop then
			outtbl[ArgsLength(TableUnpack(outtbl))+1] = intbl[i]
		end
	end
	return outtbl
end

local function RecursiveOpenTable(intbl,inval,...)
	intbl = OpenTable(intbl)
	if inval ~= nil then
		intbl[inval] = MatchReplace(intbl[inval],{})
		intbl[inval] = RecursiveOpenTable(intbl[inval],...)
	end
	return intbl
end

local function RecursiveMatchReplaceNumericTableValue(intbl,with,against,start,stop)
	start = MatchReplace(start,1)
	stop = MatchReplace(stop,TableLength(intbl))
	for i=start,stop do
		intbl[i] = MatchReplace(intbl[i],with,against)
		if IsTableToBool(intbl[i]) and intbl[i] ~= intbl and intbl[i] ~= with then
			intbl[i] = RecursiveMatchReplaceNumericTableValue(intbl[i],with,against)
		end
	end
	return intbl
end
