local D={}local Y=require(script:FindFirstAncestor("\080\108\117\103\105\110\070\114\097\109\101\119\111\114\107"))local R local y local c local i local v local H local I="\083\111\099\107\101\116"local p=I local g="\083\111\099\107\101\116"local F="\079\112\101\110 \083\111\099\107\101\116"local m=I local q=DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Right,true,false,200,300,250,300)local d local Q local r local u local K=false function D.Load(Y,D)local i=d and true or false if i then y:Error("\083\111\099\107\101\116 \080\108\117\103\105\110 \097\108\114\101\097\100\121 \108\111\097\100\101\100\033")return end d=D d.Deactivation:Connect(function()H:Unload()Y:DestroyWidget()end)d.Unloading:Connect(function()H:Unload()Y:DestroyWidget()end)Q=d:CreateToolbar(p)r=Q:CreateButton(g,F,v.Images.Icon.Socket)r.Click:Connect(function()Y:ToolbarButtonClicked()end)local I=c:HasSocketDirectory()local m=Y:GetSetting(R.Setting.IS_PLUGIN_ACTIVE)and true or false local q=m and I if q then Y:SetPluginActiveState(true)end y:Trace("\080\108\117\103\105\110 \076\111\097\100\101\100")end function D.SetSetting(R,D,Y)d:SetSetting(D,Y)end function D.GetSetting(Y,D)return d:GetSetting(D)end function D.ToolbarButtonClicked(D)D:SetPluginActiveState(not K)y:Trace(("\084\111\111\108\098\097\114 \066\117\116\116\111\110 \067\108\105\099\107\101\100 \040\065\099\116\105\118\101\058 \037\115\041"):format(tostring(K)))end function D.SetPluginActiveState(Y,D)local i=not(D==K)if not i then return end K=D if K then c:ValidateStructure()H:Unload()H:Load()Y:CreateWidget()c:ValidateBuiltInMacros()else H:Unload()Y:DestroyWidget()end Y:SetSetting(R.Setting.IS_PLUGIN_ACTIVE,K)r.Enabled=false r.Enabled=true r:SetActive(K)y:Trace("\080\108\117\103\105\110 \065\099\116\105\118\101\058",K)end function D.CreateWidget(D)D:DestroyWidget()u=d:CreateDockWidgetPluginGui(m,q)u.Title=m u.Enabled=true;(u:GetPropertyChangedSignal("\069\110\097\098\108\101\100")):Connect(function()if not u.Enabled then D:SetPluginActiveState(false)end end)y:Trace("\067\114\101\097\116\101\100 \087\105\100\103\101\116")i:Run()end function D.DestroyWidget(D)i:Stop()if u then u:Destroy()u=nil end y:Trace("\068\101\115\116\114\111\121\101\100 \087\105\100\103\101\116")end function D.GetWidget(D)return u end function D.GetPlugin(D)return d end function D.FrameworkInit(D)R=Y:Require("\080\108\117\103\105\110\067\111\110\115\116\097\110\116\115")y=Y:Require("\076\111\103\103\101\114")c=Y:Require("\083\116\117\100\105\111\072\097\110\100\108\101\114")i=Y:Require("\083\111\099\107\101\116\067\111\110\116\114\111\108\108\101\114")v=Y:Require("\073\109\097\103\101\085\116\105\108")H=Y:Require("\076\111\099\097\108\077\097\099\114\111\115")end function D.FrameworkStart(D) end return D
---
---Script for initialising the plugin
---
---@class PluginHandler
---
local PluginHandler = {}

--------------------------------------------------
-- Dependencies
local PluginFramework = require(script:FindFirstAncestor("PluginFramework")) ---@type Framework
local PluginConstants ---@type PluginConstants
local Logger ---@type Logger
local StudioHandler ---@type StudioHandler
local SocketController ---@type SocketController
local ImageUtil ---@type ImageUtil
local LocalMacros ---@type LocalMacros

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

--------------------------------------------------
-- Constants
local PLUGIN_NAME = "Socket"
local TOOLBAR_NAME = PLUGIN_NAME
local TOOLBAR_BUTTON_TITLE = "Socket"
local TOOLBAR_BUTTON_DESCRIPTION = "Open Socket"

local WIDGET_NAME = PLUGIN_NAME
local WIDGET_INFO = DockWidgetPluginGuiInfo.new(
    Enum.InitialDockState.Right, -- Widget will be initialized in floating panel
    true, -- Widget will be initially enabled
    false, -- Don't override the previous enabled state
    200, -- Default width of the floating window
    300, -- Default height of the floating window
    250, -- Minimum width of the floating window
    300 -- Minimum height of the floating window
)

--------------------------------------------------
-- Members
local plugin ---@type Plugin
local toolbar ---@type PluginToolbar
local toolbarButton ---@type PluginToolbarButton
local widget ---@type DockWidgetPluginGui

local isPluginActive = false ---@type boolean

---
---One time loading of the plugin
---
---@param passedPlugin Plugin
---
function PluginHandler:Load(passedPlugin)
    -- ERROR: Plugin already loaded
    local isAlreadyLoaded = plugin and true or false
    if isAlreadyLoaded then
        Logger:Error("Socket Plugin already loaded!")
        return
    end
    plugin = passedPlugin

    --------------------------------------------------
    -- Setup deactivation logic
    plugin.Deactivation:Connect(function()
        LocalMacros:Unload()
        self:DestroyWidget()
    end)
    plugin.Unloading:Connect(function()
        LocalMacros:Unload()
        self:DestroyWidget()
    end)

    --------------------------------------------------
    -- Create button on the plugin toolbar
    toolbar = plugin:CreateToolbar(TOOLBAR_NAME)
    toolbarButton = toolbar:CreateButton(TOOLBAR_BUTTON_TITLE, TOOLBAR_BUTTON_DESCRIPTION, ImageUtil.Images.Icon.Socket)

    toolbarButton.Click:Connect(function()
        self:ToolbarButtonClicked()
    end)

    --------------------------------------------------
    -- Creating widget (if previously active)
    local isSocketDetected = StudioHandler:HasSocketDirectory()
    local wasPluginActive = self:GetSetting(PluginConstants.Setting.IS_PLUGIN_ACTIVE) and true or false
    local doSetActive = wasPluginActive and isSocketDetected
    if doSetActive then
        self:SetPluginActiveState(true)
    end

    -- Debug Info
    Logger:Trace("Plugin Loaded")
end

---
---Sets the value of the given setting
---
---@param settingName string
---@param settingValue any
---
function PluginHandler:SetSetting(settingName, settingValue)
    plugin:SetSetting(settingName, settingValue)
end

---
---Returns the value of the given setting
---
---@param settingName string
---@return any
---
function PluginHandler:GetSetting(settingName)
    return plugin:GetSetting(settingName)
end

---
---@private
---
---Runs logic on what to do when we've clicked the toolbar button
---
function PluginHandler:ToolbarButtonClicked()
    -- Toggle active status
    self:SetPluginActiveState(not isPluginActive)
    Logger:Trace(("Toolbar Button Clicked (Active: %s)"):format(tostring(isPluginActive)))
end

---
---Sets the active state of the plugin (if active, button is active + widget is created!)
---
---@param isActive boolean
---
function PluginHandler:SetPluginActiveState(isActive)
    -- RETURN: Matches our current state
    local differsToCache = not (isActive == isPluginActive)
    if not differsToCache then
        return
    end
    isPluginActive = isActive

    -- Logic for when Plugin is Opened/Closed
    if isPluginActive then
        StudioHandler:ValidateStructure()

        LocalMacros:Unload() -- try unload now incase this was unsuccessful in the previous session
        LocalMacros:Load()

        self:CreateWidget()
        StudioHandler:ValidateBuiltInMacros()
    else
        LocalMacros:Unload()
        self:DestroyWidget()
    end

    -- Save as setting
    self:SetSetting(PluginConstants.Setting.IS_PLUGIN_ACTIVE, isPluginActive)

    -- Manage toolbar button state
    -- SetActive() wouldn't visually update `toolbarButton`, so an ugly hack for an ugly feature :D
    toolbarButton.Enabled = false
    toolbarButton.Enabled = true
    toolbarButton:SetActive(isPluginActive)

    Logger:Trace("Plugin Active:", isPluginActive)
end

---
---@private
---
---Create widget
---
function PluginHandler:CreateWidget()
    -- Destroy old widget
    self:DestroyWidget()

    -- Create widget
    widget = plugin:CreateDockWidgetPluginGui(WIDGET_NAME, WIDGET_INFO)
    widget.Title = WIDGET_NAME
    widget.Enabled = true

    -- Widget connections
    widget:GetPropertyChangedSignal("Enabled"):Connect(function()
        if not widget.Enabled then
            self:SetPluginActiveState(false)
        end
    end)

    -- Debug Info
    Logger:Trace("Created Widget")

    -- Inform SocketController
    SocketController:Run()
end

---
---@private
---
---Destroy widget
---
function PluginHandler:DestroyWidget()
    -- Inform SocketController
    SocketController:Stop()

    -- Destroy widget
    if widget then
        widget:Destroy()
        widget = nil
    end

    -- Debug Info
    Logger:Trace("Destroyed Widget")
end

---
---Returns the current widget of the plugin
---@return DockWidgetPluginGui
---
function PluginHandler:GetWidget()
    return widget
end

---
---@return Plugin
---
function PluginHandler:GetPlugin()
    return plugin
end

---
---@private
---
---Asynchronously called with all other FrameworkInit()
---
function PluginHandler:FrameworkInit()
    PluginConstants = PluginFramework:Require("PluginConstants")
    Logger = PluginFramework:Require("Logger")
    StudioHandler = PluginFramework:Require("StudioHandler")
    SocketController = PluginFramework:Require("SocketController")
    ImageUtil = PluginFramework:Require("ImageUtil")
    LocalMacros = PluginFramework:Require("LocalMacros")
end

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

return PluginHandler
