local function createSpacer(width)
	local label = WhatsNext.AceGUI:Create('Label');
	label:SetText(" ");
	if not width or width <= 0 then
		label:SetFullWidth(true)
	else
		label:SetWidth(width)
	end
	return label
end

local function createLabel(text)
	local label = WhatsNext.AceGUI:Create('Label');
	label:SetText(text .. ":");
	label:SetFont("Fonts\\FRIZQT__.TTF", 13, "")
	label:SetWidth(120)
	label.label:SetJustifyH("RIGHT")
	return label
end

WhatsNext.argumentTypes = {}

WhatsNext.argumentTypes["spell"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local text = WhatsNext.AceGUI:Create('EditBox-AutoComplete');
		text:SetWidth(300)
		text:DisableButton(true)
		text:SetLabel("")
		if not argument.suggestionList then
			text:SetValueList(SPELLAUTOCOMPLETE_LIST)
		elseif type(argument.suggestionList) =="function" then
			text:SetValueList(argument.suggestionList())
		else
			text:SetValueList(argument.suggestionList)
		end
		text:SetButtonCount(20);
		text:SetText(WhatsNext:GetSpellName(value))
		text:SetCallback("OnTextChanged", onChangeFunc)
		frame.text = text
		
		local label = WhatsNext.AceGUI:Create('Label');
		label:SetText("ID or Name. (|cFFFF0000Case Sensitive|r)");
		label:SetFont("Fonts\\FRIZQT__.TTF", 11, "")
		label:SetWidth(250)
		label.label:SetJustifyH("LEFT")
		
		frame:AddChild(text)
		frame:AddChild(createSpacer(5))
		frame:AddChild(label)
		return frame;
	end,
	["ExtractValue"] = function(frame)
		return WhatsNext:GetSpellID(frame.text:GetText()) or frame.text:GetText()
	end,
	["ToDisplayString"] = function(value,argument)
		return WhatsNext:GetSpellDisplay(value);
	end
}

WhatsNext.argumentTypes["item"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local text = WhatsNext.AceGUI:Create('EditBox-AutoComplete');
		text:SetWidth(300)
		text:DisableButton(true)
		text:SetLabel("")
		if not argument.suggestionList then
			text:SetValueList({})
		elseif type(argument.suggestionList) =="function" then
			text:SetValueList(argument.suggestionList())
		else
			text:SetValueList(argument.suggestionList)
		end
		text:SetButtonCount(20);
		text:SetText(select(1,GetItemInfo(value)) or value)
		text:SetCallback("OnTextChanged", onChangeFunc)
		frame.text = text
		
		local label = WhatsNext.AceGUI:Create('Label');
		label:SetText("ID or Name. (|cFFFF0000Case Sensitive|r)");
		label:SetFont("Fonts\\FRIZQT__.TTF", 11, "")
		label:SetWidth(250)
		label.label:SetJustifyH("LEFT")
		
		frame:AddChild(text)
		frame:AddChild(createSpacer(5))
		frame:AddChild(label)
		return frame;
	end,
	["ExtractValue"] = function(frame)
		return select(5, string.find(select(2, GetItemInfo(frame.text:GetText()) ) or "", "|?c?f?f?(%x*)|?H?([^:]*):?(%d+):?(%d*):?(%d*):?(%d*):?(%d*):?(%d*):?(%-?%d*):?(%-?%d*):?(%d*)|?h?%[?([^%[%]]*)%]?|?h?|?r?"))
	end,
	["ToDisplayString"] = function(value,argument)
		local name, link = GetItemInfo(value);
		return link or name or value
	end
}

WhatsNext.argumentTypes["percent"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local slider = WhatsNext.AceGUI:Create('Slider');
		slider:SetWidth(300)
		slider:SetIsPercent(true)
		slider:SetSliderValues(argument.min or 0,argument.max or 1,argument.increment or .01)
		slider:SetValue(value)
		slider:SetLabel("")
		slider:SetCallback("OnValueChanged", onChangeFunc)
		frame.slider = slider
		frame:AddChild(slider)
		return frame;
	end,
	["ExtractValue"] = function(frame)
		return frame.slider:GetValue();
	end,
	["ToDisplayString"] = function(value,argument)
		return value and tonumber(value) and ("|cFFFF6666" .. (value*100) .. "%%|r") or value
	end
}

WhatsNext.argumentTypes["integer"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local slider = WhatsNext.AceGUI:Create('Slider');
		slider:SetWidth(300)
		slider:SetIsPercent(false)
		slider:SetSliderValues(argument.min or 0,argument.max or 10000000,argument.increment or 1)
		slider:SetValue(value)
		slider:SetLabel("")
		slider:SetCallback("OnValueChanged", onChangeFunc)
		frame.slider = slider
		frame:AddChild(slider)
		return frame;
	end,
	["ExtractValue"] = function(frame)
		return frame.slider:GetValue();
	end,
	["ToDisplayString"] = function(value,argument)
		return value and tonumber(value) and ("|cFFFF6666" .. value .. "|r") or value
	end
}

WhatsNext.argumentTypes["text"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local text = WhatsNext.AceGUI:Create('EditBox-AutoComplete');
		text:SetWidth(555)
		text:DisableButton(true)
		text:SetLabel("")
		if not argument.suggestionList then
			text:SetValueList({})
		elseif type(argument.suggestionList) == "func" then
			text:SetValueList(argument.suggestionList())
		else
			text:SetValueList(argument.suggestionList)
		end
		text:SetButtonCount(20);
		text:SetText(value or "")
		text:SetCallback("OnTextChanged", onChangeFunc)
		
		frame.text = text
		frame:AddChild(text)
		return frame;
	end,
	["ExtractValue"] = function(frame)
		return frame.text:GetText();
	end,
	["ToDisplayString"] = function(value,argument)
		return value and ("|cFF7777FF" .. value .. "|r") or ""
	end
}

WhatsNext.argumentTypes["dropdown"] = {
	["CreateFrame"] = function(name,argument,value,onChangeFunc)
		local frame = WhatsNext.AceGUI:Create("SimpleGroup")
		frame:SetFullWidth(true)
		frame:SetLayout("Flow")
		frame.type = argument.type	
		frame:AddChild(createLabel(argument.label or name))
		frame:AddChild(createSpacer(5))

		local depth = 1
		local firstValue 
		local secondValue 
		local depth1List = {}
		for key,val in pairs(argument.possibleValues) do
			if not firstValue or val == value then
				firstValue = key
			end
			if type(val) == "table" then
				depth = 2
				depth1List[key] = key
				for key2,val2 in pairs(val) do
					if not secondValue then
						secondValue = val2
					end
					if key2 == value then
						firstValue = key
						secondValue = val2
					end
				end
			end
		end
		
		local dd1 = WhatsNext.AceGUI:Create("Dropdown")
		dd1:SetWidth(150)
		dd1:SetLabel("")
		dd1.possibleValues = argument.possibleValues
		frame.dd1 = dd1
		frame:AddChild(dd1)
		
		if depth == 2 then
			dd1:SetList(depth1List)
			dd1:SetValue(firstValue)
		
			local dd2 = WhatsNext.AceGUI:Create("Dropdown")
			dd2:SetWidth(250)
			dd2:SetLabel("")
			dd2:SetList(argument.possibleValues[firstValue])
			dd2:SetValue(secondValue)
			dd2:SetCallback("OnValueChanged", onChangeFunc)
			frame.dd2 = dd2
			dd1.dd2 = dd2
			frame:AddChild(dd2)
			
			dd1:SetCallback("OnValueChanged", function(dd,event,value) 
				dd.dd2:SetList(dd.possibleValues[value])
			
				for key2,val2 in pairs(dd.possibleValues[value]) do
					dd.dd2:SetValue(key2)
					do break end
				end
				
				onChangeFunc()
			end)
		else
			dd1:SetList(argument.possibleValues)
		end
		return frame;
	end,
	["ExtractValue"] = function(frame)
		if frame.dd2 then
			return frame.dd2:GetValue()
		else
			return frame.dd1:GetValue()
		end
	end,
	["ToDisplayString"] = function(value,argument)
		if argument.type == "unit" then
			return WhatsNext.allUnits[value] and ("|cFFFFF00F"..(WhatsNext.allUnits[value]).."|r") or value
		end
		return value and ("|cFF7777FF" .. value .. "|r") or ""
	end
}

WhatsNext.argumentTypes["unit"] = WhatsNext.argumentTypes["dropdown"]