--[[
Author: Jarth
Filename: LibJarthSharedBase_Move.lua
]] --

-------------------------------------------------------------------------------------------------
-- VARIABLES --
-------------------------------------------------------------------------------------------------
local sharedBaseModule = JarthSharedBase

-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-------------------------------------------------------------------------------------------------
function sharedBaseModule:UpdateMoveFrame(baseModule, targetFrame)
    local moveFrame = baseModule.MoveFrame
    local onMouseEnter, onMouseExit, onMouseDown, onMouseUp = nil, nil, nil, nil

    if baseModule.Global.IsMoveEnabled then
        moveFrame = sharedBaseModule.GetOrCreateMoveFrame(baseModule, targetFrame)
        onMouseEnter = sharedBaseModule.MoveFrameOnEnter
        onMouseExit = sharedBaseModule.MoveFrameOnExit
        onMouseDown = sharedBaseModule.MoveFrameOnDown
        onMouseUp = sharedBaseModule.MoveFrameOnUp
    end

    if moveFrame then
        moveFrame:SetHandler("OnMouseEnter", onMouseEnter)
        moveFrame:SetHandler("OnMouseExit", onMouseExit)
        moveFrame:SetHandler("OnMouseDown", onMouseDown)
        moveFrame:SetHandler("OnMouseUp", onMouseUp)
        moveFrame:SetHidden(not baseModule.Global.IsMoveEnabled)
        moveFrame.overlay:SetHidden(not baseModule.Global.IsMoveEnabled)
        moveFrame.labelCenter:SetHidden(not baseModule.Global.IsMoveEnabled)
        moveFrame.labelTopLeft:SetHidden(not baseModule.Global.IsMoveEnabled)
        moveFrame.MoveFrameUpdateText(moveFrame)
        moveFrame.MoveFrameUpdateColor(moveFrame)
        moveFrame.MoveFrameAnchorToTarget(moveFrame, moveFrame.TargetFrame)
    end
end

-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-- Move handlers --
-------------------------------------------------------------------------------------------------
function sharedBaseModule.GetOrCreateMoveFrame(baseModule, targetFrame)
    if baseModule.MoveFrame == nil then
        local newMoveFrame = baseModule.WM:CreateControlFromVirtual(nil, GuiRoot, baseModule.Addon.Name .. "_MoveFrame")

        --Variable is used to define what savedVariable the Frame refers to.
        newMoveFrame.TargetFrame = targetFrame
        newMoveFrame.Saved = baseModule.Saved

        newMoveFrame["MoveFrameAnchorToTarget"] = sharedBaseModule.MoveFrameAnchorToTarget
        newMoveFrame["MoveFrameGetSnapPosition"] = sharedBaseModule.MoveFrameGetSnapPosition
        newMoveFrame["MoveFrameUpdateText"] = sharedBaseModule.MoveFrameUpdateText
        newMoveFrame["MoveFrameUpdateColor"] = sharedBaseModule.MoveFrameUpdateColor
        newMoveFrame["MoveFrameOnUpdate"] = sharedBaseModule.MoveFrameOnUpdate
        newMoveFrame["MoveFrameStorePosition"] = sharedBaseModule.MoveFrameStorePosition

        newMoveFrame:SetDimensions(targetFrame:GetWidth(), targetFrame:GetHeight())
        newMoveFrame:SetDrawLayer(4)
        newMoveFrame:SetParent(GuiRoot)
        newMoveFrame:SetMouseEnabled(true)
        newMoveFrame:SetMovable(true)
        newMoveFrame:SetClampedToScreen(true)

        -- overlay
        newMoveFrame.overlay = baseModule.WM:CreateControl(nil, newMoveFrame, CT_BACKDROP)
        newMoveFrame.overlay:SetDrawLevel(2)
        newMoveFrame.overlay:SetAnchorFill(targetFrame)
        newMoveFrame.overlay:SetEdgeTexture("", 8, 1, 0)
        -- label
        newMoveFrame.labelCenter = baseModule.WM:CreateControl(nil, newMoveFrame, CT_LABEL)
        newMoveFrame.labelCenter:SetDrawLevel(3)
        newMoveFrame.labelCenter:SetAnchorFill(targetFrame)
        newMoveFrame.labelCenter:SetFont("ZoFontWinH5")
        newMoveFrame.labelCenter:SetHorizontalAlignment(1)
        newMoveFrame.labelCenter:SetVerticalAlignment(1)

        newMoveFrame.labelTopLeft = baseModule.WM:CreateControl(nil, newMoveFrame, CT_LABEL)
        newMoveFrame.labelTopLeft:SetDrawLevel(3)
        newMoveFrame.labelTopLeft:SetAnchorFill(targetFrame)
        newMoveFrame.labelTopLeft:SetFont("ZoFontWinH5")
        newMoveFrame.labelTopLeft:SetHorizontalAlignment(0)
        newMoveFrame.labelTopLeft:SetVerticalAlignment(0)

        baseModule.MoveFrame = newMoveFrame
    end

    return baseModule.MoveFrame
end

function sharedBaseModule.MoveFrameOnEnter(frame)
    frame.MoveFrameUpdateText(frame, true)
end

function sharedBaseModule.MoveFrameOnExit(frame)
    frame.MoveFrameUpdateText(frame, false)
end

function sharedBaseModule.MoveFrameOnDown(frame)
    frame:SetHandler("OnUpdate", frame.MoveFrameOnUpdate)
end

function sharedBaseModule.MoveFrameOnUp(frame)
    frame.MoveFrameOnUpdate(frame)
    frame.MoveFrameUpdateText(frame, false)
    frame:SetHandler("OnUpdate", nil)
    frame.MoveFrameStorePosition(frame)
end

function sharedBaseModule.MoveFrameOnUpdate(frame)
    frame.TargetFrame:ClearAnchors()
    frame.TargetFrame:SetAnchor(TOPLeft, GuiRoot, TOPLeft, sharedBaseModule.MoveFrameGetSnapPosition(frame, frame:GetLeft()), sharedBaseModule.MoveFrameGetSnapPosition(frame, frame:GetTop()))
    frame.MoveFrameUpdateText(frame, true)
end

function sharedBaseModule.MoveFrameUpdateText(frame, position)
    local labelTextTopLeft = ""

    frame.labelCenter:SetText(string.format("%s,%s", frame:GetWidth(), frame:GetHeight()))

    if (position) then
        labelTextTopLeft = string.format("%s,%s", frame.TargetFrame:GetLeft(), frame.TargetFrame:GetTop())
    end

    frame.labelTopLeft:SetText(labelTextTopLeft)
end

function sharedBaseModule.MoveFrameGetSnapPosition(frame, value)
    return (zo_round(value / frame.Saved.SnapSize) * frame.Saved.SnapSize)
end

function sharedBaseModule.MoveFrameStorePosition(frame)
    frame.Saved.Top = frame.MoveFrameGetSnapPosition(frame, frame:GetTop())
    frame.Saved.Left = frame.MoveFrameGetSnapPosition(frame, frame:GetLeft())
end

function sharedBaseModule.MoveFrameAnchorToTarget(frame, target)
    frame:ClearAnchors()
    frame:SetDimensions(target:GetWidth(), target:GetHeight())
    frame:SetAnchor(TOPLeft, GuiRoot, TOPLeft, target:GetLeft(), target:GetTop())
end

function sharedBaseModule.MoveFrameUpdateColor(frame)
    local centerColor = frame.Saved.CenterColor
    local edgeColor = frame.Saved.EdgeColor
    local fontColor = frame.Saved.FontColor

    frame.overlay:SetCenterColor(centerColor.r, centerColor.g, centerColor.b, centerColor.a)
    frame.overlay:SetEdgeColor(edgeColor.r, edgeColor.g, edgeColor.b, edgeColor.a)
    frame.labelCenter:SetColor(fontColor.r, fontColor.g, fontColor.b, fontColor.a)
    frame.labelTopLeft:SetColor(fontColor.r, fontColor.g, fontColor.b, fontColor.a)
end