local d={}local t=require(script:FindFirstAncestor("\080\108\117\103\105\110\070\114\097\109\101\119\111\114\107"))local l local m local S local N local B local R="\104\116\116\112\058\047\047\119\119\119\046\114\111\098\108\111\120\046\099\111\109\047\097\115\115\101\116\047\063\105\100\061\057\048\050\056\048\049\048\056\056\051"local v=UDim.new(0,4)local j=Color3.fromRGB(0,0,0)local q=1 local i=0 local K=TweenInfo.new(.2,Enum.EasingStyle.Quad,Enum.EasingDirection.InOut)local G={h=1,s=1,v=.85}local Z=UDim2.fromOffset(150,150)local b=TweenInfo.new(.7,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out)function d.Get(t,d)local m=d.text local N=d.color local F=d.activatedCallback local g=d.activatedDiscColor local C=d.cornerRadius local L=d.strokeColor local h=d.strokeThickness local O=d.strokeTransparency local r=nil local function Y(d,t)if r then r:Cancel()r:Destroy()r=nil end r=((((S.new()):SetInstance(d)):SetTweenInfo(K)):SetProperty("\073\109\097\103\101\067\111\108\111\114\051",t)):Play()end local function e(d,t,l)local m=Instance.new("\070\114\097\109\101")m.BackgroundColor3=g or Color3.fromRGB(255,255,255)m.Size=UDim2.fromScale(0,0)m.AnchorPoint=Vector2.new(.5,.5)m.Transparency=.5 m.Parent=d local N=Instance.new("\085\073\067\111\114\110\101\114")N.CornerRadius=UDim.new(1,0)N.Parent=m m.Position=UDim2.fromOffset(t-d.AbsolutePosition.X,l-d.AbsolutePosition.Y)local B=(((((S.new()):SetInstance(m)):SetTweenInfo(b)):SetProperty("\084\114\097\110\115\112\097\114\101\110\099\121",1)):SetProperty("\083\105\122\101",Z)):Play()task.spawn(function()task.wait(b.Time)B:Destroy()m:Destroy()end)end local function u(d)local t,l,m=N:ToHSV()local S=Color3.fromHSV(t*G.h,l*G.s,m*G.v)Y(d,S)end local function M(d)Y(d,N)end return l.createElement("\073\109\097\103\101\066\117\116\116\111\110",{BackgroundTransparency=1,HoverImage=R,Image=R,PressedImage=R;ImageColor3=N,Size=UDim2.fromScale(1,1);ClipsDescendants=true;[l.Event.MouseButton1Down]=function(d,t,l)e(d,t,l)F(d)end,[l.Event.MouseEnter]=u;[l.Event.MouseLeave]=M},{UICorner=l.createElement("\085\073\067\111\114\110\101\114",{CornerRadius=C or v});UIStroke=l.createElement("\085\073\083\116\114\111\107\101",{ApplyStrokeMode=Enum.ApplyStrokeMode.Contextual,Color=L or j;LineJoinMode=Enum.LineJoinMode.Round,Thickness=h or q;Transparency=O or i}),TextLabel=l.createElement("\084\101\120\116\076\097\098\101\108",{Size=UDim2.fromScale(1,1),TextScaled=true;Font=B:GetSetting("\070\111\110\116");BackgroundTransparency=1,Text=m})})end function d.FrameworkInit(d)l=t:Require("\082\111\097\099\116")m=t:Require("\087\105\100\103\101\116\067\111\110\115\116\097\110\116\115")S=t:Require("\084\119\101\101\110\067\111\110\115\116\114\117\099\116\111\114")N=t:Require("\083\111\099\107\101\116\067\111\110\116\114\111\108\108\101\114")B=t:Require("\083\111\099\107\101\116\083\101\116\116\105\110\103\115")end function d.FrameworkStart(d) end return d
---
---Pretty button
---
---@class RoactButton
---
local RoactButton = {}

--------------------------------------------------
-- Types
-- ...

--------------------------------------------------
-- Dependencies
local PluginFramework = require(script:FindFirstAncestor("PluginFramework")) ---@type Framework
local Roact ---@type Roact
local WidgetConstants ---@type WidgetConstants
local TweenConstructor ---@type TweenConstructor
local SocketController ---@type SocketController
local SocketSettings ---@type SocketSettings

--------------------------------------------------
-- Constants
local IMAGE = "http://www.roblox.com/asset/?id=9028010883"
local CORNER_RADIUS = UDim.new(0, 4)
local STROKE_COLOR = Color3.fromRGB(0, 0, 0)
local STROKE_THICKNESS = 1
local STROKE_TRANSPARENCY = 0
local BACKGROUND_COLOR_TWEEN_INFO = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
local HOVER_BACKGROUND_HSV_MULTIPLIER = { h = 1, s = 1, v = 0.85 }
local ACTIVATED_DISC_GOAL_SIZE = UDim2.fromOffset(150, 150)
local ACTIVATED_DISC_TWEEN_INFO = TweenInfo.new(0.7, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)

--------------------------------------------------
-- Members

---
---@param props table
---@return RoactElement
---
function RoactButton:Get(props)
    -- Read props
    local text = props.text ---@type string
    local color = props.color ---@type Color3
    local activatedCallback = props.activatedCallback ---@type function
    local activatedDiscColor = props.activatedDiscColor ---@type Color3 optional
    local cornerRadius = props.cornerRadius ---@type UDim optional
    local strokeColor = props.strokeColor ---@type Color3 optional
    local strokeThickness = props.strokeThickness ---@type number optional
    local strokeTransparency = props.strokeTransparency ---@type number optional

    -- Create variables
    local backgroundColorTween = nil ---@type Tween

    ---@param instance ImageButton
    ---@param toColor Color3
    local function tweenBackgroundColor(instance, toColor)
        if backgroundColorTween then
            backgroundColorTween:Cancel()
            backgroundColorTween:Destroy()
            backgroundColorTween = nil
        end

        backgroundColorTween = TweenConstructor.new()
            :SetInstance(instance)
            :SetTweenInfo(BACKGROUND_COLOR_TWEEN_INFO)
            :SetProperty("ImageColor3", toColor)
            :Play()
    end

    ---@param instance ImageButton
    ---@param x number
    ---@param y number
    local function onActivated(instance, x, y)
        -- Create disc
        local disc = Instance.new("Frame") ---@type Frame
        disc.BackgroundColor3 = activatedDiscColor or Color3.fromRGB(255, 255, 255)
        disc.Size = UDim2.fromScale(0, 0)
        disc.AnchorPoint = Vector2.new(0.5, 0.5)
        disc.Transparency = 0.5
        disc.Parent = instance

        local uiCorner = Instance.new("UICorner") ---@type UICorner
        uiCorner.CornerRadius = UDim.new(1, 0)
        uiCorner.Parent = disc

        -- Calculate position
        disc.Position = UDim2.fromOffset(x - instance.AbsolutePosition.X, y - instance.AbsolutePosition.Y)

        -- Tween
        local discTween = TweenConstructor.new()
            :SetInstance(disc)
            :SetTweenInfo(ACTIVATED_DISC_TWEEN_INFO)
            :SetProperty("Transparency", 1)
            :SetProperty("Size", ACTIVATED_DISC_GOAL_SIZE)
            :Play()

        -- Cleanup
        task.spawn(function()
            task.wait(ACTIVATED_DISC_TWEEN_INFO.Time)
            discTween:Destroy()
            disc:Destroy()
        end)
    end

    ---@param instance ImageButton
    local function onMouseEnter(instance)
        local h, s, v = color:ToHSV()
        local enterColor = Color3.fromHSV(
            h * HOVER_BACKGROUND_HSV_MULTIPLIER.h,
            s * HOVER_BACKGROUND_HSV_MULTIPLIER.s,
            v * HOVER_BACKGROUND_HSV_MULTIPLIER.v
        )
        tweenBackgroundColor(instance, enterColor)
    end

    ---@param instance ImageButton
    local function onMouseLeave(instance)
        tweenBackgroundColor(instance, color)
    end

    return Roact.createElement("ImageButton", {
        BackgroundTransparency = 1,
        HoverImage = IMAGE,
        Image = IMAGE,
        PressedImage = IMAGE,
        ImageColor3 = color,
        Size = UDim2.fromScale(1, 1),
        ClipsDescendants = true,

        [Roact.Event.MouseButton1Down] = function(instance, x, y)
            onActivated(instance, x, y)
            activatedCallback(instance)
        end,
        [Roact.Event.MouseEnter] = onMouseEnter,
        [Roact.Event.MouseLeave] = onMouseLeave,
    }, {
        UICorner = Roact.createElement("UICorner", {
            CornerRadius = cornerRadius or CORNER_RADIUS,
        }),
        UIStroke = Roact.createElement("UIStroke", {
            ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual,
            Color = strokeColor or STROKE_COLOR,
            LineJoinMode = Enum.LineJoinMode.Round,
            Thickness = strokeThickness or STROKE_THICKNESS,
            Transparency = strokeTransparency or STROKE_TRANSPARENCY,
        }),
        TextLabel = Roact.createElement("TextLabel", {
            Size = UDim2.fromScale(1, 1),
            TextScaled = true,
            Font = SocketSettings:GetSetting("Font"),
            BackgroundTransparency = 1,
            Text = text,
        }),
    })
end

---
---@private
---
---Asynchronously called with all other FrameworkInit()
---
function RoactButton:FrameworkInit()
    Roact = PluginFramework:Require("Roact")
    WidgetConstants = PluginFramework:Require("WidgetConstants")
    TweenConstructor = PluginFramework:Require("TweenConstructor")
    SocketController = PluginFramework:Require("SocketController")
    SocketSettings = PluginFramework:Require("SocketSettings")
end

---
---@private
---
---Synchronously called, one after the other, with all other FrameworkStart()
---
function RoactButton:FrameworkStart() end

return RoactButton
