--[[
Author: Jarth
Filename: CBs_MoveFrame.lua
]] --
-------------------------------------------------------------------------------------------------
-- VARIABLES --
-------------------------------------------------------------------------------------------------
local base = CollectionBars

-------------------------------------------------------------------------------------------------
-- FUNCTIONS --
-------------------------------------------------------------------------------------------------
function base.GetMoveFrameSnapPosition(frame, anchorXY)
    local snapSize = frame.Saved.SnapSize
    local x = frame:GetLeft()
    local y = frame:GetTop()

    if anchorXY == BOTTOMRIGHT or anchorXY == TOPRIGHT then
        x = frame:GetRight()
    end
    if anchorXY == BOTTOMRIGHT or anchorXY == BOTTOMLEFT then
        y = frame:GetBottom()
    end

    return (zo_round(x / snapSize) * snapSize), (zo_round(y / snapSize) * snapSize)
end

function base.UpdateMoveFrame(_type)
    local moveFrame = _type.MoveFrame
    local targetFrame = _type.Frame
    local onMouseEnter, onMouseExit, onMouseDown, onMouseUp = nil, nil, nil, nil

    if base.Global.IsMoveEnabled and (_type.Name == "Combine" or not _type.IsEmpty and not _type.Saved.IsCombined) then
        moveFrame = base.GetOrCreateMoveFrame(targetFrame, _type)

        onMouseEnter = function(frame)
            frame.MoveFrameUpdateText(frame, true)
        end
        onMouseExit = function(frame)
            frame.MoveFrameUpdateText(frame, false)
        end
        onMouseDown = function(frame)
            frame:SetHandler("OnUpdate", frame.MoveFrameOnUpdate)
        end
        onMouseUp = function(frame)
            local saved = frame.Type.Saved
            frame.MoveFrameOnUpdate(frame)
            frame.MoveFrameUpdateText(frame, false)
            frame:SetHandler("OnUpdate", nil)
            saved.X, saved.Y = base.GetMoveFrameSnapPosition(frame, saved.AnchorXY)
        end
    end

    if moveFrame then
        moveFrame:SetHandler("OnMouseEnter", onMouseEnter)
        moveFrame:SetHandler("OnMouseExit", onMouseExit)
        moveFrame:SetHandler("OnMouseDown", onMouseDown)
        moveFrame:SetHandler("OnMouseUp", onMouseUp)
        moveFrame:SetHidden(not base.Global.IsMoveEnabled)
        moveFrame.overlay:SetHidden(not base.Global.IsMoveEnabled)
        moveFrame.labelCenter:SetHidden(not base.Global.IsMoveEnabled)
        moveFrame.labelTopLeft:SetHidden(not base.Global.IsMoveEnabled)
        moveFrame.MoveFrameUpdateText(moveFrame)
        moveFrame.MoveFrameUpdateColor(moveFrame)
        moveFrame:ClearAnchors()
        moveFrame:SetDimensions(targetFrame:GetWidth(), targetFrame:GetHeight())
        moveFrame:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, targetFrame:GetLeft(), targetFrame:GetTop())
    end
end

function base.GetOrCreateMoveFrame(targetFrame, _type)
    if _type.MoveFrame == nil then
        local moveFrameName = _type.Name .. "_MoveFrame"
        local newMoveFrame = base.WM:CreateControlFromVirtual(moveFrameName, GuiRoot, base.Addon.Abbreviation .. "_MoveFrame")

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

        newMoveFrame["MoveFrameUpdateText"] = function(frame, position)
            local labelTextTopLeft = ""

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

            frame.labelCenter:SetText(string.format("%s,%s", frame:GetWidth(), frame:GetHeight()))
            frame.labelTopLeft:SetText(labelTextTopLeft)
        end
        newMoveFrame["MoveFrameOnUpdate"] = function(frame)
            local x, y = base.GetMoveFrameSnapPosition(frame, TOPLEFT)
            frame.TargetFrame:ClearAnchors()
            frame.TargetFrame:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, x, y)
            frame.MoveFrameUpdateText(frame, true)
        end

        newMoveFrame["MoveFrameUpdateColor"] = function(frame)
            frame.overlay:SetCenterColor(0.88, 0.88, 0.88, 0.4)
            frame.overlay:SetEdgeColor(0.88, 0.88, 0.88, 0)
            frame.labelCenter:SetColor(0.9, 0.9, 0.9, 0.9)
            frame.labelTopLeft:SetColor(0.9, 0.9, 0.9, 0.9)
        end

        newMoveFrame:SetAnchorFill(targetFrame)
        newMoveFrame:SetParent(GuiRoot)

        -- -- overlay
        if newMoveFrame.overlay == nil then
            newMoveFrame.overlay = GetControl(moveFrameName .. "BG")
        end

        -- labels
        if newMoveFrame.labelTopLeft == nil or newMoveFrame.labelCenter == nil then
            newMoveFrame.labelTopLeft = GetControl(moveFrameName .. "LabelTopLeft")
            newMoveFrame.labelTopLeft:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
            newMoveFrame.labelTopLeft:SetVerticalAlignment(TEXT_ALIGN_TOP)

            newMoveFrame.labelCenter = GetControl(moveFrameName .. "LabelCenter")
            newMoveFrame.labelCenter:SetHorizontalAlignment(TEXT_ALIGN_CENTER)
            newMoveFrame.labelCenter:SetVerticalAlignment(TEXT_ALIGN_CENTER)
        end

        _type.MoveFrame = newMoveFrame
    end

    return _type.MoveFrame
end