-------------------------------------------------------------------------------------------------
-- Load in global variables --
-------------------------------------------------------------------------------------------------
ArmoryStyleManager = {
	variableVersion = 1,
	color = {
		defaultText = GetInterfaceColor(INTERFACE_COLOR_TYPE_TEXT_COLORS, INTERFACE_TEXT_COLOR_NORMAL)
	}
}

local name = "ArmoryStyleManager"

local COLLECTIBLE_TYPES = {
	COLLECTIBLE_CATEGORY_TYPE_BODY_MARKING,
	COLLECTIBLE_CATEGORY_TYPE_COSTUME,
	COLLECTIBLE_CATEGORY_TYPE_FACIAL_ACCESSORY,
	COLLECTIBLE_CATEGORY_TYPE_FACIAL_HAIR_HORNS,
	COLLECTIBLE_CATEGORY_TYPE_HAIR,
	COLLECTIBLE_CATEGORY_TYPE_HAT,
	COLLECTIBLE_CATEGORY_TYPE_HEAD_MARKING,
	COLLECTIBLE_CATEGORY_TYPE_MOUNT,
	COLLECTIBLE_CATEGORY_TYPE_PERSONALITY,
	COLLECTIBLE_CATEGORY_TYPE_PIERCING_JEWELRY,
	COLLECTIBLE_CATEGORY_TYPE_POLYMORPH,
	COLLECTIBLE_CATEGORY_TYPE_SKIN,
	COLLECTIBLE_CATEGORY_TYPE_VANITY_PET
}

local ROLE_ICONS = {
	active = {
		[1] = "esoui/art/lfg/gamepad/lfg_roleicon_dps_down.dds",
		[4] = "esoui/art/lfg/gamepad/lfg_roleicon_healer_down.dds",
		[2] = "esoui/art/lfg/gamepad/lfg_roleicon_tank_down.dds",
	},
	notActive = {
		[1] = "esoui/art/lfg/gamepad/lfg_roleicon_dps_up.dds",
		[4] = "esoui/art/lfg/gamepad/lfg_roleicon_healer_up.dds",
		[2] = "esoui/art/lfg/gamepad/lfg_roleicon_tank_up.dds",
	}
}

local GRASHOROG_ID = 9745
local ZUQOTH_ID = 10618

local defaultData = {
	builds = {
		[1] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[2] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[3] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[4] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[5] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[6] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[7] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[8] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[9] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		},
		[10] = {
			locked = false,
			role = nil,
			roleActive = true,
			tabard = nil,
			collectibles = {
				[2] = 0,
				[3] = 0,
				[4] = 0,
				[9] = 0,
				[10] = 0,
				[11] = 0,
				[12] = 0,
				[13] = 0,
				[14] = 0,
				[15] = 0,
				[16] = 0,
				[17] = 0,
				[18] = 0
			}
		}
	}
}

local BUTTON_PADDING_X = 10
local BUTTON_SIZE = 45

local CURSE_ICON = {
	[0] = nil,
	[1] = "esoui/art/armory/buildicons/buildicon_44.dds",
	[2] = "esoui/art/armory/buildicons/buildicon_45.dds"
}

local function CreateOverlay(parent, rel, relPoint, x, y, width, height, vAlign, hAlign)
	local overlay = WINDOW_MANAGER:CreateControl(nil, parent, CT_LABEL)
	overlay:SetInheritScale(false)
	overlay:SetDrawTier(DT_HIGH)
	overlay:SetDrawLayer(DL_OVERLAY)
	overlay:SetAnchor(rel, parent, relPoint, x, y)
	overlay:SetHorizontalAlignment(hAlign or TEXT_ALIGN_CENTER)
	overlay:SetVerticalAlignment(vAlign or TEXT_ALIGN_CENTER)

	return overlay
end

local function CreateButton(name, parent)
	local button = WINDOW_MANAGER:CreateControl(name, parent, CT_BUTTON)

	button:SetInheritScale(false)
	button:SetDrawTier(DT_HIGH)
	button:SetDrawLayer(DL_OVERLAY)
	button:SetMouseEnabled(true)
	button:SetState(BSTATE_NORMAL)
	button:SetHorizontalAlignment(TEXT_ALIGN_CENTER)
	button:SetVerticalAlignment(TEXT_ALIGN_CENTER)
	button:SetFont("ZoFontHeader")
	button:SetNormalTexture("ESOUI/art/miscellaneous/gamepad/gp_icon_locked32.dds")

	return button
end


local function isCurrentBuildLocked()
	local currentBuildIndex = ARMORY_KEYBOARD.selectedBuildIndex
	local currentBuildLocked = ArmoryStyleManager.savedVariables.builds[currentBuildIndex].locked

	return currentBuildLocked
end

local function RefreshUI()

	local selectedBuildIndex = ARMORY_KEYBOARD.selectedBuildIndex

	-- Set the Curse Text to nothing so we can replace the long string "Curse: Werewolf" with an icon
	ArmoryStyleManager.CurseOutfitRow:GetNamedChild("CurseType"):SetText("")
	-- Set the Outfit Label to be positioned next to the Mundus label
	ArmoryStyleManager.CurseOutfitRow:GetNamedChild("Outfit"):SetAnchor(LEFT, ArmoryStyleManager.CurseOutfitRow:GetNamedChild("CurseType"), RIGHT, -ZO_ARMORY_KEYBOARD_MISC_ROW_LABEL_OFFSET_X/2, 0)

	local textWidth = ArmoryStyleManager.CurseOutfitRow:GetNamedChild("Outfit"):GetTextWidth() + ArmoryStyleManager.Mundus:GetTextWidth()

	if ArmoryStyleManager.savedVariables.currentBuildIndex == nil then
		ARMORY_KEYBOARD.buildCountLabel:SetText(zo_strformat("Current Builds: <<1>>", GetNumUnlockedArmoryBuilds()))
	else
		ARMORY_KEYBOARD.buildCountLabel:SetText(zo_strformat("Current Build: <<1>>", GetArmoryBuildName(ArmoryStyleManager.savedVariables.currentBuildIndex)))
	end

	if not selectedBuildIndex then return false end

	local nextButtonToUpdate = 1

	for index, control in ipairs(ArmoryStyleManager.UIButtons) do
		control:SetText("")
	end

	ArmoryStyleManager.UIButtons[1]:SetAnchor(LEFT, ArmoryStyleManager.UIContainer:GetNamedChild("Header"), LEFT, 295, 460)
	-- Show 4 buttons rather than 5 if the text will overlap
	if textWidth > 260 then
		ArmoryStyleManager.UIButtons[5].refreshed = true
		ArmoryStyleManager.UIButtons[1]:SetAnchor(LEFT, ArmoryStyleManager.UIContainer:GetNamedChild("Header"), LEFT, 350, 460)
	end

	function setNextButton(icon)
		control = ArmoryStyleManager.UIButtons[nextButtonToUpdate]
		control:SetText(zo_strformat("|t45:45:<<1>>|t|r", icon))
		nextButtonToUpdate = nextButtonToUpdate + 1
	end

	-- Vampire
	curseType = GetArmoryBuildCurseType(selectedBuildIndex)
	if curseType ~= 0 then
		setNextButton(CURSE_ICON[curseType])
	end

	-- Polymorph
	local hasPoly = false
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_POLYMORPH] > 1 then
		hasPoly = true
	end

	if hasPoly then
		polyIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_POLYMORPH])
		setNextButton(polyIcon)
	end

	-- Skin
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_SKIN] > 1 and not hasPoly then
		skinIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_SKIN])
		setNextButton(skinIcon)
	end

	-- Hat
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_HAT] > 1 and ArmoryStyleManager.savedVariables.builds[ARMORY_KEYBOARD.selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_HAT] ~= 5002 and not hasPoly then
		hatIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_HAT])
		setNextButton(hatIcon)
	end

	-- Costume
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_COSTUME] > 1 and not hasPoly then
		costumeIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_COSTUME])
		setNextButton(costumeIcon)
	end

	-- Mount
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_MOUNT] > 1 then
		mountIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_MOUNT])
		setNextButton(mountIcon)
	end

	-- Pet
	if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_VANITY_PET] > 1 then
		petIcon = GetCollectibleIcon(ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].collectibles[COLLECTIBLE_CATEGORY_TYPE_VANITY_PET])
		setNextButton(petIcon)
	end

	-- Lock
	if isCurrentBuildLocked() then
		ArmoryStyleManager.lockButton:SetNormalTexture("ESOUI/art/miscellaneous/gamepad/gp_icon_locked32.dds")
		ArmoryStyleManager.lockButton:SetAnchor(RIGHT, ArmoryStyleManager.Collapse, RIGHT, -30, 0)
	else
		ArmoryStyleManager.lockButton:SetNormalTexture("ESOUI/art/miscellaneous/gamepad/gp_icon_unlocked32.dds")
		ArmoryStyleManager.lockButton:SetAnchor(RIGHT, ArmoryStyleManager.Collapse, RIGHT, -27, 0)
	end

	-- Role
	local roleIcon = nil
	local currentRole = ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].role
	if currentRole then
		if ArmoryStyleManager.savedVariables.builds[selectedBuildIndex].roleActive then
			roleIcon = ROLE_ICONS.active[currentRole]
		else
			roleIcon = ROLE_ICONS.notActive[currentRole]
		end
		ArmoryStyleManager.roleButton:SetNormalTexture(roleIcon)
	else
		ArmoryStyleManager.roleButton:SetNormalTexture("")
	end
end

local function SummonAssistant(assistantId)
	local _, _, icon, _, unlocked, _, summoned = GetCollectibleInfo(assistantId)

	local summondedMsg = ""
	local colour = ""

	local iconLink = zo_strformat("|t20:20:<<1>>|t", icon)
	local collectibleLink = zo_strformat("|H1:collectible:<<1>>|h|h", assistantId)

	if unlocked then
		colour = "bfbfbf"
		summondedMsg = "You summon"
		if summoned then summondedMsg = "You dismiss" end

		UseCollectible(assistantId)
	else
		colour = "bf0000"
		summondedMsg = "You did not unlock the collectible, cannot summon"
	end

	local message = zo_strformat("|c<<1>><<2>>|r<<3>><<4>>.", colour, summondedMsg, iconLink, collectibleLink)
	d(message)
end

function ArmoryStyleManager.SummonGrashorog()
	SummonAssistant(GRASHOROG_ID)
end

function ArmoryStyleManager.SummonZuqoth()
	SummonAssistant(ZUQOTH_ID)
end

-------------------------------------------------------------------------------------------------
-- Load in the saved variables  --
-------------------------------------------------------------------------------------------------
local function InitSavedVariables()
	ArmoryStyleManager.savedVariables = ZO_SavedVars:NewCharacterIdSettings("ArmoryStyleManagerData", ArmoryStyleManager.variableVersion, nil, defaultData)
end

local function ArmoryBuildUpdated(_, buildIndex)
	local collectibles = {}
	for i, collectibleType in pairs(COLLECTIBLE_TYPES) do
		collectibles[collectibleType] = GetActiveCollectibleByType(collectibleType)
	end
	ArmoryStyleManager.savedVariables.builds[buildIndex].collectibles = collectibles
	ArmoryStyleManager.savedVariables.builds[buildIndex].title = GetTitle(GetCurrentTitleIndex())
	ArmoryStyleManager.savedVariables.builds[buildIndex].role = GetSelectedLFGRole()
	ArmoryStyleManager.savedVariables.builds[buildIndex].tabard = Id64ToString(GetItemUniqueId(BAG_WORN, EQUIP_SLOT_COSTUME))

	RefreshUI()
end


local function ArmoryBuildLoaded(_, result, buildIndex)
	if result ~= ARMORY_BUILD_RESTORE_RESULT_SUCCESS then return false end

	ArmoryStyleManager.savedVariables.currentBuildIndex = buildIndex

	for collectibleType, id in pairs(ArmoryStyleManager.savedVariables.builds[buildIndex].collectibles) do
		local eqippedCollectible = GetActiveCollectibleByType(collectibleType)
		if eqippedCollectible ~= id then
			if id ~= 0 then
				if IsCollectibleUnlocked(id) and IsCollectibleUsable(id) and IsCollectibleValidForPlayer(id) then
					UseCollectible(id)
				end
			else
				if eqippedCollectible ~= 0 then
					-- If a collectible is already equipped then we want to 'un- use' the current one
					UseCollectible(eqippedCollectible)
				end
			end
		end
	end

	local currentTitle = GetCurrentTitleIndex()

	local newTitleString = ArmoryStyleManager.savedVariables.builds[buildIndex].title
	local newTitle = nil

	local numTitles = GetNumTitles()
	for titleIdx = 0, numTitles do
		if GetTitle(titleIdx) == newTitleString then
			newTitle = titleIdx
			break
		end
	end

	if newTitle == nil then
		local errorMessage = "Invalid title saved, failed to load"
		local colour = "cb0000"

		local message = zo_strformat("<<1>>: |c<<2>><<3>>|r: <<4>>", name, colour, errorMessage, newTitleString)
		d(message)
	elseif currentTitle ~= newTitle then
		SelectTitle(newTitle)
	end

	local newRole = ArmoryStyleManager.savedVariables.builds[buildIndex].role
	local oldRole = GetSelectedLFGRole()
	if newRole then
		if newRole ~= oldRole and CanUpdateSelectedLFGRole() and ArmoryStyleManager.savedVariables.builds[buildIndex].roleActive then
			UpdateSelectedLFGRole(newRole)
		end
	end

	local tabard = ArmoryStyleManager.savedVariables.builds[buildIndex].tabard
	if tabard ~= '0' then
		local bagSize = GetBagSize(BAG_BACKPACK)
		for bagSlot = 0, bagSize do
			local id = Id64ToString(GetItemUniqueId(BAG_BACKPACK, bagSlot))
			if id == tabard then
				EquipItem(BAG_BACKPACK, bagSlot, EQUIP_SLOT_COSTUME)
			end
  		end
	else
		UnequipItem(EQUIP_SLOT_COSTUME)
	end

	RefreshUI()
end

local function RegisterEvents()
	EVENT_MANAGER:RegisterForEvent(name, EVENT_ARMORY_BUILD_UPDATED , ArmoryBuildUpdated)
	EVENT_MANAGER:RegisterForEvent(name, EVENT_ARMORY_BUILD_RESTORE_RESPONSE, ArmoryBuildLoaded)
end

local function CreateUI(control)
	local UIContainer = control:GetNamedChild("Container")
	local CurseOutfitRow = control:GetNamedChild("ContainerCurseOutfitRow")
	local Header =  UIContainer:GetNamedChild("Header")
	local Collapse =  Header:GetNamedChild("Collapse")
	local Mundus = UIContainer:GetNamedChild("Mundus")

	ArmoryStyleManager.CurseOutfitRow = CurseOutfitRow
	ArmoryStyleManager.Mundus = Mundus
	ArmoryStyleManager.UIContainer = UIContainer

	UIButtons = {}
	local lastSlotControl = nil
	for i=1,5 do
		local slotControl = CreateOverlay(CurseOutfitRow, LEFT, LEFT, 0, 0)
		slotControl:SetFont("ZoFontHeader")
		slotControl:SetDimensions(45, 45)

		if lastSlotControl then
			slotControl:SetAnchor(LEFT, lastSlotControl, RIGHT, BUTTON_PADDING_X, 0)
		else
			slotControl:SetAnchor(LEFT, UIContainer:GetNamedChild("Header"), LEFT, 295, 460)
		end

		table.insert(UIButtons, slotControl)
		lastSlotControl = slotControl
	end

	ArmoryStyleManager.UIButtons = UIButtons

	ArmoryStyleManager.lockButton = CreateButton("ArmoryStyleManager-lock", Header)
	ArmoryStyleManager.lockButton:SetDimensions(32, 32)
	ArmoryStyleManager.lockButton:SetAnchor(RIGHT, Collapse, RIGHT, -30, 0)

	ArmoryStyleManager.lockButton:SetHandler("OnMouseUp",function(self)
		local currentBuild = ArmoryStyleManager.savedVariables.builds[ARMORY_KEYBOARD.selectedBuildIndex]
		ArmoryStyleManager.savedVariables.builds[ARMORY_KEYBOARD.selectedBuildIndex].locked = not currentBuild.locked
		KEYBIND_STRIP:UpdateKeybindButtonGroup(ARMORY_KEYBOARD.keybindStripDescriptor)
		RefreshUI()
	end)

	ArmoryStyleManager.roleButton = CreateButton("ArmoryStyleManager-role", CurseOutfitRow)
	ArmoryStyleManager.roleButton:SetDimensions(45, 45)
	ArmoryStyleManager.roleButton:SetAnchor(LEFT, Collapse, LEFT, -75, 0)

	ArmoryStyleManager.roleButton:SetHandler("OnMouseUp",function(self)
		local currentBuild = ArmoryStyleManager.savedVariables.builds[ARMORY_KEYBOARD.selectedBuildIndex]
		ArmoryStyleManager.savedVariables.builds[ARMORY_KEYBOARD.selectedBuildIndex].roleActive = not currentBuild.roleActive
		RefreshUI()
	end)

	RefreshUI()
	return false
end

-------------------------------------------------------------------------------------------------
-- Initialize --
-------------------------------------------------------------------------------------------------
local function Initialize()
	InitSavedVariables()
	RegisterEvents()

	local AmoryAssistantName = GetCollectibleInfo(GRASHOROG_ID)
	ZO_CreateStringId("SI_BINDING_NAME_ARMORY_STYLE_MANAGER_SUMMON_GRASHOROG", zo_strformat("Summon <<1>>", AmoryAssistantName))

	local AmoryAssistantName = GetCollectibleInfo(ZUQOTH_ID)
	ZO_CreateStringId("SI_BINDING_NAME_ARMORY_STYLE_MANAGER_SUMMON_ZUQOTH", zo_strformat("Summon <<1>>", AmoryAssistantName))

	ZO_PreHook("ZO_Armory_ExpandedEntry_OnInitialized", CreateUI)
	ZO_PostHook("ZO_Armory_Keyboard_CollapsedEntry_OnMouseUp", RefreshUI)
	ZO_PostHook(ARMORY_KEYBOARD, "RefreshBuilds", RefreshUI)

	ARMORY_KEYBOARD.keybindStripDescriptor[2].enabled = function()
				if isCurrentBuildLocked() then return false end
                local function disabledAlertText()
                    return zo_strformat(SI_ARMORY_BUILD_OPERATION_COOLDOWN_ALERT, ZO_FormatTimeMilliseconds(ARMORY_OPERATION_COOLDOWN_DURATION_MS, TIME_FORMAT_STYLE_SHOW_LARGEST_UNIT_DESCRIPTIVE, TIME_FORMAT_PRECISION_SECONDS))
                end
                return not ZO_ARMORY_MANAGER:IsBuildOperationInProgress(), disabledAlertText
            end

	EVENT_MANAGER:UnregisterForEvent(name, EVENT_ADD_ON_LOADED)
end

local function AddonLoaded(e, addonName)
	if addonName ~= name then return end
	Initialize()
end

EVENT_MANAGER:RegisterForEvent(name, EVENT_ADD_ON_LOADED, AddonLoaded)