--	LibAddonMenu-2.0 & its files © Ryan Lakanen (Seerah)	--
--	All Rights Reserved										--
--	Permission is granted to use Seerah's LibAddonMenu-2.0	--
--	in your project. Any modifications to LibAddonMenu-2.0	--
--	may not be redistributed.								--
--------------------------------------------------------------


--Register LAM with LibStub
local MAJOR, MINOR = "LibAddonMenu-2.0", 9
local lam, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not lam then return end	--the same or newer version of this lib is already loaded into memory


--UPVALUES--
local wm = WINDOW_MANAGER
local cm = CALLBACK_MANAGER
local tinsert = table.insert
local optionsWindow = ZO_OptionsWindowSettingsScrollChild
local _

local addonsForList = {}
local addonToOptionsMap = {}
local optionsCreated = {}
local widgets = {}


--METHOD: REGISTER WIDGET--
--each widget has its version checked before loading,
--so we only have the most recent one in memory
--Usage:
--	widgetType = "string"; the type of widget being registered
--	widgetVersion = integer; the widget's version number
LAMCreateControl = LAMCreateControl or {}
local lamcc = LAMCreateControl

function lam:RegisterWidget(widgetType, widgetVersion)
	if widgets[widgetType] and widgets[widgetType] >= widgetVersion then
		return false
	else
		widgets[widgetType] = widgetVersion
		return true
	end
end


--METHOD: OPEN TO ADDON PANEL--
--opens to a specific addon's option panel
--Usage:
--	panel = userdata; the panel returned by the :RegisterOptionsPanel method
--local settings = {en = "Settings", de = "Einstellungen", fr = "Réglages"}
--local locSettings = settings[GetCVar("Language.2")]
local locSettings = GetString(SI_GAME_MENU_SETTINGS)
function lam:OpenToPanel(panel)
	SCENE_MANAGER:Show("gameMenuInGame")
	zo_callLater(function()
			ZO_GameMenu_InGame.gameMenu.headerControls[locSettings]:SetOpen(true)
			SCENE_MANAGER:AddFragment(OPTIONS_WINDOW_FRAGMENT)
			ZO_OptionsWindow_ChangePanels(lam.panelID)
			panel:SetHidden(false)
		end, 200)
end


--INTERNAL FUNCTION
--creates controls when options panel is first shown
--controls anchoring of these controls in the panel
local function CreateOptionsControls(panel)
	local addonID = panel:GetName()
	local optionsTable = addonToOptionsMap[addonID]

	if optionsTable then
		local lastAddedControl, lacAtHalfRow
		for _, widgetData in ipairs(optionsTable) do
			local widgetType = widgetData.type
			if widgetType == "submenu" then
				local submenu = LAMCreateControl[widgetType](panel, widgetData)
				if lastAddedControl then
					submenu:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
				else
					submenu:SetAnchor(TOPLEFT)
				end
				lastAddedControl = submenu
				lacAtHalfRow = false

				local lastAddedControlSub, lacAtHalfRowSub
				for _, subWidgetData in ipairs(widgetData.controls) do
					local subWidgetType = subWidgetData.type
					local subWidget = LAMCreateControl[subWidgetType](submenu, subWidgetData)
					local isHalf = subWidgetData.width == "half"
					if lastAddedControlSub then
						if lacAtHalfRowSub and isHalf then
							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, TOPRIGHT, 5, 0)
							lacAtHalfRowSub = false
						else
							subWidget:SetAnchor(TOPLEFT, lastAddedControlSub, BOTTOMLEFT, 0, 15)
							lacAtHalfRowSub = isHalf and true or false
							lastAddedControlSub = subWidget
						end
					else
						subWidget:SetAnchor(TOPLEFT)
						lacAtHalfRowSub = isHalf and true or false
						lastAddedControlSub = subWidget
					end
				end
			else
				local widget = LAMCreateControl[widgetType](panel, widgetData)
				local isHalf = widgetData.width == "half"
				if lastAddedControl then
					if lacAtHalfRow and isHalf then
						widget:SetAnchor(TOPLEFT, lastAddedControl, TOPRIGHT, 10, 0)
						lacAtHalfRow = false
					else
						widget:SetAnchor(TOPLEFT, lastAddedControl, BOTTOMLEFT, 0, 15)
						lacAtHalfRow = isHalf and true or false
						lastAddedControl = widget
					end
				else
					widget:SetAnchor(TOPLEFT)
					lacAtHalfRow = isHalf and true or false
					lastAddedControl = widget
				end
			end
		end
	end

	optionsCreated[addonID] = true
	cm:FireCallbacks("LAM-PanelControlsCreated", panel)
end


--INTERNAL FUNCTION
--handles switching between panels
local function ToggleAddonPanels(panel)	--called in OnShow of newly shown panel
	local currentlySelected = LAMAddonPanelsMenu.currentlySelected
	if currentlySelected and currentlySelected ~= panel then
		currentlySelected:SetHidden(true)
	end
	LAMAddonPanelsMenu.currentlySelected = panel

	if not optionsCreated[panel:GetName()] then	--if this is the first time opening this panel, create these options
		CreateOptionsControls(panel)
	end

	cm:FireCallbacks("LAM-RefreshPanel", panel)
end


--METHOD: REGISTER ADDON PANEL
--registers your addon with LibAddonMenu and creates a panel
--Usage:
--	addonID = "string"; unique ID which will be the global name of your panel
--	panelData = table; data object for your panel - see controls\panel.lua
function lam:RegisterAddonPanel(addonID, panelData)
	local panel = lamcc.panel(nil, panelData, addonID)	--addonID==global name of panel
	panel:SetHidden(true)
	panel:SetAnchor(TOPLEFT, LAMAddonPanelsMenu, TOPRIGHT, 10, 0)
	panel:SetAnchor(BOTTOMLEFT, LAMAddonPanelsMenu, BOTTOMRIGHT, 10, 0)
	panel:SetWidth(549)
	panel:SetDrawLayer(DL_OVERLAY)
	tinsert(addonsForList, {panel = addonID, name = panelData.name})
	panel:SetHandler("OnShow", ToggleAddonPanels)
	if panelData.slashCommand then
		SLASH_COMMANDS[panelData.slashCommand] = function()
			lam:OpenToPanel(panel)
		end
	end

	return panel	--return for authors creating options manually
end


--METHOD: REGISTER OPTION CONTROLS
--registers the options you want shown for your addon
--these are stored in a table where each key-value pair is the order
--of the options in the panel and the data for that control, respectively
--see exampleoptions.lua for an example
--see controls\<widget>.lua for each widget type
--Usage:
--	addonID = "string"; the same string passed to :RegisterAddonPanel
--	optionsTable = table; the table containing all of the options controls and their data
function lam:RegisterOptionControls(addonID, optionsTable)	--optionsTable = {sliderData, buttonData, etc}
	addonToOptionsMap[addonID] = optionsTable
end


--INTERNAL FUNCTION
--handles switching between LAM's Addon Settings panel and other panels in the Settings menu
local oldDefaultButton = ZO_OptionsWindowResetToDefaultButton
local oldCallback = oldDefaultButton.callback
local dummyFunc = function() end
local panelWindow = ZO_OptionsWindow
local bgL = ZO_OptionsWindowBGLeft
local bgR = ZO_OptionsWindowBGLeftBGRight
local function HandlePanelSwitching(panel)
	if panel == lam.panelID then	--our addon settings panel
		oldDefaultButton:SetCallback(dummyFunc)
		oldDefaultButton:SetHidden(true)
		oldDefaultButton:SetAlpha(0)	--just because it still bugs out
		panelWindow:SetDimensions(999, 960)
		bgL:SetWidth(666)
		bgR:SetWidth(333)
	else
		local shown = LAMAddonPanelsMenu.currentlySelected
		if shown then shown:SetHidden(true) end
		oldDefaultButton:SetCallback(oldCallback)
		oldDefaultButton:SetHidden(false)
		oldDefaultButton:SetAlpha(1)
		panelWindow:SetDimensions(768, 914)
		bgL:SetWidth(512)
		bgR:SetWidth(256)
	end
end


--INTERNAL FUNCTION
--creates LAM's Addon Settings panel
local function CreateAddonSettingsPanel()
	if not LAMSettingsPanelCreated then
		local controlPanelID = "LAM_ADDON_SETTINGS_PANEL"
		--Russian for TERAB1T's RuESO addon, which creates an "ru" locale
		--game font does not support Cyrillic, so they are using custom fonts + extended latin charset
		local controlPanelNames = {en = "Addon Settings", fr = "Extensions", de = "Erweiterungen", ru = "Îacòpoéêè äoïoìîeîèé"}

		ZO_OptionsWindow_AddUserPanel(controlPanelID, controlPanelNames[GetCVar("Language.2")] or controlPanelName["en"])

		lam.panelID = _G[controlPanelID]

		ZO_PreHook("ZO_OptionsWindow_ChangePanels", HandlePanelSwitching)

		LAMSettingsPanelCreated = true
	end
end


--INTERNAL FUNCTION
--adds each registered addon to the menu in LAM's panel
local function CreateAddonButtons(list, addons)
	for i = 1, #addons do
		local button = wm:CreateControlFromVirtual("LAMAddonMenuButton"..i, list.scrollChild, "ZO_DefaultTextButton")
		button.name = addons[i].name
		button.panel = _G[addons[i].panel]
		button:SetText(button.name)
		button:SetHorizontalAlignment(TEXT_ALIGN_LEFT)
		button:SetWidth(190)
		if i == 1 then
			button:SetAnchor(TOPLEFT, list.scrollChild, TOPLEFT, 5, 5)
		else
			button:SetAnchor(TOPLEFT, _G["LAMAddonMenuButton"..i-1], BOTTOMLEFT)
		end
		button:SetHandler("OnClicked", function(self) self.panel:SetHidden(false) end)
	end
end


--INTERNAL FUNCTION
--creates the left-hand menu in LAM's panel
local function CreateAddonList()
	local list
	--check if an earlier loaded copy of LAM created it already
	list = LAMAddonPanelsMenu or wm:CreateControlFromVirtual("LAMAddonPanelsMenu", optionsWindow, "ZO_ScrollContainer")
	list:ClearAnchors()
	list:SetAnchor(TOPLEFT)
	list:SetHeight(675)
	list:SetWidth(200)

	list.bg = list.bg or wm:CreateControl(nil, list, CT_BACKDROP)
	local bg = list.bg
	bg:SetAnchorFill()	--offsets of 8?
	bg:SetEdgeTexture("EsoUI\\Art\\miscellaneous\\borderedinsettransparent_edgefile.dds", 128, 16)
	bg:SetCenterColor(0, 0, 0, 0)

	list.scrollChild = LAMAddonPanelsMenuScrollChild
	list.scrollChild:SetResizeToFitPadding(0, 15)

	local generatedButtons
	list:SetHandler("OnShow", function(self)
			if not generatedButtons and #addonsForList > 0 then
				--we're about to show our list for the first time - let's sort the buttons before creating them
				table.sort(addonsForList, function(a, b)
						return a.name < b.name
					end)
				CreateAddonButtons(list, addonsForList)
				self.currentlySelected = LAMAddonMenuButton1 and LAMAddonMenuButton1.panel
				--since our addon panels don't have a parent, let's make sure they hide when we're done with them
				ZO_PreHookHandler(ZO_OptionsWindow, "OnHide", function() self.currentlySelected:SetHidden(true) end)
				generatedButtons = true
			end
			if self.currentlySelected then self.currentlySelected:SetHidden(false) end
		end)

	list.controlType = OPTIONS_CUSTOM
	list.panel = lam.panelID

	ZO_OptionsWindow_InitializeControl(list)

	return list
end


--INITIALIZING
CreateAddonSettingsPanel()
CreateAddonList()