--[[	SlashHelp
	by SDPhantom
	http://www.phantomweb.org	]]
------------------------------------------

SlashHelp_MaxBtns=32;

SlashHelp_AutoCompleted=false;
SlashHelp_ListOffset=0;
SlashHelp_BtnArr={n=0};
SlashHelp_CurList={n=0};

function SlashHelp_FilterList(filter)
	local k,v;
	local emotelist={};
	local namelist={};
	local cmdlist={};
	for k,v in pairs(_G) do
		if type(v)=="string" and v:sub(1,1)=="/" then
			local ctype=k:match("^SLASH_(.-)%d+$");
			if not ctype then
				ctype=k:match("^EMOTE(%d+)_CMD%d+$");
			end

			if ctype then
				local id=string.format("%s_%s",ctype,v:match("^/(.+)"):upper());
				if
					not namelist[id]
				and	(filter==nil or v:sub(1,filter:len()):lower()==filter:lower())
				then
					local insert=false;
					local info={
						cmd=v
					,	sec=ctype
					,	color={0.5,0.5,0.5}
					};

					if k:sub(1,5)=="EMOTE" then
						insert=SlashHelpShowEmote:GetChecked();
						info.sec=(getglobal("EMOTE"..(tonumber(ctype) or 0).."_TOKEN") or "");
						info.color={0.75,0,0.5};
					elseif ChatTypeInfo[ctype] then
						insert=SlashHelpShowChat:GetChecked();
						info.color={0,0.75,0};
					elseif IsSecureCmd(v) then
						insert=SlashHelpShowCmdSecure:GetChecked();
						info.color={0.5,0.5,1};
					elseif SlashCmdList[ctype] then
						insert=SlashHelpShowCmdNormal:GetChecked();
						info.color={0.75,0.5,0};
					end

					if insert then
						--info.sec=k;
						namelist[id]=k;	-- No real purpose, just a marker to prevent duplicates
						cmdlist[(#cmdlist)+1]=info;
					end
				end
			end
		end
	end

	return cmdlist;
end

function SlashHelp_ArrayKeys(arr)
	local ret={};
	local i,j;
	for i,j in arr do
		ret[(#ret)+1]=i;
	end
	return ret;
end

function SlashHelp_SortComp(v1,v2)
	local v1len;
	local v2len;
	local i;

--	Group Sort
	if SlashHelpSortGroup:GetChecked() then
		v1len=v1.sec:len();
		v2len=v2.sec:len();
		for i=1,min(v1len,v2len) do
			local v1char=v1.sec:lower():byte(i);
			local v2char=v2.sec:lower():byte(i);
			if v1char~=v2char then
				return v1char<v2char;
			end
		end

		if v1len~=v2len then
			return v1len<v2len;
		end
	end

--	Alphabetical Sort
	v1len=v1.cmd:len();
	v2len=v2.cmd:len();
	for i=1,min(v1len,v2len) do
		local v1char=v1.cmd:lower():byte(i);
		local v2char=v2.cmd:lower():byte(i);
		if v1char~=v2char then
			return v1char<v2char;
		end
	end

	return v1len<v2len;
end

SlashHelp_LastText=""
function SlashHelp_OnUpdate()
	if ChatFrameEditBox:GetText()~=SlashHelp_LastVal then
		SlashHelp_CurList={};
		if string.sub(ChatFrameEditBox:GetText(),1,1)=="/" then
			SlashHelpOptionsFrame:Show();

			local cmdlist=SlashHelp_FilterList(ChatFrameEditBox:GetText());
			sort(cmdlist,SlashHelp_SortComp);

			if (#cmdlist)>0 then
				SlashHelpScrollFrame:Show();
			else
				SlashHelpScrollFrame:Hide();
			end
--[[
			if (#cmdlist)<=1 then
				if
					(#cmdlist)==1
				and	cmdlist[1].autocomplete
				and	string.len(SlashHelp_LastText)<string.len(ChatFrameEditBox:GetText())
				and	(
						not SlashHelp_AutoCompleted
					or	string.lower(string.sub(ChatFrameEditBox:GetText(),1,string.len(SlashHelp_LastText)))==SlashHelp_LastText
					)
				then
					local hstart=string.len(ChatFrameEditBox:GetText());
					local hend=string.len(cmdlist[1].cmd);

					SlashHelp_LastText=string.lower(ChatFrameEditBox:GetText());

					ChatFrameEditBox:SetText(cmdlist[1].cmd);
					ChatFrameEditBox:HighlightText(hstart,hend);

					SlashHelp_AutoCompleted=true;
				else
					SlashHelp_LastText=string.lower(ChatFrameEditBox:GetText());
					SlashHelp_AutoCompleted=false;
				end
			else
				SlashHelp_LastText=string.lower(ChatFrameEditBox:GetText());
				SlashHelp_AutoCompleted=false;
			end
--]]
			SlashHelp_CurList=cmdlist;
			SlashHelp_BuildList();
		else
			SlashHelpScrollFrame:Hide();
			SlashHelpOptionsFrame:Hide();
		end
		SlashHelp_ListOffset=0;

		SlashHelp_LastVal=ChatFrameEditBox:GetText();
	end

	if (#SlashHelp_CurList)>SlashHelp_MaxBtns then
		SlashHelpUpButton:Show();
		SlashHelpDownButton:Show();
		SlashHelpScrollFrame:SetHeight((12*(SlashHelp_MaxBtns+2))+10);

		if SlashHelpEntry1 then
			SlashHelpEntry1:SetPoint("TOPLEFT",SlashHelpScrollFrame,"TOPLEFT",8,-17);
		end
	else
		SlashHelpUpButton:Hide();
		SlashHelpDownButton:Hide();
		SlashHelpScrollFrame:SetHeight((12*(#SlashHelp_CurList))+16);

		if SlashHelpEntry1 then
			SlashHelpEntry1:SetPoint("TOPLEFT",SlashHelpScrollFrame,"TOPLEFT",8,-8);
		end
	end
end

function SlashHelp_BuildList()
	if SlashHelp_BtnArr.n<SlashHelp_MaxBtns then
		local i;
		for i=(#SlashHelp_BtnArr)+1,SlashHelp_MaxBtns do
			local btnobj=CreateFrame("Button","SlashHelpEntry"..i,SlashHelpScrollFrame,"SlashHelpEntryTemplate");
			local cmdobj=getglobal(btnobj:GetName().."CommandText");
			local secobj=getglobal(btnobj:GetName().."SectionText");

			btnobj:SetID(i);
			if i<=1 then
				btnobj:SetPoint("TOPLEFT",SlashHelpScrollFrame,"TOPLEFT",8,-17);
			else
				btnobj:SetPoint("TOPLEFT","SlashHelpEntry"..(i-1),"BOTTOMLEFT");
			end
			btnobj:SetPoint("RIGHT",SlashHelpScrollFrame,"RIGHT",-8,0);

			cmdobj:SetText("Test"..i);
			secobj:SetText("Test"..i);
--[
			SlashHelp_BtnArr[i]={
				btnobj=btnobj
			,	cmdobj=cmdobj
			,	secobj=secobj
			};
--]]
--[[
			btnobj:SetScript("OnClick",
				function(self)
					local idx=SlashHelp_ListOffset+self:GetID();

					if idx<=(#SlashHelp_CurList) then
						if SlashHelp_CurList[idx].autocomplete then
							SlashHelp_AutoCompleted=true;
							ChatFrameEditBox:SetText(SlashHelp_CurList[idx].cmd);
						else
							message("SlashHelp is unable to insert Secure Commands due to Blizzard's Security measures.");
						end
					end
				end
			);
--]]
			btnobj:SetScript("OnUpdate",
				function(self)
					local idx=SlashHelp_ListOffset+self:GetID();

					local cmdobj=getglobal(self:GetName().."CommandText");
					local secobj=getglobal(self:GetName().."SectionText");
					if idx<=(#SlashHelp_CurList) then
						self:SetAlpha(1);
						cmdobj:SetText(SlashHelp_CurList[idx].cmd);
						secobj:SetText(SlashHelp_CurList[idx].sec);

						cmdobj:SetTextColor(unpack(SlashHelp_CurList[idx].color));
						secobj:SetTextColor(unpack(SlashHelp_CurList[idx].color));
					else
						self:SetAlpha(0);
					end
				end
			);
		end
	end
end

CreateFrame("Frame","SlashHelpEventFrame");
SlashHelpEventFrame:SetScript("OnUpdate",SlashHelp_OnUpdate);

------------------------------------------
--[[	SlashHelp Scroll Functions	]]
------------------------------------------

function SlashHelp_Scroll(offset)
	if (#SlashHelp_CurList)-SlashHelp_MaxBtns>0 then
		SlashHelp_ListOffset=min(max(SlashHelp_ListOffset+offset,0),(#SlashHelp_CurList)-SlashHelp_MaxBtns);
	end
end

function SlashHelp_ScrollValidate(self,offset)
	local arrow=getglobal(self:GetName().."Arrow");
	local hlight=getglobal(self:GetName().."Highlight");

	if
		(SlashHelp_ListOffset+offset)<0
	or	(SlashHelp_ListOffset+offset)>((#SlashHelp_CurList)-SlashHelp_MaxBtns)
	then
		self.valid=nil;
		arrow:SetVertexColor(0.5,0.5,1);
		hlight:SetAlpha(0);
	else
		self.valid=1;
		arrow:SetVertexColor(1,1,1);
		hlight:SetAlpha(1);
	end
end
