--[[
	Informant - An addon for World of Warcraft that shows pertinent information about
	an item in a tooltip when you hover over the item in the game.
	Version: 3.4.6918 (SwimmingSeadragon)
	Revision: $Id: InfSettings.lua 6918 2023-01-20 18:28:56Z none $
	URL: http://auctioneeraddon.com/dl/Informant/

	Command handler. Assumes responsibility for allowing the user to set the
	options via slash command, MyAddon etc.

	License:
		This program is free software; you can redistribute it and/or
		modify it under the terms of the GNU General Public License
		as published by the Free Software Foundation; either version 2
		of the License, or (at your option) any later version.

		This program is distributed in the hope that it will be useful,
		but WITHOUT ANY WARRANTY; without even the implied warranty of
		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
		GNU General Public License for more details.

		You should have received a copy of the GNU General Public License
		along with this program(see GPL.txt); if not, write to the Free Software
		Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

	Note:
		This AddOn's source code is specifically designed to work with
		World of Warcraft's interpreted AddOn system.
		You have an implicit license to use this AddOn with these facilities
		since that is its designated purpose as per:
		http://www.fsf.org/licensing/licenses/gpl-faq.html#InterpreterIncompat


data layout:
		InformantConfig = {

			["profile.test4"] = {
				["all"] = true,
				["enable"] = true,
			},

			["profiles"] = {
				"Default", -- [1]
				"test4", -- [2]
			},

			["users.Foobar.Picksell"] = "test4",

			["profile.Default"] = {
				["miniicon.angle"] = 187,
				["miniicon.distance"] = 15,
			},

		}

if user does not have a set profile name, they get the default profile


Usage:
	def = Informant.Settings.GetDefault('TooltipShowValues')
	val = Informant.Settings.GetSetting('TooltipShowValues')
	Informant.Settings.SetSetting('TooltipShowValues', true );


]]
if not Informant then return end

Informant_RegisterRevision("$URL: Informant/InfSettings.lua $", "$Rev: 6918 $")

local lib = Informant.Settings
local gui
local debugPrint
local _TRANS = Informant.Locale.Translate

local UserSig = format("users.%s.%s", GetRealmName(), UnitName("player"))

local function getUserProfileName()
	if (not InformantConfig) then InformantConfig = {} end
	return InformantConfig[UserSig] or "Default"
end

local function getUserProfile()
	local profileName = getUserProfileName()
	if (not InformantConfig["profile."..profileName]) then
		if profileName ~= "Default" then
			profileName = "Default"
			InformantConfig[UserSig] = "Default"
		end
		if profileName == "Default" then
			InformantConfig["profile."..profileName] = {}
		end
	end
	return InformantConfig["profile."..profileName]
end


local function cleanse( profile )
	if type(profile) == "table" then
		wipe(profile)
	end
end


-- reset all settings for the current user
function lib.RestoreDefaults()
	local profile = getUserProfile()
	cleanse(profile)
end


-- Default setting values
-- moved from InfMain.lua filterDefaults
local settingDefaults = {
	['all'] = true,
	['embed'] = false,
	['show-vendor'] = true,
	['show-vendor-buy'] = true,
	['show-vendor-sell'] = true,
	['show-usage'] = true,
	['show-stack'] = true,
	['show-merchant'] = true,
	['show-zero-merchants'] = true,
	['show-quest'] = true,
	['show-ilevel'] = true,
	['show-link'] = false,
	['auto-update'] = false,
	['ModTTShow'] = "always",
	['show-binding'] = false,
	['altchatlink-tooltip'] = false,

-- leave this option off until we have real data to test with
-- enable only for dev testing
	['show-crafted'] = false,
}

local function getDefault(setting)

	-- lookup the simple settings
	local result = settingDefaults[setting];

	-- no idea what this setting is, so log it for debugging purposes
	if (result == nil) then
		debugPrint("Function GetDefault, requested key is unknown: " .. tostring(setting), "GetDefault: Unknown key", nil, "Info")
	end

	return result

end

function lib.GetDefault(setting)
	local val = getDefault(setting);
	return val;
end

local function setter(setting, value)
	if (not InformantConfig) then InformantConfig = {} end

	-- turn value into a canonical true or false
	if value == 'on' then
		value = true
	elseif value == 'off' then
		value = false
	end

	-- for defaults, just remove the value and it'll fall through
	if (value == 'default') or (value == getDefault(setting)) then
		-- Don't save default values
		value = nil
	end

	local a,b,c = strsplit(".", setting)
	if (a == "profile") then
		if (setting == "profile.save") then
			value = gui.elements["profile.name"]:GetText()

			-- Create the new profile
			InformantConfig["profile."..value] = {}

			-- Set the current profile to the new profile
			InformantConfig[UserSig] = value
			-- Get the new current profile
			local newProfile = getUserProfile()

			-- Clean it out and then resave all data
			cleanse(newProfile)
			gui:Resave()

			-- Add the new profile to the profiles list
			local profiles = InformantConfig["profiles"]
			if (not profiles) then
				profiles = { "Default" }
				InformantConfig["profiles"] = profiles
			end

			-- Check to see if it already exists
			local found = false
			for pos, name in ipairs(profiles) do
				if (name == value) then found = true end
			end

			-- If not, add it and then sort it
			if (not found) then
				table.insert(profiles, value)
				table.sort(profiles)
			end

			DEFAULT_CHAT_FRAME:AddMessage(_TRANS("INF_Help_ChatProfileSaved")..value)

		elseif (setting == "profile.delete") then
			-- User clicked the Delete button, see what the select box's value is.
			value = gui.elements["profile"].value

			-- If there's a profile name supplied
			if (value) then
				-- Clean it's profile container of values
				cleanse(InformantConfig["profile."..value])

				-- Delete it's profile container
				InformantConfig["profile."..value] = nil

				-- Find it's entry in the profiles list
				local profiles = InformantConfig["profiles"]
				if (profiles) then
					for pos, name in ipairs(profiles) do
						-- If this is it, then extract it
						if (name == value and name ~= "Default") then
							table.remove(profiles, pos)
						end
					end
				end

				-- If the user was using this one, then move them to Default
				if (getUserProfileName() == value) then
					InformantConfig[UserSig] = 'Default'
				end

				DEFAULT_CHAT_FRAME:AddMessage(_TRANS("INF_Help_ChatProfileDeleted")..value)

			end

		elseif (setting == "profile.default") then
			-- User clicked the reset settings button

			-- Get the current profile from the select box
			value = gui.elements["profile"].value

			-- Clean it's profile container of values
			InformantConfig["profile."..value] = {}

			DEFAULT_CHAT_FRAME:AddMessage(_TRANS("INF_Help_ChatProfileReset")..value)

		elseif (setting == "profile") then
			-- User selected a different value in the select box, get it
			value = gui.elements["profile"].value

			-- Change the user's current profile to this new one
			InformantConfig[UserSig] = value

			DEFAULT_CHAT_FRAME:AddMessage(_TRANS("INF_Help_ChatProfileUsing")..value)

		end

		-- Refresh all values to reflect current data
		gui:Refresh()
	elseif a == "locale" then
		local success = Informant.Locale.SetLocale(value)
		if success then
			gui:Refresh()
		end
	else
		-- Set the value for this setting in the current profile
		local db = getUserProfile()
		db[setting] = value
	end

	if (a == "sideIcon") and Informant.SideIcon then
-- not implemented yet
--		Informant.SideIcon.Update()
	end

end

function lib.SetSetting(...)
	setter(...)
	if (gui) then
		gui:Refresh()
	end
end


local function getter(setting)
	if (not InformantConfig) then InformantConfig = {} end
	if not setting then return end

	local a,b,c = strsplit(".", setting)
	if (a == 'profile') then
		if not b then -- setting == 'profile'
			return getUserProfileName()
		elseif b == 'profiles' then
			local pList = InformantConfig["profiles"]
			if (not pList) then
				pList = { "Default" }
			end
			return pList
		else -- other profile settings - no return values
			return
		end
	elseif a == "locale" then
		local _, future = Informant.Locale.GetLocale()
		return future
	end

	local db = getUserProfile()
	if ( db[setting] ~= nil ) then
		return db[setting]
	else
		return getDefault(setting)
	end
end

function lib.GetSetting(setting, default)
	local option = getter(setting)
	if ( option ~= nil ) then
		return option
	else
		return default
	end
end

local function makeGuiConfig()
	local id, last, cont
	local Configator = LibStub:GetLibrary("Configator")
	gui = Configator:Create(setter, getter)
	lib.Gui = gui

	local localelist = Informant.Locale.GetLocaleList()
	local localedropdown = {}
	for index = 1, #localelist do
		tinsert(localedropdown, {localelist[index], localelist[index]})
	end
	local function selectorLocales()
		return localedropdown
	end

  	gui:AddCat("Informant")	-- TODO - localize me!

	id = gui:AddTab("General")
	gui:AddControl(id, "Header",     0,    _TRANS('INF_Interface_GeneralOptions'))

	gui:AddControl(id, "Checkbox",   0, 1, "all", _TRANS('INF_Interface_EnableInformant') )
	gui:AddTip(id, _TRANS('INF_HelpTooltip_EnableInformant'))

	gui:AddControl(id, "Checkbox",   0, 1, "embed", _TRANS('INF_Interface_Embed') )
	gui:AddTip(id, _TRANS('INF_HelpTooltip_Embed'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-vendor", _TRANS('INF_Interface_VendorToggle'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_VendorToggle'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-vendor-buy", _TRANS('INF_Interface_ShowVendorBuy'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowVendorBuy'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-vendor-sell", _TRANS('INF_Interface_ShowVendorSell'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowVendorSell'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-usage", _TRANS('INF_Interface_ShowUsage'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowUsage'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-stack", _TRANS('INF_Interface_ShowStack'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowStack'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-merchant", _TRANS('INF_Interface_ShowMerchant'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowMerchant'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-zero-merchants", _TRANS('INF_Interface_ShowZeroMerchants'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowZeroMerchants'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-quest", _TRANS('INF_Interface_ShowQuest'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowQuest'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-ilevel", _TRANS('INF_Interface_ShowIlevel'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowIlevel'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-binding", _TRANS('INF_Interface_ShowBindinginTT'))
	gui:AddTip(id, _TRANS('INF_HelpToolTip_ShowBindingitTT'))

	gui:AddControl(id, "Checkbox",   0, 1, "show-link", _TRANS('INF_Interface_ShowLink'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowLink'))
	gui:AddControl(id, "Checkbox",   0, 1, "show-crafted", _TRANS('INF_Interface_ShowCrafted'))
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ShowCrafted'))
	gui:AddControl(id, "Subhead",     0,	_TRANS('INF_Interface_ModTTShow')) --"Show Tooltip:"
	gui:AddControl(id, "Selectbox", 0, 1, { { "always", _TRANS('INF_Interface_MTS_Always') }, {"alt", _TRANS('INF_Interface_MTS_Alt') }, { "noalt", _TRANS('INF_Interface_MTS_NoAlt') }, {"shift", _TRANS('INF_Interface_MTS_Shift') }, {"noshift", _TRANS('INF_Interface_MTS_NoShift')}, {"ctrl", _TRANS('INF_Interface_MTS_Ctrl')},{"noctrl", _TRANS('INF_Interface_MTS_NoCtrl')}, { "never", _TRANS('INF_Interface_MTS_Never')} }, "ModTTShow")
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ModTTShow')) --"Determines Tooltip behavior. Always: Show Informant's Tooltip every time. When <mod> is pressed: Only show Informant's tooltip if the specified modifier is pressed. When <mod> is not pressed: Only show Informant's tooltip if the specified modifier is not pressed. Never: Never show Informant's tooltip."
	gui:AddControl(id, "Checkbox",   0, 1, "altchatlink-tooltip", _TRANS('INF_Interface_AltChatLink')) --"Open tooltips from chat links with Alt left-clicks"
	gui:AddTip(id, _TRANS('INF_HelpTooltip_AltChatLink')) --"Enables opening a tooltip by left-clicking on an item link in chat while the Alt key is pressed."

	gui:AddControl(id, "Checkbox",   0, 1, "auto-update", _TRANS('INF_Interface_AutoUpdate')) --"Automatically update item information at merchants"
	gui:AddTip(id, _TRANS('INF_HelpTooltip_AutoUpdate')) --"Allow Informant to scan your bags and merchant inventory for updates"

	gui:AddControl(id, "Selectbox", 0, 1, selectorLocales, "locale", 60, "Change localization language (for next session)") -- "locale" is not a true setting, it gets special handling by setter and getter functions
	gui:AddTip(id, "The selected Locale takes effect after a /reload or on next login")

	-- TODO - localize me!
	gui:AddHelp(id, "what is",
		_TRANS('INF_Help_WhatIs'), --"What is Informant?"
		_TRANS('INF_Help_WhatIsAnswer')) --"Informant provides extra information about items in tooltips, in an information window, and to other addons."

	gui:AddHelp(id, "how to use information window",
		_TRANS('INF_Help_HowInfoWin'), --"How do I use the Information Window?"
		_TRANS('INF_Help_HowInfoWinAnswer')) --"You can bind a key to toggle the Informant information window to get more detailed information about items.  To do this, you need to open game options, select \"Key Bindings\" and look for Informant: Toggle Information Window."

	--Copied from ADV
	id = gui:AddTab("Profiles")

	gui:AddControl(id, "Header",     0,    _TRANS('INF_Interface_SetupProfile')) --"Setup, Configure and Edit Profiles"

	gui:AddControl(id, "Subhead",    0,    _TRANS('INF_Interface_ActivateProfile')) --"Activate a current profile"
	gui:AddControl(id, "Selectbox",  0, 1, "profile.profiles", "profile")
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ActivateProfile')) --"Select the profile that you wish to use for this character"

	gui:AddControl(id, "Button",     0, 1, "profile.delete", _TRANS('INF_Interface_Delete')) --"Delete"
	gui:AddTip(id, _TRANS('INF_HelpTooltip_DeleteProfile')) --"Deletes the currently selected profile"

	gui:AddControl(id, "Button",     0, 1, "profile.default", _TRANS('INF_Interface_DefaultProfile'))
	gui:AddTip(id, _TRANS('INF_Helptooltip_DefaultProfile')) -- Reset all settings for the current profile"

	gui:AddControl(id, "Subhead",    0,    _TRANS('INF_Interface_CreateProfile')) --"Create or replace a profile"

	gui:AddControl(id, "Text",       0, 1, "profile.name", _TRANS('INF_Interface_ProfileName')) --"New profile name:"
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ProfileName')) --"Enter the name of the profile that you wish to create"

	gui:AddControl(id, "Button",     0, 1, "profile.save", _TRANS('INF_Interface_SaveProfile')) --"Save"
	gui:AddTip(id, _TRANS('INF_HelpTooltip_ProfileSave')) --"Click this button to create or overwrite the specified profile name")

	-- TODO - localize me!
	-- these are stolen from EnhTT
	gui:AddHelp(id, "what is",
		"What is a profile?",
		"A profile is used to contain a group of settings, you can use different profiles for different characters, or switch between profiles for the same character when doing different tasks."
	)
	gui:AddHelp(id, "how to create",
		"How do I create a new profile?",
		"You enter the name of the new profile that you wish to create into the text box labelled \"New profile name\", and then click the \"Save\" button. A profile may be called whatever you wish, but it should reflect the purpose of the profile so that you may more easily recall that purpose at a later date."
	)
	gui:AddHelp(id, "how to delete",
		"How do I delete a profile?",
		"To delete a profile, simply select the profile you wish to delete with the drop-down selection box and then click the Delete button."
	)
	gui:AddHelp(id, "why delete",
		"Why would I want to delete a profile?",
		"You can delete a profile when you don't want to use it anymore, or you want to create it from scratch again with default values. Deleting a profile will also affect any other characters who are using the profile."
	)

	makeGuiConfig = nil
end

function lib.MakeGuiConfig()
	if makeGuiConfig then
		makeGuiConfig()
	end
end


-------------------------------------------------------------------------------
-- Prints the specified message to nLog.
--
-- syntax:
--    errorCode, message = debugPrint([message][, title][, errorCode][, level])
--
-- parameters:
--    message   - (string) the error message
--                nil, no error message specified
--    title     - (string) the title for the debug message
--                nil, no title specified
--    errorCode - (number) the error code
--                nil, no error code specified
--    level     - (string) nLog message level
--                         Any nLog.levels string is valid.
--                nil, no level specified
--
-- returns:
--    errorCode - (number) errorCode, if one is specified
--                nil, otherwise
--    message   - (string) message, if one is specified
--                nil, otherwise
-------------------------------------------------------------------------------
function debugPrint(message, title, errorCode, level)
	return Informant.DebugPrint(message, "InfSettings", title, errorCode, level)
end

