local checks = {}
local checkResults = {}
local categories = {}
local temp,temp2 = {},{}
local checkTexts = {}

function WhatsNext:GetNumberDisplay(number)
	return number and tonumber(number) and ("|cFFFF6666" .. number .. "|r") or number
end

function WhatsNext:GetItemDisplay(itemName)
	local name, link = GetItemInfo(itemName);
	return link or name or itemName
end

function WhatsNext:GetStringDisplay(text)
	return text and ("|cFF7777FF" .. text .. "|r") or text
end

function WhatsNext:AddConditionalStatement(checkName,checkBlock)
	wipe(categories)
	checks[checkName] = checkBlock
end

function WhatsNext:RemoveConditionalStatement(checkName)
	wipe(categories)
	checks[checkName] = nil
end

function WhatsNext:ContainsConditionalStatement(checkName)
	return checks[checkName] ~= nil
end

function WhatsNext:GetConditionalStatement(checkName)
	return checks[checkName]
end

function WhatsNext:SetupTestChecks()
	wipe(checkTexts)
	WhatsNext:ResetTestChecks()
end

local _,x,y,check
function WhatsNext:ResetTestChecks()
	wipe(checkResults)
end

function WhatsNext:TestCheck(checkTable)
	if not checkResults[self:GetCheckText(checkTable)] then
		check = checks[checkTable.type]
		for arg,argTable in pairs(check.arguments) do
			if not checkTable[arg] then
				checkTable[arg] = argTable.default
			end
		end
		if checks[checkTable.type].test(checkTable) then
			checkResults[self:GetCheckText(checkTable)] = checkTable.invert and 0 or 1
		else
			checkResults[self:GetCheckText(checkTable)] = checkTable.invert and 1 or 0
		end
	end
	return checkResults[self:GetCheckText(checkTable)] == 1
end

function WhatsNext:TestChecks(checkList)
	if checkList then
		for i,checkTable in ipairs(checkList) do
			if not self:TestCheck(checkTable) then
				return false
			end
		end
	end
	return true
end

function WhatsNext:GetArguments(checkType)
	if checks[checkType] then
		return checks[checkType].arguments
	end
end

function WhatsNext:GetCleanCheckText(checkTable)
	return string.gsub(WhatsNext:GetCheckText(checkTable),"|c(........)(.-)|r",function(a,b)  
		if string.sub(b,1,1) == "|" then
			return "|c"..a..b.."|r"
		else
			return b;
		end
	end)
end

function WhatsNext:GetCheckText(checkTable)
	local check = checks[checkTable.type]
	if check then
		local text,varText = check.text,nil;
		if type(text) == "function" then
			return "";
		end
		for arg,argTable in pairs(check.arguments) do
			varText = WhatsNext.argumentTypes[argTable.type].ToDisplayString(checkTable[arg] or argTable.default,argTable)
			text = string.gsub(text,"{" .. arg .. "}",varText)
		end
		return (checkTable.invert and "Not if " or "If ") .. text
	end
	return ""
end

function WhatsNext:GetSampleCheckTexts(category)
	local temp = {}
	for checkType, check in pairs(checks) do
		if not category or category == check.category then
			temp[checkType] = self:GetSampleCheckText(checkType)
		end
	end
	return temp
end

function WhatsNext:GetCheckCategories()
	if #categories == 0 then
		for type, check in pairs(checks) do
			 if not tContains(categories,check.category) then
				tinsert(categories,check.category)
			 end
		end
		sort(categories,function(a,b)
			return a < b
		end)
	end
	return categories
end

function WhatsNext:GetSampleCheckText(checkType)
	local check = checks[checkType]
	if not check then
		return ""
	end
	local text,varText = check.text,nil;
	if type(text) == "function" then
		return "";
	end
	for var,varType in pairs(check.arguments) do
		varText = "|cFFFFF00F{"..(varType.label or var).."}|r"
		text = string.gsub(text,"{" .. var .. "}",varText)
	end
	return  "If " .. text
end

function WhatsNext:GetCheckCategory(checkName)
	return checks[checkName].category
end

function UnitBuffByID(unit,buffID)
	for i = 1,40 do
		local name, _, _, _, _, _, _, _, _, _, spellId = UnitBuff(unit, i) 
		if not name then
			return
		end
		if name and tonumber(spellId) == tonumber(buffID) then
			return UnitBuff(unit, i) 
		end
	end
end
