-- AutoQuestLearner Guide
--
-- A scrollable in-game help window covering what this addon does and
-- how to use it -- opened with /aql guide, or the "Guide" button on the
-- config panel.
--
-- IMPORTANT: the frame is built LAZILY (only the first time it's
-- actually shown) and wrapped in pcall, rather than being constructed
-- unconditionally when this file loads. A previous version built
-- everything immediately at load time with the function that opens it
-- defined at the very end of the file -- if ANY of the frame
-- construction calls above it had failed at runtime for any reason
-- (something luac's syntax-only check can't catch), that function
-- would never get defined at all, and every other file loading
-- afterward would see AutoQuestLearner_ShowGuide as nil with no
-- indication why. This structure means a construction failure reports
-- itself clearly instead of failing silently.

local GUIDE_TEXT = [[
|cff00ff00AutoQuestLearner -- How To Use|r

|cffffcc00What this addon does|r
This addon learns where quest NPCs and objectives actually are as you
play -- both from a large bundled database and from your own
gameplay -- then shows you a directional arrow, colored map/minimap
dots, and an enhanced quest tracker so you always know where to go
next. Everything it learns from your own play is shared across every
character on your account, not just the one that discovered it.

|cffffcc00The Arrow|r
The floating arrow (drag it anywhere) always points toward your
closest known objective or turn-in. It automatically switches targets
as you finish objectives or quests -- you don't have to do anything.
A few things it can tell you:
  - "Ready to turn in here." -- you're at the right spot.
  - "Find <name> nearby." -- an objective's known location.
  - "Not in this zone -- X is in <Zone>." -- the objective isn't in
    your current zone. If a known flight connects the two zones, or a
    real verified overland route exists (see Travel Routes below),
    it'll say so specifically instead of just "fly or travel there."
  - "Speak to <name> to accept this quest." -- a nearby quest you
    haven't picked up yet (see Available Quests below).
  - "No separate objective location known yet." -- nothing learned
    for this yet, static or otherwise. Play normally and it'll fill in.

|cffffcc00Map & Minimap Dots|r
Colored dots show where quest objectives are. If a quest asks for
parts from several different creatures, each one gets its own
distinct color so you can tell them apart at a glance. Nearby spawns
that would visually overlap get merged into one ring automatically;
hold Ctrl on the world map (or over the minimap) to temporarily see
every individual spawn point instead -- release it to go back to the
merged view. Green dots are a separate thing -- nearby quests you
could pick up, shown regardless of what's in your log (see Available
Quests below). Hover any dot for details; dots for a specific
objective disappear on their own once that part is done, not just
when the whole quest is turned in.

|cffffcc00Available Quests|r
With "Display Available Quest Givers" on (Config panel, on by
default), both the arrow and the map will also suggest nearby quests
you haven't picked up yet -- not just what's already in your log.
Several filters run automatically before anything gets suggested:
  - Your level range (configurable in Config)
  - Your faction -- a real bitwise check against the quest's race
    restriction, including single-race restrictions (Draenei-only,
    Night Elf-only, etc.), not just whole-faction ones. A quest with
    no faction tag of its own inherits one from a known chain
    relative if one exists, since chains essentially never switch
    faction partway through.
  - Whether you've actually already completed it -- checked against
    the SERVER's real completion history (not just what this addon
    has personally seen), so something you finished long before
    installing this addon won't show as available. Daily/repeatable
    quests are exempted from this once seen at least once, so they
    don't get stuck looking permanently "done" after their first
    completion.
  - Known chain prerequisites -- if this addon knows the quest
    requires an earlier one first (or several -- some quests need
    multiple), it won't suggest it until all of them are done. Backed
    by real bundled prerequisite data covering thousands of quests,
    not just a small hand-researched list.
  - Deprecated/internal database entries (roughly 200 old dev-only
    quest duplicates bundled in the source data, marked with
    recognizable prefixes) are filtered out entirely.
None of these filters are perfect. If a quest still gets suggested too
early, that's a gap in that specific data, not a design flaw -- tell me
the quest name and NPC dialog you actually see, and it can usually be
fixed for good.

|cffffcc00Quest Item Buttons|r
For quests that need you to use a specific item on something (like an
Essence Extractor on a corpse), a small movable panel shows that
item's icon plus the quest name -- click it to use the item directly,
same as clicking it in your bags. Shift-drag the panel to move it
anywhere; position is remembered. Toggle in Config ("Show Quest Item
Buttons", on by default).

|cffffcc00Travel Routes (cross-zone quests)|r
When a tracked quest's destination is in a different zone, the arrow
looks for a REAL, verified route before falling back to the generic
message: a known flight connection first, then a hand-verified
overland route if one exists for that destination zone (a growing
list -- currently covers a handful of zones with tricky access, like
the Hinterlands mountain pass and the Un'Goro Crater entrance from
Tanaris). Where a route has a precise checkpoint coordinate, the arrow
can point at and track it like any normal destination, self-correcting
as you reach each checkpoint. Where only general directions are known,
it shows those as text instead. Missing a zone you need routed? Say
which one and it can be researched and added the same verified way.

|cffffcc00You don't need to do anything to teach it|r
Just quest normally. Accepting a quest teaches the giver's location;
turning one in teaches the turn-in location; killing/looting toward an
objective teaches that location. All of it saves permanently and
shares across your whole account automatically. The commands below are
for special cases, not everyday play.

|cffffcc00Useful commands|r
|cffffcc00/aql learn [quest name]|r
  Manually save your CURRENT position for a quest right now, instead
  of waiting to naturally trigger it. Correctly detects whether the
  quest is complete (saves a turn-in location) or still in progress
  (saves an objective location). With no name, uses whatever quest is
  pinned, or the one quest currently being tracked if only one is.

|cffffcc00/aql proximity|r
  Toggle automatic proximity-based learning on/off (learning objective
  locations just by being near them while questing, no kill/loot
  required). On by default.

|cffffcc00/aql focus|r
  Toggle "focus mode" -- only show map/minimap dots for whatever the
  arrow is currently tracking, hiding everything else. Good for
  decluttering a busy zone. Off by default.

|cffffcc00/aql resync|r
  Force an immediate refresh of everything -- re-checks every quest in
  your log against the current logic and redraws all nodes. Useful if
  something looks stuck (rare, but a safety net).

|cffffcc00/aql db|r
  Prints exactly how much your account has learned so far -- number of
  quests with a known giver/turn-in, number with known objective
  spawns. Good for confirming the shared database is actually growing.

|cffffcc00/aql opendb [questID]|r
  Opens that quest's page on the Ascension Database in your browser --
  with a quest selected/open in your quest log, or a specific quest ID
  typed directly (e.g. "/aql opendb 641"). Needs this client's
  OpenAscensionDBURL function; not available on all clients.

|cffffcc00/aql route|r
  Suggests an order to tackle your active quests in your CURRENT zone,
  aiming for the least backtracking -- starts from where you're
  standing and picks the nearest known stop each time. Straight-line
  distance only (doesn't know about walls or actual walking paths),
  and only covers quests with a known location in this zone.

|cffffcc00/aql zone|r
  Shows how many known quests you've completed in your current zone
  (e.g. "Tirisfal Glades: 12/34 done"), plus a list of what's left.
  Counts what THIS addon's database knows about, not literally every
  quest that zone has ever had across every patch.

|cffffcc00/aql chain [quest name]|r
  Shows the next quest in the chain, if this addon knows one -- also
  shown automatically in the arrow's description once a quest is ready
  to turn in ("Next: ..."). Not every quest has known chain data; a
  quest with no shown follow-up may just be a one-off, or simply not
  covered by what this addon currently knows.

|cffffcc00/aql config|r
  Opens the settings panel -- minimap toggle, tracker options, node
  display style, available-quest filters, quest item buttons, and
  more. Always sized to fit everything automatically; has quick-access
  buttons along the top for the Guide, Route, Zone, and Chain commands
  so you don't need to type them out.

|cffffcc00/aql tracker|r / |cffffcc00/aql blizztracker|r
  Toggle this addon's own quest tracker, or toggle Blizzard's default
  tracker, independently of each other.

|cffffcc00/aql tomtomauto|r
  Toggle auto-selecting the closest TomTom waypoint automatically (if
  you have TomTom installed).

|cffffcc00/aql map|r
  Force an update of map/minimap nodes right now.

|cffffcc00/aql gossip|r
  Manually reprocess whatever gossip window is currently open, in case
  automatic learning missed it.

|cffffcc00/aql arrow|r
  Diagnostic: explains exactly what the arrow is doing right now and
  why, per quest in your log. Useful if something seems off and you
  want to know what the addon actually knows.

|cffffcc00/aql questitems|r
  Diagnostic for the Quest Item Buttons panel -- shows what's currently
  detected and why a button might not be appearing.

|cffffcc00/aql debug|r
  Prints low-level diagnostic info. Not needed for normal use.

|cffffcc00/aql|r or |cffffcc00/aql status|r
  Shows a short status summary and the full command list in chat.

|cffffcc00Pinning a quest|r
Alt+Right-Click a quest in the tracker to "pin" it -- the arrow will
stay locked on that one quest until you unpin it (Alt+Right-Click
again, or |cffffcc00/aql unpin|r), ignoring everything else in your log
(including Available Quest suggestions, which are automatically
suppressed while a quest is pinned).

|cffffcc00If something looks wrong|r
The bundled database is large but not perfect -- occasionally a
location will be stale or just wrong, or a quest will be suggested as
"available" slightly too early because its chain data isn't known yet.
If you notice one, stand at the REAL location and run
|cffffcc00/aql learn|r (with the quest name if needed) -- that
permanently corrects it for your whole account, and since the data is
shared, it self-heals over time as anyone plays normally too. For a
wrong "available" suggestion specifically, note the quest name and
what the NPC's dialog actually shows -- that's usually enough to trace
and fix the real prerequisite chain.

|cffffcc00Troubleshooting tools|r
These aren't needed for normal play -- they exist for tracking down a
specific problem, and were the actual tools that found and fixed some
real bugs in this addon (including a serious tracker-flickering issue
that took a while to solve, and only got solved once these existed).

|cffffcc00/aql flickerdebug|r
  Records for 5 seconds and reports exactly how many times various
  tracker functions actually fired -- useful if the tracker or map
  ever seems to flicker/refresh oddly again.

|cffffcc00/aql perf|r
  Quick memory usage check for this addon specifically.

|cffffcc00/aql perfdebug|r
  Records for 10 seconds and reports real measured time spent in the
  functions most likely to affect FPS -- move around and play normally
  during the recording rather than standing still.
]]

local guideFrame = nil
local guideBuildFailed = false

local function BuildGuideFrame()
  local f = CreateFrame("Frame", "AutoQuestLearnerGuide", UIParent)
  f:Hide()
  f:SetWidth(460)
  f:SetHeight(520)
  f:SetPoint("CENTER", 0, 0)
  f:SetFrameStrata("HIGH")
  f:SetMovable(true)
  f:EnableMouse(true)
  f:SetClampedToScreen(true)

  f:SetScript("OnMouseDown", function() this:StartMoving() end)
  f:SetScript("OnMouseUp", function() this:StopMovingOrSizing() end)

  f:SetBackdrop({
    bgFile = "Interface/Tooltips/UI-Tooltip-Background",
    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
    tile = true, tileSize = 16, edgeSize = 16,
    insets = { left = 4, right = 4, top = 4, bottom = 4 }
  })
  f:SetBackdropColor(0, 0, 0, 0.9)
  f:SetBackdropBorderColor(0.2, 1, 0.8, 1)

  table.insert(UISpecialFrames, "AutoQuestLearnerGuide")

  f.title = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  f.title:SetPoint("TOP", f, "TOP", 0, -10)
  f.title:SetFont(STANDARD_TEXT_FONT, 13)
  f.title:SetText("|cff00ff00AutoQuestLearner|r Guide")

  f.close = CreateFrame("Button", "AutoQuestLearnerGuideClose", f)
  f.close:SetPoint("TOPRIGHT", -5, -5)
  f.close:SetHeight(20)
  f.close:SetWidth(20)
  f.close.texture = f.close:CreateTexture(nil, "ARTWORK")
  f.close.texture:SetTexture("Interface/Buttons/UI-Panel-MinimizeButton-Up")
  f.close.texture:ClearAllPoints()
  f.close.texture:SetPoint("TOPLEFT", f.close, "TOPLEFT", 4, -4)
  f.close.texture:SetPoint("BOTTOMRIGHT", f.close, "BOTTOMRIGHT", -4, 4)
  f.close:SetScript("OnClick", function() f:Hide() end)

  -- Scrollable text: a ScrollFrame (built-in Blizzard template, handles
  -- the scrollbar) containing a plain Frame (the "scroll child") with a
  -- FontString inside it.
  f.scrollFrame = CreateFrame("ScrollFrame", "AutoQuestLearnerGuideScrollFrame", f, "UIPanelScrollFrameTemplate")
  f.scrollFrame:SetPoint("TOPLEFT", 16, -34)
  f.scrollFrame:SetPoint("BOTTOMRIGHT", -34, 44)

  f.scrollChild = CreateFrame("Frame", nil, f.scrollFrame)
  f.scrollChild:SetWidth(400)
  f.scrollFrame:SetScrollChild(f.scrollChild)

  f.text = f.scrollChild:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  f.text:SetFont(STANDARD_TEXT_FONT, 12)
  f.text:SetPoint("TOPLEFT", 0, 0)
  f.text:SetWidth(400)
  f.text:SetJustifyH("LEFT")
  f.text:SetJustifyV("TOP")
  f.text:SetText(GUIDE_TEXT)

  local sized = false
  f:SetScript("OnShow", function()
    if sized then return end
    f:SetScript("OnUpdate", function(self)
      self:SetScript("OnUpdate", nil)
      local ok, h = pcall(function() return f.text:GetStringHeight() end)
      f.scrollChild:SetHeight((ok and h or 1400) + 20)
    end)
    sized = true
  end)

  return f
end

function AutoQuestLearner_ShowGuide()
  if guideBuildFailed then
    print("|cff00ff00AutoQuestLearner:|r The guide window failed to build earlier this session and won't retry automatically -- a /reload may help; if not, please report this.")
    return
  end
  if not guideFrame then
    local ok, result = pcall(BuildGuideFrame)
    if not ok then
      guideBuildFailed = true
      print("|cff00ff00AutoQuestLearner:|r Couldn't open the guide -- " .. tostring(result))
      return
    end
    guideFrame = result
  end
  guideFrame:Show()
end
