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

local QuestsFu = QuestsFu
local QuestsFu_Tracker = QuestsFu:NewModule("Tracker", "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 07:58:47 -0400 (Fri, 30 Mar 2007) $"):match("%d%d%d%d%-%d%d%-%d%d")
end

local tablet = AceLibrary("Tablet-2.0")
local quixote = AceLibrary("Quixote-1.0")
local dewdrop = AceLibrary("Dewdrop-2.0")

local L = AceLibrary("AceLocale-2.2"):new("QuestsFu_Tracker")
L:RegisterTranslations("enUS", function() return {
	["Tracker"] = true,
	["Autowatch"] = true,
	["Automatically add quests to the tracker when appropriate"] = true,
	["Use own tracker"] = true,
	["Replace the default quest tracker with a slightly more featureful one."] = true,
	["Login"] = true,
	["Re-add quests you were watching before you logged out"] = true,
	["Zone"] = true,
	["Add quests to the tracker when you enter their zone"] = true,
	["Subzone"] = true,
	["Add quests to the tracker when you enter their subzone"] = true,
	["Gained"] = true,
	["Add quests to the tracker when they are first gained"] = true,
	["Progress"] = true,
	["Add quests to the tracker when you make progress on them"] = true,
	["Remove completed"] = true,
	["Remove quests from the tracker when you complete their objectives"] = true,
} end)

L:RegisterTranslations("deDE", function() return {
	["Tracker"] = "Questüberwachung",
	["Autowatch"] = "Autoüberwachen",
	["Automatically add quests to the tracker when appropriate"] = "Automatisch ein Quest zur Questüberwachung hinzufügen wenn genug Platz ist.",
	["Use own tracker"] = "Benutze eigenes Questdetail Fenster",
	["Replace the default quest tracker with a slightly more featureful one."] = "Zeigt die Questdeatils in dem erweiterten Fenster von QuestFu.",
	["Login"] = "Login",
	["Re-add quests you were watching before you logged out"] = "Wieder hinzufügen von Quest die Überwacht wurden bevor du ausgeloggt bist.",
	["Zone"] = "Zone",
	["Add quests to the tracker when you enter their zone"] = "Quests zur Questüberwachung hinzufügen wenn du die Questzone betrittst.",
	["Subzone"] = "Unterzone",
	["Add quests to the tracker when you enter their subzone"] = "Quests zur Questüberwachung hinzufügen wenn du die Unterzone betrittst.",
	["Gained"] = "Bei Erhalt",
	["Add quests to the tracker when they are first gained"] = "Quest zu Questüberwachung hinzufügen bei erhalt der Quest.",
	["Progress"] = "Bei Fortschritt",
	["Add quests to the tracker when you make progress on them"] = "Quest zu Questüberwachung hinzufügen bei Fortschritt in der Quest.",
	["Remove completed"] = "Entferne Vollendet",
	["Remove quests from the tracker when you complete their objectives"] = "Entferne Quest aus der Questüberwachung, wenn ihre Quest-Ziele vollendet wurden.",
} end)

L:RegisterTranslations("koKR", function() return {
	["Tracker"] = "트래커",
	["Autowatch"] = "퀘스트 알림이 자동 추가",
	["Automatically add quests to the tracker when appropriate"] = "퀘스트 진행상황이 있을 경우 퀘스트 알림이에 자동으로 추가합니다.",
	["Use own tracker"] = "트래커 사용",
	["Replace the default quest tracker with a slightly more featureful one."] = "기본 퀘스트 트래커를 좀더 강화된 기능을 하는 것으로 대체합니다.",
	["Login"] = "로그인",
	["Re-add quests you were watching before you logged out"] = "로그아웃 하기전에 보고 있었던 퀘스트를 다시 추가합니다.",  -- 체크
	["Zone"] = "지역",
	["Add quests to the tracker when you enter their zone"] = "해당 지역에 도착했을 경우 자동으로 퀘스트 알림이에 추가합니다.",
	["Subzone"] = "세부 지역",
	["Add quests to the tracker when you enter their subzone"] = "해당 세부 지역에 도착했을 경우 자동으로 퀘스트 알림이에 추가합니다.",
	["Gained"] = "획득",
	["Add quests to the tracker when they are first gained"] = "퀘스트 아이템을 획득할 경우 자동으로 퀘스트 알림이에 추가합니다.",
	["Progress"] = "진행 상황",
	["Add quests to the tracker when you make progress on them"] = "진행 상황이 있을 경우 자동으로 퀘스트 알림이에 추가합니다.",
	["Remove completed"] = "완료시 제거",
	["Remove quests from the tracker when you complete their objectives"] = "목표를 모두 획득할 경우 퀘스트 트래커에서 제거합니다.",
} end)

L:RegisterTranslations("zhTW", function() return {
	["Tracker"] = "追蹤框架",
	["Autowatch"] = "自動追蹤任務",
	["Automatically add quests to the tracker when appropriate"] = "自動將適當任務增加到追蹤欄位中",
	["Use own tracker"] = "使用自訂框架",
	["Replace the default quest tracker with a slightly more featureful one."] = "使用自訂的追蹤框架取代原始追蹤框架",
	["Login"] = "登入",
	["Re-add quests you were watching before you logged out"] = "自動追蹤上次登出時追蹤的任務",
	["Zone"] = "區域",
	["Add quests to the tracker when you enter their zone"] = "自動追蹤所在區域的任務",
	["Subzone"] = "子區",
	["Add quests to the tracker when you enter their subzone"] = "自動追蹤所在子區的任務",
	["Gained"] = "取得",
	["Add quests to the tracker when they are first gained"] = "自動追蹤剛取得的任務",
	["Progress"] = "進度",
	["Add quests to the tracker when you make progress on them"] = "自動追蹤正在執行進度的任務",
	["Remove completed"] = "移除已完成",
	["Remove quests from the tracker when you complete their objectives"] = "自動移除已完成所有目標的任務",
} end)

function QuestsFu_Tracker:OnInitialize()
	self.db = QuestsFu:AcquireDBNamespace("Tracker")
	QuestsFu:RegisterDefaults("Tracker", "profile", {
		login = true,
		zone = false,
		subzone = true,
		gained = false,
		progress = true,
		removeCompleted = false,
		useOwnTracker = true,
		data = {
			fontSizePercent=0.7, detached=true, transparency=0, 
		},
		strata = 'HIGH',
	})
	QuestsFu:RegisterDefaults("Tracker", "char", {
		watchedQuests = {},
		autowatched = {},
	})
	QuestsFu.options.args.Tracker = {
		name = L["Tracker"],
		desc = L["Replace the default quest tracker with a slightly more featureful one."],
		type = "group",
		args = {
			auto = {
				name = L["Autowatch"],
				desc = L["Automatically add quests to the tracker when appropriate"],
				type = "group",
				args = {
					login = {
						type = "toggle", name = L["Login"],
						desc = L["Re-add quests you were watching before you logged out"],
						get = function() return self.db.profile.login end,
						set = function(t) self.db.profile.login = t end,
					},
					zone = {
						type = "toggle", name = L["Zone"],
						desc = L["Add quests to the tracker when you enter their zone"],
						get = function() return self.db.profile.zone end,
						set = function(t) self.db.profile.zone = t end,
					},
					subzone = {
						type = "toggle", name = L["Subzone"],
						desc = L["Add quests to the tracker when you enter their subzone"],
						get = function() return self.db.profile.subzone end,
						set = function(t) self.db.profile.subzone = t end,
					},
					progress = {
						type = "toggle", name = L["Progress"],
						desc = L["Add quests to the tracker when you make progress on them"],
						get = function() return self.db.profile.progress end,
						set = function(t) self.db.profile.progress = t end,
					},
					gained = {
						type = "toggle", name = L["Gained"],
						desc = L["Add quests to the tracker when they are first gained"],
						get = function() return self.db.profile.gained end,
						set = function(t) self.db.profile.gained = t end,
					},
					removeCompleted = {
						type = "toggle", name = L["Remove completed"],
						desc = L["Remove quests from the tracker when you complete their objectives"],
						get = function() return self.db.profile.removeCompleted end,
						set = function(t) self.db.profile.removeCompleted = t end,
					},
				},
			},
			own = {
				type = 'toggle', name = L["Use own tracker"],
				desc = L["Replace the default quest tracker with a slightly more featureful one."],
				get = function() return self.db.profile.useOwnTracker end,
				set = function(t)
					self.db.profile.useOwnTracker = t
					if self.db.profile.useOwnTracker then
						if tablet:IsRegistered('QuestsFu_Tracker') then tablet:Open('QuestsFu_Tracker') end
						self:UpdateTracker()
					else tablet:Close('QuestsFu_Tracker'); QuestWatchFrame:Show() end
				end,
			},
			strata = {
				name=AceLibrary("AceLocale-2.2"):new("QuestsFu")["Strata"], type="text", desc=AceLibrary("AceLocale-2.2"):new("QuestsFu")["Adjust the strata of this panel (takes effect after you reload your UI)"],
				get=function() return self.db.profile.strata end,
				set=function(t) self.db.profile.strata = t end,
				validate={'BACKGROUND', 'LOW', 'MEDIUM', 'HIGH', },
				order = 1,
			},
			--This one will look a little weird on the tablet right-click menu, as it'll be duplicating native functionality.  But it's totally worth it to stop people complaining.
			lock = {
				type = 'toggle', name = AceLibrary("AceLocale-2.2"):new("QuestsFu")["Lock"],
				desc = AceLibrary("AceLocale-2.2"):new("QuestsFu")["Lock or unlock this panel"],
				disabled = function() return not tablet:IsRegistered("QuestsFu_Tracker") end,
				get = function() return tablet:IsRegistered("QuestsFu_Tracker") and tablet:IsLocked("QuestsFu_Tracker") end,
				set = function() tablet:ToggleLocked("QuestsFu_Tracker") end,
				order = 1,
			},
			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()
					if tablet:IsRegistered('QuestsFu_Tracker') then tablet:Close('QuestsFu_Tracker'); QuestWatchFrame:Show() end
					QuestsFu:ToggleModuleActive(self)
				end
			},
		},
	}
end

function QuestsFu_Tracker:OnEnable()
	if quixote.firstScanDone then
		self:SecureHook("AddQuestWatch")
		self:SecureHook("RemoveQuestWatch")
		self:RegisterEvent("MINIMAP_ZONE_CHANGED", "OnZoneChange")
		self:RegisterEvent("ZONE_CHANGED", "OnZoneChange")
		self:RegisterEvent("ZONE_CHANGED_INDOORS", "OnZoneChange")
		self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "OnZoneChange")
		self:RegisterEvent("Quixote_Leaderboard_Update")
		self:RegisterEvent("Quixote_Quest_Gained")
		self:RegisterEvent("Quixote_Quest_Complete")
		self:RegisterEvent("Quixote_Quest_Lost")
		self:Hook(QuestsFu, "ToggleQuestWatch")
		self:Hook(QuestsFu, "IsWatched")
		
		self:SecureHook("QuestWatch_Update", "UpdateTracker")
		self:RegisterEvent("Quixote_Update", "UpdateTracker")
		self:RegisterEvent("Quixote_Party_Quest_Sync", "UpdateTracker")
		self:RegisterEvent("Quixote_Party_Quest_Gained", "UpdateTracker")
		self:RegisterEvent("Quixote_Party_Quest_Lost", "UpdateTracker")
		self:RegisterEvent("Quixote_Party_Leaderboard_Update", "UpdateTracker")

		
		--Check various bits of saved info for continuing validity
		for i,name in pairs(self.db.char.autowatched) do
			if not quixote:GetQuest(name) then
				self.db.char.autowatched[i] = nil
			end
		end
		for name in pairs(self.db.char.watchedQuests) do
			if not quixote:GetQuest(name) then
				self.db.char.watchedQuests[name] = nil
			end
		end
		self:LoadWatchedQuests()
		self:OnZoneChange()
		
		self.oldMAX_WATCHABLE_QUESTS = MAX_WATCHABLE_QUESTS
		MAX_WATCHABLE_QUESTS = 50
	else
		self:RegisterEvent("Quixote_Ready", function() self:OnEnable() end, true)
	end
end

function QuestsFu_Tracker:OnDisable()
	MAX_WATCHABLE_QUESTS = self.oldMAX_WATCHABLE_QUESTS
	tablet:Unregister('QuestsFu_Tracker')
end

--- Make other QuestsFu modules deal with this ---

function QuestsFu_Tracker:ToggleQuestWatch(object, questid)
	if self.db.profile.useOwnTracker then
		local questName = quixote:GetQuestById(questid)
		if self.db.char.watchedQuests[questName] then
			self.db.char.watchedQuests[questName] = nil
		else
			self.db.char.watchedQuests[questName] = true
		end
		self:UpdateTracker()
	else
		return self.hooks[object].ToggleQuestWatch(object)
	end
end

function QuestsFu_Tracker:IsWatched(questid)
	if type(questid) == 'number' then
		--need the name
		questid = quixote:GetQuestById(questid)
	end
	return self.db.char.watchedQuests[questName]
	--not calling of the hook
end

--- Quest watching ---

function QuestsFu_Tracker:LoadWatchedQuests()
	if self.db.profile.useOwnTracker then
		self:UpdateTracker()
	else
		if not (GetNumQuestWatches() > 0) then
			for questName in pairs(self.db.char.watchedQuests) do
				local questId = quixote:GetQuestByName(questName)
				if questId then
					AddQuestWatch(questId)
				else
					self.db.char.watchedQuests[questName] = nil
				end
			end
		end
		QuestWatch_Update()
	end
	self.loadedWatchedQuests = true
end

function QuestsFu_Tracker:SaveWatchedQuests()
	if self.db.profile.useOwnTracker then
		self:UpdateTracker()
	else
		if self.loadedWatchedQuests then
			for k in pairs(self.db.char.watchedQuests) do
				self.db.char.watchedQuests[k] = nil
			end
			for i = 1, GetNumQuestWatches() do
				local questName = quixote:GetQuestById(GetQuestIndexForWatch(i))
				if questName then self.db.char.watchedQuests[questName] = true end
			end
		end
	end
end

function QuestsFu_Tracker:AddQuestWatch(questid)
--	if self.db.profile.useOwnTracker then
		local questName = quixote:GetQuestById(questid)
		if questName then
			self.db.char.watchedQuests[questName] = true
		end
--	end
--	self:SaveWatchedQuests()
	QuestWatchFrame:Hide()
end

function QuestsFu_Tracker:RemoveQuestWatch(questid)
--	if self.db.profile.useOwnTracker then
		local questName = quixote:GetQuestById(questid)
		if questName then
			self.db.char.watchedQuests[questName] = nil
		end
--	end
--	self:SaveWatchedQuests()
end

function QuestsFu_Tracker:Quixote_Quest_Lost(name, id)
	if self.db.profile.useOwnTracker then
		self.db.char.watchedQuests[name] = nil
	end
	if #self.db.char.autowatched > 0 then
		for i,n in pairs(self.db.char.autowatched) do
			if n == name then
				table.remove(self.db.char.autowatched, i)
				break
			end
		end
	end
	if self.db.profile.rememberQuestgiver then
		self.db.char.questgivers[name] = nil
	end
end

function QuestsFu_Tracker:OnZoneChange()
	if not (self.db.profile.zone or self.db.profile.subzone) then return end
	if UnitIsDeadOrGhost('player') then return end
	local zone = GetRealZoneText()
	local subzone = GetSubZoneText()
	--Get rid of Trackered quests
	for i, name in pairs(self.db.char.autowatched) do
		local questid = select(8, quixote:GetQuestByName(name))
		RemoveQuestWatch(questid)
		self.db.char.autowatched[i] = nil
	end
	for _, questid in quixote:QuestsByZone(zone) do
		local name = quixote:GetQuestById(questid)
		-- If we're already watching it, don't Tracker.  (This way it won't be de-watched when we leave the zone.)
		if not self.db.char.watchedQuests[name] then
			if self.db.profile.zone then
				table.insert(self.db.char.autowatched, name)
				AddQuestWatch(questid)
			elseif self.db.profile.subzone and subzone ~= "" then
				local objective, description = quixote:GetQuestText(questid)
				if string.find(objective, subzone, 1, true) or string.find(description, subzone, 1, true) then
					table.insert(self.db.char.autowatched, name)
					AddQuestWatch(questid)
				end
			end
		end
	end
end

function QuestsFu_Tracker:Quixote_Leaderboard_Update(name, id, lid, desc, numHad, numGot, numNeeded)
	if AUTO_QUEST_WATCH=="0" and self.db.profile.progress then
		AddQuestWatch(id)
	end
end

function QuestsFu_Tracker:Quixote_Quest_Gained(name, id)
	if self.db.profile.gained then
		AddQuestWatch(id)
	end
	if self.db.profile.zone then
		local zone = GetRealZoneText()
		local questzone = select(7, quixote:GetQuestById(id))
		if zone == questzone then
			AddQuestWatch(id)
		end
	elseif self.db.profile.subzone then
		local subzone = GetSubZoneText()
		local objective, description = quixote:GetQuestText(id)
		if subzone ~= "" and (string.find(objective, subzone, 1, true) or string.find(description, subzone, 1, true)) then
			table.insert(self.db.char.autowatched, name)
			AddQuestWatch(id)
		end
	end
end

function QuestsFu_Tracker:Quixote_Quest_Complete(name, id)
	if self.db.profile.removeCompleted then
		RemoveQuestWatch(id)
	end
end

--- Tracker ---

function QuestsFu_Tracker:UpdateTracker()
	if self.db.profile.useOwnTracker then
		local trackerOrder = {}
		if not tablet:IsRegistered('QuestsFu_Tracker') then
			local function tableCleaner(t)
				--Nil out the table and any other tables nested within it
				for k in pairs(t) do
					if type(t[k]) == 'table' then
						tableCleaner(t[k])
					end
					t[k] = nil
				end
			end
			local function sortQuestsByLevel(a, b)
				local level_a = select(2, quixote:GetQuestByName(a))
				local level_b = select(2, quixote:GetQuestByName(b))
				if level_a == level_b then
					return a < b
				else
					return level_a < level_b
				end
			end
			tablet:Register('QuestsFu_Tracker', 'detachedData', self.db.profile.data, 'cantAttach', true, 'dontHook', true,
				'hideWhenEmpty', true, 'strata', self.db.profile.strata,
				'menu', function() dewdrop:FeedAceOptionsTable(QuestsFu.options.args.Tracker) end,
				'children', function()
					--Sort the quests:
					for questName in pairs(self.db.char.watchedQuests) do
						table.insert(trackerOrder, questName)
					end
					table.sort(trackerOrder, sortQuestsByLevel)
					--Display them:
					tablet:SetTitle("Tracker")
					local cat = tablet:AddCategory('columns', 2, 'child_func', QuestsFu.QuestClick, 'child_arg1', QuestsFu)
					for _,questName in pairs(trackerOrder) do QuestsFu:AddQuestToCategory(cat, questName, false, true, true) end
					--Clear up the order table:
					tableCleaner(trackerOrder)
				end)
			tablet:Open('QuestsFu_Tracker')
		end
		tablet:Refresh('QuestsFu_Tracker')
		QuestWatchFrame:Hide()
	end
end