---@type Diesal.GUI
local DiesalGUI = LibStub("DiesalGUI-2.0")
---@type Diesal.Tools
local DiesalTools = LibStub("DiesalTools-2.0")
---@type Diesal.Style
local DiesalStyle = LibStub("DiesalStyle-2.0")
-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Colors = DiesalStyle.Colors
local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- | Input |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Type = "DiesalInput"
local Version = 1
-- | Stylesheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local Stylesheet = {
    ["frame-background"] = {
        type = "texture",
        layer = "BACKGROUND",
        color = "000000",
        alpha = 0.6,
    },
    ["editBox-outline"] = {
        type = "outline",
        layer = "BORDER",
        color = "FFFFFF",
        alpha = 0.02,
        position = 1,
    },
    ["editBox-inline"] = {
        type = "outline",
        layer = "BORDER",
        color = "000000",
        alpha = 0.7,
    },
    ["editBox-hover"] = {
        type = "texture",
        layer = "HIGHLIGHT",
        color = "ffffff",
        alpha = 0.05,
        position = -1,
    },
    ["editBox-font"] = {
        type = "Font",
        color = Colors.UI_TEXT,
    },
}

-- ~~| Spinner Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---@class Diesal.GUI.Input.Methods
local methods = {
    ---@param self Diesal.GUI.Object.Input
    ["OnAcquire"] = function(self)
        self:SetStylesheet(Stylesheet)
        self:ApplySettings()
        self:Show()
    end,
    ---@param self Diesal.GUI.Object.Input
    ["OnRelease"] = function(self) end,
    ---@param self Diesal.GUI.Object.Input
    ["ApplySettings"] = function(self)
        self:SetWidth(self.settings.width)
        self:SetHeight(self.settings.height)
    end,
    ---@param self Diesal.GUI.Object.Input
    ["GetText"] = function(self)
        return self.editBox:GetText()
    end,
    ---@param self Diesal.GUI.Object.Input
    ["SetText"] = function(self, txt)
        self.editBox:SetText(txt)
    end,
    ---@param self Diesal.GUI.Object.Input
    ["SetTextColor"] = function(self, color, alpha)
        alpha = alpha or 1
        color = { DiesalTools.GetColor(color) }
        self.editBox:SetTextColor(color[1], color[2], color[3], alpha)
    end,
}

---@class DiesalInput : Diesal.GUI.Object.Input

-- | Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local function Constructor()
    ---@class Diesal.GUI.Object.Input : Diesal.GUI.ObjectBase, Diesal.GUI.Input.Methods
    ---@field editBox EditBox
    local self = DiesalGUI:Create(Type, true)
    local frame = CreateFrame("Frame", nil, UIParent)
    self.frame = frame
    self.defaults = {
        height = 16,
        width = 50,
        mouse = true,
    }
    -- ~~ Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- OnAcquire, OnRelease, OnHeightSet, OnWidthSet
    -- OnEnter, OnLeave, OnEnterPressed, OnValueChanged
    -- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    frame:SetScript("OnHide", function(this)
        self:FireEvent("OnHide")
    end)

    local editBox = self:CreateRegion("EditBox", "editBox", frame) --[[@as Diesal.GUI.Region.EditBox]]
    editBox:SetAllPoints()
    editBox:SetAutoFocus(false)
    editBox:SetJustifyH("LEFT")
    editBox:SetJustifyV("CENTER")
    editBox:SetTextInsets(3, 0, 2, 0)
    editBox:SetScript("OnEnterPressed", function(this, ...)
        self:FireEvent("OnEnterPressed", ...)
        DiesalGUI:ClearFocus()
    end)
    editBox:HookScript("OnEscapePressed", function(this, ...)
        self:FireEvent("OnEscapePressed", ...)
    end)
    editBox:HookScript("OnEditFocusLost", function(this, ...)
        self:FireEvent("OnEditFocusLost", ...)
    end)
    editBox:HookScript("OnEditFocusGained", function(this, ...)
        self:FireEvent("OnEditFocusGained", ...)
    end)
    editBox:SetScript("OnEnter", function(this, ...)
        self:FireEvent("OnEnter", ...)
    end)
    editBox:SetScript("OnLeave", function(this, ...)
        self:FireEvent("OnLeave", ...)
    end)

    -- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    self:SetMethods(methods)
    --[[ for method, func in pairs(methods) do
        self[method] = func
    end ]]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    return self
end

DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version)
