-- ------------------------------------------------------------------------------ --
--                                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 Macros = TSM.MainUI.Settings:NewPackage("Macros")
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster") -- loads the localization table
local private = {}
local MACRO_NAME = "TSMMacro"
local MACRO_ICON = "Achievement_Faction_GoldenLotus"
local BINDING_NAME = "MACRO "..MACRO_NAME
local BUTTON_MAPPING = {
	["row1.auctioningPostCheckbox"] = "TSMAuctioningPostButton",
	["row1.auctioningCancelCheckbox"] = "TSMAuctioningCancelButton",
	["row2.shoppingBuyoutCheckbox"] = "TSMShoppingBuyoutButton",
	["row2.shoppingBuyoutConfirmCheckbox"] = "TSMShoppingBuyoutConfirmationButton",
	-- TODO: implement once this button exists
	-- ["row3.myAuctionsCancelCheckbox"] = "",
	["row3.vendoringSellAllCheckbox"] = "TSMVendoringSellAllButton",
}
local CHARACTER_BINDING_SET = 2
local MAX_MACRO_LENGTH = 255



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

function Macros.OnInitialize()
	TSM.MainUI.Settings.RegisterSettingPage("Macros", "middle", private.GetMacrosSettingsFrame)
end



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

function private.GetMacrosSettingsFrame()
	local body = GetMacroBody(MACRO_NAME) or ""
	local upEnabled, downEnabled, altEnabled, ctrlEnabled, shiftEnabled = false, false, false, false, false
	for _, binding in TSMAPI_FOUR.Util.VarargIterator(GetBindingKey(BINDING_NAME)) do
		upEnabled = upEnabled or (strfind(binding, "MOUSEWHEELUP") and true)
		downEnabled = upEnabled or (strfind(binding, "MOUSEWHEELDOWN") and true)
		altEnabled = altEnabled or (strfind(binding, "ALT-") and true)
		ctrlEnabled = ctrlEnabled or (strfind(binding, "CTRL-") and true)
		shiftEnabled = shiftEnabled or (strfind(binding, "SHIFT-") and true)
	end
	return TSMAPI_FOUR.UI.NewElement("ScrollFrame", "macroSettings")
		:SetStyle("padding", 10)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Text")
			:SetStyle("height", 50)
			:SetText(L["Many commonly-used actions in TSM can be macro’d and bound to your scroll wheel. Select the actions you would like to include in this macro and any modifier(s) you would like to use."])
		)
		:AddChild(TSM.MainUI.Settings.CreateHeadingLine("actionsHeading", L["Bound Actions"]))
		:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "row1")
			:SetStyle("margin", { bottom = 16 })
			:SetStyle("height", 26)
			:SetLayout("HORIZONTAL")
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "auctioningPostCheckbox")
				:SetStyle("width", 400)
				:SetText(L["Auctioning 'POST' Button"])
				:SetChecked(strfind(body, BUTTON_MAPPING["row1.auctioningPostCheckbox"]) and true or false)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "auctioningCancelCheckbox")
				:SetText(L["Auctioning 'CANCEL' Button"])
				:SetChecked(strfind(body, BUTTON_MAPPING["row1.auctioningCancelCheckbox"]) and true or false)
			)
		)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "row2")
			:SetStyle("margin", { bottom = 16 })
			:SetStyle("height", 26)
			:SetLayout("HORIZONTAL")
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "shoppingBuyoutCheckbox")
				:SetStyle("width", 400)
				:SetText(L["Shopping 'BUYOUT' Button"])
				:SetChecked(strfind(body, BUTTON_MAPPING["row2.shoppingBuyoutCheckbox"]) and true or false)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "shoppingBuyoutConfirmCheckbox")
				:SetText(L["Shopping 'BUYOUT' (Confirmation) Button"])
				:SetChecked(strfind(body, BUTTON_MAPPING["row2.shoppingBuyoutConfirmCheckbox"]) and true or false)
			)
		)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Frame", "row3")
			:SetStyle("margin", { bottom = 16 })
			:SetStyle("height", 26)
			:SetLayout("HORIZONTAL")
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "myAuctionsCancelCheckbox")
				:SetStyle("width", 400)
				:SetText(L["My Auctions 'CANCEL' Button"])
				-- TODO: implement once this button exists
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "vendoringSellAllCheckbox")
				:SetText(L["Vendoring 'Sell All' Button"])
				:SetChecked(strfind(body, BUTTON_MAPPING["row3.vendoringSellAllCheckbox"]) and true or false)
			)
		)
		:AddChild(TSM.MainUI.Settings.CreateHeadingLine("configureHeading", L["Configure Scroll Wheel"]))
		:AddChild(TSM.MainUI.Settings.CreateSettingLine("direction", L["Scroll wheel direction:"])
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "upCheckbox")
				:SetStyle("width", 100)
				:SetText(L["Up"])
				:SetChecked(upEnabled)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "downCheckbox")
				:SetText(L["Down"])
				:SetChecked(downEnabled)
			)
		)
		:AddChild(TSM.MainUI.Settings.CreateSettingLine("modifiers", L["Modifiers:"])
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "altCheckbox")
				:SetStyle("width", 100)
				:SetText(L["ALT"])
				:SetChecked(altEnabled)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "ctrlCheckbox")
				:SetStyle("width", 100)
				:SetText(L["CTRL"])
				:SetChecked(ctrlEnabled)
			)
			:AddChild(TSMAPI_FOUR.UI.NewElement("Checkbox", "shiftCheckbox")
				:SetText(L["SHIFT"])
				:SetChecked(shiftEnabled)
			)
		)
		:AddChild(TSMAPI_FOUR.UI.NewElement("Button", "createBtn")
			:SetStyle("height", 25)
			:SetStyle("margin", { left = 50, right = 50 })
			:SetStyle("borderTexture", "Interface\\Addons\\TradeSkillMaster\\Media\\ButtonEdgeFrame.blp")
			:SetStyle("borderSize", 7)
			:SetText(GetMacroInfo(MACRO_NAME) and L["Replace Existing Macro"] or L["Create Macro"])
			:SetScript("OnClick", private.CreateButtonOnClick)
		)
end



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

function private.CreateButtonOnClick(self)
	-- remove the old bindings and macros
	for _, binding in TSMAPI_FOUR.Util.VarargIterator(GetBindingKey(BINDING_NAME)) do
		SetBinding(binding)
	end
	DeleteMacro(MACRO_NAME)

	-- create the new macro
	local scrollFrame = self:GetParentElement()
	local lines = TSMAPI_FOUR.Util.AcquireTempTable()
	for elementPath, buttonName in pairs(BUTTON_MAPPING) do
		if scrollFrame:GetElement(elementPath):IsChecked() then
			tinsert(lines, "/click "..buttonName)
		end
	end
	local macroText = table.concat(lines, "\n")
	CreateMacro(MACRO_NAME, MACRO_ICON, macroText)
	TSMAPI_FOUR.Util.ReleaseTempTable(lines)

	-- create the binding
	local modifierStr = ""
	if scrollFrame:GetElement("modifiers.ctrlCheckbox"):IsChecked() then
		modifierStr = modifierStr.."CTRL-"
	end
	if scrollFrame:GetElement("modifiers.altCheckbox"):IsChecked() then
		modifierStr = modifierStr.."ALT-"
	end
	if scrollFrame:GetElement("modifiers.shiftCheckbox"):IsChecked() then
		modifierStr = modifierStr.."SHIFT-"
	end
	-- we want to save these bindings to be per-character, so the mode should be 1 / 2 if we're currently on
	-- per-character bindings or not respectively
	local bindingMode = (GetCurrentBindingSet() == CHARACTER_BINDING_SET) and 1 or 2
	if scrollFrame:GetElement("direction.upCheckbox") then
		SetBinding(modifierStr.."MOUSEWHEELUP", nil, bindingMode)
		SetBinding(modifierStr.."MOUSEWHEELUP", BINDING_NAME, bindingMode)
	end
	if scrollFrame:GetElement("direction.downCheckbox") then
		SetBinding(modifierStr.."MOUSEWHEELDOWN", nil, bindingMode)
		SetBinding(modifierStr.."MOUSEWHEELDOWN", BINDING_NAME, bindingMode)
	end
	SaveBindings(CHARACTER_BINDING_SET)

	TSM:Print(L["Macro created and scroll wheel bound!"])
	if #macroText > MAX_MACRO_LENGTH then
		TSM:Print(L["WARNING: The macro was too long, so was truncated to fit by WoW."])
	end
end
