local _, ns = ...
local M, R, U, I = unpack(ns)
local Bar = M:GetModule("Actionbar")

local _G = _G
local tinsert = tinsert
local margin = R.Bars.margin

local function hasPetActionHighlightMark(index)
	return PET_ACTION_HIGHLIGHT_MARKS[index];
end

function Bar:UpdatePetBarInWW()
	local petActionButton, petActionIcon, petAutoCastOverlay;
	for i=1, NUM_PET_ACTION_SLOTS, 1 do
		petActionButton = self.actionButtons[i];
		petActionIcon = petActionButton.icon;
		petAutoCastOverlay = petActionButton.AutoCastOverlay;
		local name, texture, isToken, isActive, autoCastAllowed, autoCastEnabled, spellID = GetPetActionInfo(i);
		if ( not isToken ) then
			petActionIcon:SetTexture(texture);
			petActionButton.tooltipName = name;
		else
			petActionIcon:SetTexture(_G[texture]);
			petActionButton.tooltipName = _G[name];
		end
		petActionButton.isToken = isToken;
		if spellID then
			local spell = Spell:CreateFromSpellID(spellID);
			petActionButton.spellDataLoadedCancelFunc = spell:ContinueWithCancelOnSpellLoad(function()
				petActionButton.tooltipSubtext = spell:GetSpellSubtext();
			end);
		end
		if ( isActive ) then
			if ( IsPetAttackAction(i) ) then
				petActionButton:StartFlash();
				-- the checked texture looks a little confusing at full alpha (looks like you have an extra ability selected)
				petActionButton:GetCheckedTexture():SetAlpha(0.5);
			else
				petActionButton:StopFlash();
				petActionButton:GetCheckedTexture():SetAlpha(1.0);
			end
			petActionButton:SetChecked(true);
		else
			petActionButton:StopFlash();
			petActionButton:SetChecked(false);
		end
		petAutoCastOverlay:SetShown(autoCastAllowed);
		petAutoCastOverlay:ShowAutoCastEnabled(autoCastEnabled);
		if ( texture ) then
			if ( GetPetActionSlotUsable(i) ) then
				petActionIcon:SetVertexColor(1, 1, 1);
			else
				petActionIcon:SetVertexColor(0.4, 0.4, 0.4);
			end
			petActionIcon:Show();
		else
			petActionIcon:Hide();
		end

		SharedActionButton_RefreshSpellHighlight(petActionButton, hasPetActionHighlightMark(i));
	end
	self:UpdateCooldowns();
	self.rangeTimer = -1;
end

function Bar:UpdatePetBar()
	local petActionButton, petActionIcon, petAutoCastableTexture, petAutoCastShine;
	for i=1, NUM_PET_ACTION_SLOTS, 1 do
		petActionButton = self.actionButtons[i];
		petActionIcon = petActionButton.icon;
		petAutoCastableTexture = petActionButton.AutoCastable;
		petAutoCastShine = petActionButton.AutoCastShine;
		local name, texture, isToken, isActive, autoCastAllowed, autoCastEnabled, spellID = GetPetActionInfo(i);
		if ( not isToken ) then
			petActionIcon:SetTexture(texture);
			petActionButton.tooltipName = name;
		else
			petActionIcon:SetTexture(_G[texture]);
			petActionButton.tooltipName = _G[name];
		end
		petActionButton.isToken = isToken;
		if spellID then
			local spell = Spell:CreateFromSpellID(spellID);
			petActionButton.spellDataLoadedCancelFunc = spell:ContinueWithCancelOnSpellLoad(function()
				petActionButton.tooltipSubtext = spell:GetSpellSubtext();
			end);
		end
		if ( isActive ) then
			if ( IsPetAttackAction(i) ) then
				petActionButton:StartFlash();
				-- the checked texture looks a little confusing at full alpha (looks like you have an extra ability selected)
				petActionButton:GetCheckedTexture():SetAlpha(0.5);
			else
				petActionButton:StopFlash();
				petActionButton:GetCheckedTexture():SetAlpha(1.0);
			end
			petActionButton:SetChecked(true);
		else
			petActionButton:StopFlash();
			petActionButton:SetChecked(false);
		end
		if ( autoCastAllowed ) then
			petAutoCastableTexture:Show();
		else
			petAutoCastableTexture:Hide();
		end
		if ( autoCastEnabled ) then
			AutoCastShine_AutoCastStart(petAutoCastShine);
		else
			AutoCastShine_AutoCastStop(petAutoCastShine);
		end
		if ( texture ) then
			if ( GetPetActionSlotUsable(i) ) then
				petActionIcon:SetVertexColor(1, 1, 1);
			else
				petActionIcon:SetVertexColor(0.4, 0.4, 0.4);
			end
			petActionIcon:Show();
		else
			petActionIcon:Hide();
		end

		SharedActionButton_RefreshSpellHighlight(petActionButton, hasPetActionHighlightMark(i));
	end
	self:UpdateCooldowns();
	self.rangeTimer = -1
end

function Bar.PetBarOnEvent(event)
	if event == "PET_BAR_UPDATE_COOLDOWN" then
		PetActionBar:UpdateCooldowns()
	else
		Bar.UpdatePetBarInWW(PetActionBar)
	end
end

function Bar:CreatePetbar()
	local num = NUM_PET_ACTION_SLOTS
	local buttonList = {}

	local frame = CreateFrame("Frame", "UI_ActionBarPet", UIParent, "SecureHandlerStateTemplate")
	frame.mover = M.Mover(frame, U["Pet Actionbar"], "PetBar", {"BOTTOMRIGHT", _G.UI_ActionBar3, "TOPRIGHT", 0, -margin})
	Bar.movers[10] = frame.mover

	for i = 1, num do
		local button = _G["PetActionButton"..i]
		button:SetParent(frame)
		tinsert(buttonList, button)
		tinsert(Bar.buttons, button)
		local hotkey = button.HotKey
		if hotkey then
			hotkey:ClearAllPoints()
			hotkey:SetPoint("TOPRIGHT")
		end
	end
	frame.buttons = buttonList

	frame.frameVisibility = "[petbattle][overridebar][vehicleui][possessbar][shapeshift] hide; [pet] show; hide"
	RegisterStateDriver(frame, "visibility", frame.frameVisibility)

	-- Fix pet bar updating
	Bar:PetBarOnEvent()
	M:RegisterEvent("UNIT_PET", Bar.PetBarOnEvent)
	M:RegisterEvent("UNIT_FLAGS", Bar.PetBarOnEvent)
	M:RegisterEvent("PET_UI_UPDATE", Bar.PetBarOnEvent)
	M:RegisterEvent("PET_BAR_UPDATE", Bar.PetBarOnEvent)
	M:RegisterEvent("PLAYER_CONTROL_LOST", Bar.PetBarOnEvent)
	M:RegisterEvent("PLAYER_CONTROL_GAINED", Bar.PetBarOnEvent)
	M:RegisterEvent("PLAYER_TARGET_CHANGED", Bar.PetBarOnEvent)
	M:RegisterEvent("PET_BAR_UPDATE_USABLE", Bar.PetBarOnEvent)
	M:RegisterEvent("PET_BAR_UPDATE_COOLDOWN", Bar.PetBarOnEvent)
	M:RegisterEvent("UPDATE_VEHICLE_ACTIONBAR", Bar.PetBarOnEvent)
	M:RegisterEvent("PLAYER_MOUNT_DISPLAY_CHANGED", Bar.PetBarOnEvent)
	M:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED", Bar.PetBarOnEvent)
end