local VERSION = tonumber(("$Revision: 31397 $"):match("%d+"))

local QuestsFu = QuestsFu
local QuestsFu_Blizz = QuestsFu:NewModule("Blizz", "AceEvent-2.0", "AceHook-2.1", "AceConsole-2.0")
if QuestsFu.revision < VERSION then
	QuestsFu.version = "r" .. VERSION
	QuestsFu.revision = VERSION
	QuestsFu.date = ("$Date: 2007-03-30 12:06:49 -0400 (Fri, 30 Mar 2007) $"):match("%d%d%d%d%-%d%d%-%d%d")
end

local quixote = AceLibrary("Quixote-1.0")

local L = AceLibrary("AceLocale-2.2"):new("QuestsFu_Blizz")
L:RegisterTranslations("enUS", function() return {
	["Blizzard frames"] = true,
	["Improvements to the default UI"] = true,
	
	["Quest levels"] = true,
	["Show quest levels in the quest log and NPC dialogs"] = true,
	["Quest log"] = true,
	["Add levels to the quest log"] = true,
	["NPC dialogs"] = true,
	["Add levels to NPC dialogs"] = true,
	["LFG"] = true,
	["Add levels to quests in the LFG tool"] = true,
	
	["Double-width quest log"] = true,
	["Move the details frame from the bottom of the quest log to a new panel on its right side"] = true,
} end)

L:RegisterTranslations("deDE", function() return {
	["Blizzard frames"] = "Blizzard-Fenster",
	["Improvements to the default UI"] = "Verbesserungen für die Blizzard UI.",
	
	["Quest levels"] = "Quest-Level",
	["Show quest levels in the quest log and NPC dialogs"] = "Zeige die Questlevel im Quest-Log und bei NPC Dialogen",
	["Quest log"] = "Quest-Log",
	["Add levels to the quest log"] = "Levelangabe zum Quest-Log hinzufügen.",
	["NPC dialogs"] = "NPC Dialoge",
	["Add levels to NPC dialogs"] = "Levelangabe zu NPC Dialogen hinzufügen.",
	["LFG"] = "LFG",
	["Add levels to quests in the LFG tool"] = "Levelangabe bei der Suche Nach Gruppe Funktion hinzufügen.",
	
	["Double-width quest log"] = "Doppelte-Breite Questlog",
	["Move the details frame from the bottom of the quest log to a new panel on its right side"] = "Verschiebe das Quest Detail Fenster vom unteren Ende der Quest zu einem neuen Fenster auf der rechten Seite.",
} end)

L:RegisterTranslations("koKR", function() return {
	["Blizzard frames"] = "블리자드 프레임",
	--["Improvements to the default UI"] = true,
	["Show quest levels in the quest log and NPC dialogs"] = "퀘스트 로그와 NPC 대화시 퀘스트 레벨을 표시합니다.",
} end)

L:RegisterTranslations("zhTW", function() return {
	["Blizzard frames"] = "Blizzardé è¨­æ¡†",
	["Improvements to the default UI"] = "æ”¹å–„Blizzardé è¨­UI",
	
	["Quest levels"] = "ä»»å‹™ç­‰ç´š",
	["Show quest levels in the quest log and NPC dialogs"] = "åœ¨ä»»å‹™ç´€éŒ„å’ŒNPCå°è©±ä¸­é¡¯ç¤ºä»»å‹™ç­‰ç´š",
	["Quest log"] = "ä»»å‹™ç´€éŒ„",
	["Add levels to the quest log"] = "åœ¨ä»»å‹™ç´€éŒ„ä¸­é¡¯ç¤ºä»»å‹™ç­‰ç´š",
	["NPC dialogs"] = "NPCå°è©±",
	["Add levels to NPC dialogs"] = "åœ¨NPCå°è©±ä¸­é¡¯ç¤ºç­‰ç´š",
	["LFG"] = "æ‰¾éšŠå¹«æ‰‹",
	["Add levels to quests in the LFG tool"] = "åœ¨æ‰¾éšŠå¹«æ‰‹ä¸­é¡¯ç¤ºä»»å‹™ç­‰ç´š",
	
	["Double-width quest log"] = "åŠ å¯¬ä»»å‹™ç´€éŒ„",
	["Move the details frame from the bottom of the quest log to a new panel on its right side"] = "å°‡ä»»å‹™è©³è¿°å¾žä»»å‹™ç´€éŒ„æ¡†æž¶åº•éƒ¨ç§»åˆ°åŽŸæœ¬æ¡†æž¶çš„å³é‚Š",
} end)

function QuestsFu_Blizz:OnInitialize()
	self.db = QuestsFu:AcquireDBNamespace("Blizz")
	QuestsFu:RegisterDefaults("Blizz", "profile", {
		levels = {
			log = true,
			dialog = true,
			lfg = true,
		},
		doublewide = true,
	})
	QuestsFu.options.args.Blizz = {
		name = L["Blizzard frames"],
		desc = L["Improvements to the default UI"],
		type = "group",
		args = {
			levels = {
				name = L["Quest levels"],
				desc = L["Show quest levels in the quest log and NPC dialogs"],
				type = 'group',
				args = {
					log = {
						name = L["Quest log"],
						desc = L["Add levels to the quest log"],
						type = 'toggle',
						get = function() return self.db.profile.levels.log end,
						set = function(t)
							self.db.profile.levels.log = t
							self:UpdateLevelsHooks()
						end,
					},
					dialog = {
						name = L["NPC dialogs"],
						desc = L["Add levels to NPC dialogs"],
						type = 'toggle',
						get = function() return self.db.profile.levels.dialog end,
						set = function(t)
							self.db.profile.levels.dialog = t
							self:UpdateLevelsHooks()
						end,
					},
					lfg = {
						name = L["LFG"],
						desc = L["Add levels to quests in the LFG tool"],
						type = 'toggle',
						get = function() return self.db.profile.levels.lfg end,
						set = function(t)
							self.db.profile.levels.lfg = t
							self:UpdateLevelsHooks()
						end,
						disabled = true,
					},
				},
			},
			doublewide = {
				name = L["Double-width quest log"],
				desc = L["Move the details frame from the bottom of the quest log to a new panel on its right side"],
				type = 'toggle',
				get = function() return self.db.profile.doublewide end,
				set = function(t) self.db.profile.doublewide = t end,
				disabled = true,
			},
			toggle = {
				name = AceLibrary("AceLocale-2.2"):new("QuestsFu")["Enabled"],
				desc = AceLibrary("AceLocale-2.2"):new("QuestsFu")["Suspend/resume this module."],
				type = 'toggle',
				order = -1,
				get = function() return QuestsFu:IsModuleActive(self) end,
				set = function() QuestsFu:ToggleModuleActive(self) end,
			},
		},
	}
end

function QuestsFu_Blizz:OnEnable()
	self:UpdateLevelsHooks()
end

function QuestsFu_Blizz:UpdateLevelsHooks()
	-- In quest log
	if self.db.profile.levels.log then
		if not self:IsHooked("QuestLog_Update") then
			self:SecureHook("QuestLog_Update")
		end
	else
		if self:IsHooked("QuestLog_Update") then
			self:Unhook("QuestLog_Update")
		end
	end
	-- In dialogs
	if self.db.profile.levels.dialog then
		if not self:IsEventRegistered("GOSSIP_SHOW") then
			self:RegisterEvent("GOSSIP_SHOW")
			self:RegisterEvent("QUEST_GREETING")
		end
	else
		if self:IsEventRegistered("GOSSIP_SHOW") then
			self:UnregisterEvent("GOSSIP_SHOW")
			self:UnregisterEvent("QUEST_GREETING")
		end
	end
	--[[
	-- In lfg
	if self.db.profile.levels.log then
		if not self:IsHooked("GetLFGTypeEntries") then
			self:Hook("GetLFGTypeEntries", true)
		end
	else
		if self:IsHooked("GetLFGTypeEntries") then
			self:Unhook("GetLFGTypeEntries")
		end
	end
	--]]
end

----------------------------------------------------
-- Add quest levels to the quest log
----------------------------------------------------

function QuestsFu_Blizz:QuestLog_Update()
	--This is fragile, but lets us ignore event sequencing.  It'll break if anyone is meddling with the output of GetQuestLogTitle.
	--(questIndexes can change on every QUEST_LOG_UPDATE; this *will* be called before Quixote updates from that event, because Quixote is
	--throttling to avoid crashing the client on edge cases. I blame Blizzard for it being possible to crash the game by scanning the quest log. So.)
	for i = 1, QUESTS_DISPLAYED, 1 do
		--local questIndex = i + FauxScrollFrame_GetOffset(QuestLogListScrollFrame)
		local titleLine = _G["QuestLogTitle"..i]
		if titleLine and titleLine:GetText() then
			local title, level, tag = quixote:GetQuest(titleLine:GetText():trim())
			if title then
				titleLine:SetText(QuestsFu:MakeTag(level, tag)..title)
				local check = _G["QuestLogTitle" .. i .. "Check"]
				if check:IsVisible() then
					check:SetPoint("LEFT", titleLine, "LEFT", QuestLogDummyText:GetWidth() + 24, 0)
				end
			end
		end
	end
end

----------------------------------------------------
-- Add quest levels to LFG
----------------------------------------------------

--[[
-- Fuck you, Blizzard. ~vhaarr
function QuestsFu_Blizz:GetLFGTypeEntries(index)
	if index and tonumber(index) then
		index = tonumber(index)
		local original = {self.hooks["GetLFGTypeEntries"](index)}
		for i, v in ipairs(original) do
			if index == 2 or index == 3 or index == 5 then
				if (index == 5 and tourist:IsZone(v)) or tourist:IsInstance(v) then
					local low, high = tourist:GetLevel(v)
					if low and high then
						original[i] = v .. " ("..tostring(low).."-"..tostring(high)..")"
					end
				end
			elseif index == 4 then
				local _, level = quixote:GetQuestByName(v)
				if level and tonumber(level) then
					original[i] = "["..tostring(level).."] "..v
				end
			end
		end
		return unpack(original)
	end
	return self.hooks["GetLFGTypeEntries"](index)
end
]]

----------------------------------------------------
-- Add quest levels to NPC dialog when possible
----------------------------------------------------

--This is pretty much how Minimalist does it, which it credits to AutoSelect.
function QuestsFu_Blizz:GOSSIP_SHOW()
	local buttonindex = 1
	local list, button
	if GetGossipAvailableQuests() then
		list = {GetGossipAvailableQuests()}
		for i = 2,getn(list),2 do
			button = _G["GossipTitleButton"..buttonindex]
			button:SetText(format('[%d] %s',list[i],list[i-1]))
			buttonindex = buttonindex + 1
		end
		buttonindex = buttonindex + 1
		for k in pairs(list) do
			list[k] = nil
		end
	end
	if GetGossipActiveQuests() then
		list = {GetGossipActiveQuests()}
		for i = 2,getn(list),2 do
			button = _G["GossipTitleButton"..buttonindex]
			button:SetText(format('[%d] %s',list[i],list[i-1]))
			buttonindex = buttonindex + 1
		end
		for k in pairs(list) do
			list[k] = nil
		end
	end
end

--This is pretty much how Minimalist does it, which it credits to AutoSelect.
function QuestsFu_Blizz:QUEST_GREETING()
	local numactive,numavailable = GetNumActiveQuests(), GetNumAvailableQuests()
	local title, level, button
	local o,GetTitle,GetLevel = 0,GetActiveTitle,GetActiveLevel
	for i=1, numactive + numavailable do
		if i == numactive + 1 then
			o,GetTitle,GetLevel = numactive,GetAvailableTitle,GetAvailableLevel
		end
		title,level = GetTitle(i-o), GetLevel(i-o)
		button = _G["QuestTitleButton"..i]
		button:SetText(format('[%d] %s',level,title))
	end
end
