-- ------------------------------------------------------------------------------ --
--                                TradeSkillMaster                                --
--                http://www.curse.com/addons/wow/tradeskill-master               --
--                                                                                --
--             A TradeSkillMaster Addon (http://tradeskillmaster.com)             --
--    All Rights Reserved* - Detailed license information included with addon.    --
-- ------------------------------------------------------------------------------ --

local _, TSM = ...
local Settings = TSM.MainUI:NewPackage("Settings")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
local private = { settingPages = { top = {}, middle = {}, bottom = {}, callback = {} }, frame = nil }
local HEADER_LINE_TEXT_MARGIN = { right = 8 }
local HEADER_LINE_MARGIN = { top = 16, bottom = 16 }
local SETTING_LINE_MARGIN = { bottom = 16 }
local SETTING_LABEL_WIDTH = 400
local SHOW_TSM3_UI = true



-- ============================================================================
-- Module Functions
-- ============================================================================

function Settings.RegisterSettingPage(name, section, callback)
	tinsert(private.settingPages[section], name)
	private.settingPages.callback[name] = callback
end

function Settings.OnInitialize()
	TSM.MainUI.RegisterTopLevelPage("Settings", "iconPack.24x24/Settings", private.GetSettingsFrame)
end

function Settings.CreateHeadingLine(id, text)
	return TSMAPI_FOUR.UI.NewElement("Frame", id)
		:SetLayout("HORIZONTAL")
		:SetStyle("height", 34)
		:SetStyle("margin", HEADER_LINE_MARGIN)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Text", "text")
			:SetStyle("textColor", "#79a2ff")
			:SetStyle("fontHeight", 24)
			:SetStyle("margin", HEADER_LINE_TEXT_MARGIN)
			:SetStyle("autoWidth", true)
			:SetText(text)
		)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Texture", "vline")
			:SetStyle("color", "#e2e2e2")
			:SetStyle("height", 2)
		)
end

function Settings.CreateSettingLine(id, labelText, width)
	width = width or SETTING_LABEL_WIDTH

	return TSMAPI_FOUR.UI.NewElement("Frame", id)
		:SetLayout("HORIZONTAL")
		:SetStyle("height", 26)
		:SetStyle("margin", SETTING_LINE_MARGIN)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Text", "label")
			:SetStyle("width", width)
			:SetStyle("textColor", "#e2e2e2")
			:SetStyle("fontHeight", 18)
			:SetText(labelText)
		)
end

function Settings.PromptToReload()
	StaticPopupDialogs["TSMReloadPrompt"] = StaticPopupDialogs["TSMReloadPrompt"] or {
		text = L["You must reload your UI for these settings to take effect. Reload now?"],
		button1 = YES,
		button2 = NO,
		timeout = 0,
		OnAccept = ReloadUI,
	}
	TSMAPI_FOUR.Util.ShowStaticPopupDialog("TSMReloadPrompt")
end



-- ============================================================================
-- Settings UI
-- ============================================================================

function private.GetSettingsFrame()
	if SHOW_TSM3_UI then
		-- temporarily show the TSM3 UI since the TSM4 one isn't ready yet
		local frame = TSMAPI_FOUR.UI.NewElement("Frame", "settings")
			:SetLayout("VERTICAL")
			:SetStyle("padding", { top = 30 })
			:SetStyle("background", "#171717")
			:AddChild(TSMAPI_FOUR.UI.NewElement("Text", "text")
				:SetStyle("height", 20)
				:SetStyle("textColor", "#ff2222")
				:SetStyle("justifyH", "CENTER")
				:SetText("This is a temporary view of the TSM3 UI until this one is updated for TSM4.")
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Texture", "line")
				:SetStyle("height", 2)
				:SetStyle("color", "#9d9d9d")
				:SetStyle("margin", { top = 16, bottom = 16 })
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "content"))

		if not private.tsm3SimpleFrame then
			private.tsm3SimpleFrame = LibStub("AceGUI-3.0"):Create("TSMSimpleFrame")
			private.tsm3SimpleFrame:SetLayout("Fill")
		else
			private.tsm3SimpleFrame:Show()
		end
		if #private.tsm3SimpleFrame.children > 0 then
			private.tsm3SimpleFrame:ReleaseChildren()
		end
		private.tsm3SimpleFrame.frame:SetParent(frame:GetElement("content"):_GetBaseFrame())
		private.tsm3SimpleFrame.frame:SetAllPoints()
		TSM.Options.Load(private.tsm3SimpleFrame)
		frame:SetScript("OnHide", function()
			private.tsm3SimpleFrame:Hide()
		end)
		return frame
	end

	local defaultPage = private.settingPages.top[1]
	local frame = TSMAPI_FOUR.UI.NewElement("Frame", "settings")
		:SetLayout("HORIZONTAL")
		:SetStyle("background", "#363636")
		:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "settingNavigation")
			:SetLayout("VERTICAL")
			:SetStyle("background", "#1ae2e2e2")
			:SetStyle("width", 200)
			:SetStyle("padding", { top = 30 })
			:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "top")
				:SetLayout("VERTICAL")
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Texture", "vline")
				:SetStyle("color", "#e2e2e2")
				:SetStyle("height", 1)
				:SetStyle("margin", { right = 20, left = 20, top = 20, bottom = 20 })
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "middle")
				:SetLayout("VERTICAL")
				:SetStyle("margin", { bottom = 20 })
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "bottom")
				:SetLayout("VERTICAL")
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "spacer")
				-- make all the navigation align to the top
			)
		)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "contentFrame")
			:SetLayout("VERTICAL")
			:SetStyle("padding", { top = 30 })
			:AddChild(TSMAPI_FOUR.UI.NewElement("Text", "title")
				:SetStyle("height", 30)
				:SetStyle("fontHeight", 24)
				:SetStyle("font", TSM.UI.Fonts.bold)
				:SetStyle("justifyH", "CENTER")
				:SetText(defaultPage)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("ViewContainer", "content")
				:SetNavCallback(private.ContentNavCallback)
			)
		)
	local content = frame:GetElement("contentFrame.content")
	local settingNav = frame:GetElement("settingNavigation")
	for _, location in TSMAPI_FOUR.Util.VarargIterator("top", "middle", "bottom") do
		local navFrame = settingNav:GetElement(location)
	    for _, settingName in ipairs(private.settingPages[location]) do
			navFrame:AddChild(TSMAPI_FOUR.UI.NewElement("Button", settingName)
				:SetText(settingName)
				:SetStyle("height", 30)
				:SetStyle("justifyH", "LEFT")
				:SetStyle("margin", { left = 20 })
				:SetStyle("textColor", settingName == defaultPage and "#ffd839" or nil)
				:SetScript("OnClick", private.NavButtonOnClick)
			)
			content:AddPath(settingName, settingName == defaultPage)
		end
	end
	return frame
end

function private.ContentNavCallback(content, path)
    return TSMAPI_FOUR.UI.NewElement("Frame", "page")
		:SetLayout("VERTICAL")
		:SetStyle("padding", { top = 10 })
		:AddChild(private.settingPages.callback[path]())
end



-- ============================================================================
-- Local Script Handlers
-- ============================================================================

function private.NavButtonOnClick(self)
	local contentFrame = self:GetElement("__parent.__parent.__parent.contentFrame")
	local page = self:GetText()

	local titleText = contentFrame:GetElement("title")
	titleText:SetText(page)
	titleText:Draw()

	local settingNavigationFrame = contentFrame:GetElement("__parent.settingNavigation")
	for _, location in TSMAPI_FOUR.Util.VarargIterator("top", "middle", "bottom") do
		for _, settingName in ipairs(private.settingPages[location]) do
			private.ClearNavSelection(settingNavigationFrame, settingName, location)
		end
	end

	self:SetStyle("textColor", "#ffd839")
	self:Draw()

	contentFrame:GetElement("content"):SetPath(page, true)
end



-- ============================================================================
-- Private Helper Functions
-- ============================================================================

function private.ClearNavSelection(settingNavigationFrame, settingName, location)
	local navItem = settingNavigationFrame:GetElement(location ..".".. settingName)
	navItem:SetStyle("textColor", nil)
	navItem:Draw()
end
