--***********************************************************
--** TM_VectorToTrap.lua
--***********************************************************
-- Draws a directional line from the player to the last hovered trap
-- when TM_VectorEnabled is true and TM_VectorTrap has a valid {x,y,z}.
-- Length is capped to 40 world tiles (same cap as Show Key Origin).
-- The line persists even when the mouse leaves the Trap Manager window.

require "ISUI/ISUIElement"
require "luautils"

TM_VectorToTrap = ISUIElement:derive("TM_VectorToTrap")

function TM_VectorToTrap:initialise()
    ISUIElement.initialise(self)
end

-- Render parameters
local r, g, b, alpha = 1, 1, 0, 1  -- yellow-ish
local thickness = 2

function TM_VectorToTrap:render()
    local md = self.playerObj and self.playerObj:getModData() or nil
    if not md or md.TM_VectorEnabled ~= true then return end

    local tgt = md.TM_VectorTrap
    if not (tgt and type(tgt.x)=="number" and type(tgt.y)=="number" and type(tgt.z)=="number") then
        return
    end

    -- Player position
    local px, py, pz = self.playerObj:getX(), self.playerObj:getY(), self.playerObj:getZ()

    -- Vector in world space
	-- +(0.5, 0.5) to center towards the center of the trap square, instead of the northwest corner
    local dx, dy = (tgt.x + 0.5 - px), (tgt.y + 0.5 - py)
    local dist = math.sqrt(dx*dx + dy*dy)
    if dist < 0.0001 then return end

    -- Unit direction and clamped length
    local maxLen = 40.0
    local len = math.min(maxLen, dist)
    local ux, uy = dx / dist, dy / dist

    -- World endpoints (start slightly offset from player to avoid overdraw)
    local xStart, yStart = px, py
    local xEnd,   yEnd   = px + ux * len, py + uy * len

    -- Screen space for current playerNum
    local pn = self.playerNum or 0
    local x1 = isoToScreenX(pn, xStart, yStart, pz)
    local y1 = isoToScreenY(pn, xStart, yStart, pz)
    local x2 = isoToScreenX(pn, xEnd,   yEnd,   pz)
    local y2 = isoToScreenY(pn, xEnd,   yEnd,   pz)

    -- Optional advanced line if available (angle param not critical here)
    if luautils.drawLine2 then
        local ang = math.atan2(uy, ux) -- radians
        luautils.drawLine2(x1, y1, x2, y2, alpha, r, g, b, ang, thickness)
    else
        self:drawLine2(x1, y1, x2, y2, alpha, r, g, b)
    end
end

function TM_VectorToTrap:new(playerNum, playerObj)
    local posX = getPlayerScreenLeft(playerNum)
    local posY = getPlayerScreenTop(playerNum)
    local o = ISUIElement:new(posX, posY, 1, 1)
    setmetatable(o, self); self.__index = self
    o.playerNum = playerNum
    o.playerObj = playerObj
    return o
end

-- Keep one UI element per player alive while the character lives
function TM_VectorToTrap.onCreatePlayer(playerNum, playerObj)
    if not playerObj or (playerObj.getIsNPC and playerObj:getIsNPC()) then return end
    TM_VectorToTrap.cache = TM_VectorToTrap.cache or {}

    if TM_VectorToTrap.cache[playerNum] then
        TM_VectorToTrap.cache[playerNum]:removeFromUIManager()
    end

    local ui = TM_VectorToTrap:new(playerNum, playerObj)
    ui:initialise(); ui:instantiate(); ui:addToUIManager()
    TM_VectorToTrap.cache[playerNum] = ui
end

function TM_VectorToTrap.onCharacterDeath(characterObj)
    if characterObj and characterObj.getPlayerNum then
        local pn = characterObj:getPlayerNum()
        if TM_VectorToTrap.cache and TM_VectorToTrap.cache[pn] then
            TM_VectorToTrap.cache[pn]:removeFromUIManager()
            TM_VectorToTrap.cache[pn] = nil
        end
    end
end

Events.OnCreatePlayer.Add(TM_VectorToTrap.onCreatePlayer)
Events.OnCharacterDeath.Add(TM_VectorToTrap.onCharacterDeath)