Quantcast
local addonName, addon = ...
local L = addon.L

--[[-------------------------------------------------------------------
--  Quest objective waypoint source for TomTomLite
--
--  Anytime the quest log or objective POI information changes, the
--  objective tracker is scanned for all objectives and waypoints are
--  created for each of them. The priority of the first waypoint, i.e.
--  the first one in the objectives tracker, is set higher than the
--  rest. This of course can be overridden by the user
-------------------------------------------------------------------]]--

do
    local desc = L["This source provides waypoints for each of the objectives listed in the Blizzard objectives tracker. To add a quest to the tracking list, just shift-click it in your quest log."]
    addon:RegisterSource("questobj", L["Quest Objectives (tracked)"], desc)
end

local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("QUEST_POI_UPDATE")
eventFrame:RegisterEvent("QUEST_LOG_UPDATE")
hooksecurefunc("WatchFrame_Update", function(self)
    addon:OBJECTIVES_CHANGED()
end)

eventFrame:SetScript("OnEvent", function(self, event, ...)
    if event == "QUEST_POI_UPDATE" then
        addon:OBJECTIVES_CHANGED()
    elseif event == "QUEST_LOG_UPDATE" then
        addon:OBJECTIVES_CHANGED()
    end
end)

-- This function scans the current set of objectives, adding and removing
-- waypoints to reflect the current state of the tracker.

local waypoints = {}
function addon:OBJECTIVES_CHANGED()
    local map, floor = GetCurrentMapAreaID()
    floor = floor or 0

    -- Do not set any NEW waypoints if we're on the continent map
    if self:IsContinentMap(map) then
        return
    end

    local cvar = GetCVarBool("questPOI")
    SetCVar("questPOI", 1)

    -- Only do an objective scan if the option is enabled
    if not self.db.profile.sources.questobj then
        return
    end

    local newWaypoints = {}
    local changed = false

    -- This function relies on the above CVar being set, and updates the icon
    -- position information so it can be queries via the API
    QuestPOIUpdateIcons()

    -- Scan through every quest that is being tracked, and create a waypoint
    -- for each of the objectives that are being tracked. These waypoints will
    -- be unordered, and will be sorted or ordered by the user/algorithm
    local first
    local watchIndex = 1
    while true do
        local questIndex = GetQuestIndexForWatch(watchIndex)
        if not questIndex then
            break
        end

        local title = GetQuestLogTitle(questIndex)
        local qid = select(9, GetQuestLogTitle(questIndex))
        local completed, x, y, objective = QuestPOIGetIconInfo(qid)

        if x and y then
            -- Try to uniquely identify objective waypoints using qid, x, y along
            -- with map and floor. This may not always work, but its the best we
            -- can do right now. This allows us to ensure we don't double-set a
            -- waypoint.

            if completed then
                title = "Turn in: " .. title
            end

            local key = title .. tostring(qid + (x * 100) * (y * 100) * map * (floor + 1))
            if not first then
                first = key
            end

            if waypoints[key] then
                -- This waypoint already exists, no need to do anything, except
                -- possibly change the priority

				-- NOTE: Priority broken right now, so skip this
                local waypoint = waypoints[key]
                -- local newpri = key == first and addon.PRI_ACTIVE or addon.PRI_NORMAL
                -- if waypoint.priority ~= newpri then
                --     changed = true
                --     waypoint.priority = newpri
                -- end

                newWaypoints[key] = waypoint
            else
                -- Create the waypoint, setting priority
                local waypoint = self:AddWaypoint(map, floor, x, y, {
                    title = title,
					priority = addon.PRI_NORMAL,
					-- Proximity sory appears to be broken right now
                    -- priority = key == first and addon.PRI_ACTIVE or addon.PRI_NORMAL,
					source = "questobj",
                })

                newWaypoints[key] = waypoint
            end
        end

        watchIndex = watchIndex + 1
    end

    SetCVar("questPOI", cvar and 1 or 0)

    -- Check to see if there are any waypoints that are in 'waypoints' but
    -- not in 'newWaypoints' so we can remove them. Additionally, we may have
    -- changed a waypoint's priority during the scan, so trigger an update in
    -- that case.

    for k, waypoint in pairs(newWaypoints) do
        waypoints[k] = nil
    end

    for k, waypoint in pairs(waypoints) do
        -- This waypoint is no longer being tracked
        addon:RemoveWaypoint(waypoint)
    end

    -- Swap the arrays
    waypoints = newWaypoints

    if changed then
        addon:FireMessage("TOMTOMLITE_WAYPOINTS_CHANGED")
    end
end