--Track: Blizzard_HousingTemplates/Blizzard_HousingCatalogFilters.lua


local _, addon = ...
local API = addon.API;


local After = C_Timer.After;


local REF_UNIT = 0.51399;   --Banana Length 0.52336


local MODULE_ENABLED = false;
local SHOW_REF_MODEL = false;
local MODEL_DB_KEY = "DecorModelScaleRef_ShowBanana";


local RefActors = {};
local FooterFrames = {};


local function Round(n)
	return math.floor(n * 1000 + 0.5) / 1000
end

local function ShowRefs(state)
	if state then
		for _, actor in ipairs(RefActors) do
			actor:Show();
		end
	else
		for _, actor in ipairs(RefActors) do
			actor:Hide();
		end
	end
end

local function ToggleRefs()
	SHOW_REF_MODEL = not SHOW_REF_MODEL;
	addon.SetDBValue(MODEL_DB_KEY, SHOW_REF_MODEL, true);
	ShowRefs(SHOW_REF_MODEL);
end

local function GetActorDimensions(actor)
	local bottomX, bottomY, bottomZ, topX, topY, topZ = actor:GetActiveBoundingBox();
	if bottomX and bottomY and bottomZ and topX and topY and topZ then
		local width = topX - bottomX;
		local depth = topY - bottomY;
		local height = topZ - bottomZ;
		return width, depth, height
	end
end

local function OnModelLoadedCallback(self)
	if MODULE_ENABLED then
		After(0, function()
			local scale = self:GetScale();
			local width, depth, height = GetActorDimensions(self);
			if height and self.plumberRefActor then
				self.plumberRefActor:SetScale(scale);
				self.plumberRefActor:SetPosition(0, 0, 0.5 * height);
				if SHOW_REF_MODEL then
					self.plumberRefActor:Show();
				else
					self.plumberRefActor:Hide();
				end

				local l = string.format("%.2f", Round(depth / REF_UNIT));
				local w = string.format("%.2f", Round(width / REF_UNIT));
				local h = string.format("%.2f", Round(height / REF_UNIT));
				--print(string.format("%s x %s x %s ba", l, w, h))

				self.plumberRefActor.FooterFrame:SetText(string.format("%s x %s x %s ba", l, w, h));
			end
		end);
	end
end

local function GetDeltaModifierForCameraMode(self, mode)
	if mode == 1 then
		return .008;
	elseif mode == 2 then
		return -.008;   --Reverse Pitch
	elseif mode == 3 then
		return .008;
	elseif mode == 4 then
		return .1;
	elseif mode == 5 then
		return .05;
	elseif mode == 6 then
		return .05;
	elseif mode == 7 then
		return 0.93;
	elseif mode == 8 then
		return 0.93;
	end
	return 0.0;
end


local FooterFrameMixin = {};
do
	local function OnUpdate_FadeIn(self, elapsed)
		self.alpha = self.alpha + 5 * elapsed;
		if self.alpha >= 1 then
			self.alpha = 1;
			self:SetScript("OnUpdate", nil);
		end
		self:SetAlpha(self.alpha)
	end

	local function OnUpdate_FadeOut(self, elapsed)
		self.alpha = self.alpha - 5 * elapsed;
		if self.alpha <= 0.5 then
			self.alpha = 0.5;
			self:SetScript("OnUpdate", nil);
		end
		self:SetAlpha(self.alpha)
	end

	function FooterFrameMixin:SetText(text)
		self.Text:SetText(text);
		local textWidth = self.Text:GetWrappedWidth();

		local fullSize = textWidth;
		local leftOffset = 0.5 * fullSize;
		self.Text:ClearAllPoints();
		self.Text:SetPoint("LEFT", self, "CENTER", -leftOffset, 0);

		self.BananaButton:Show();
		self:SetWidth(fullSize);

		local numButtons = 6;
		local buttonHorizontalPadding = -6;
		self.controlFrame:SetWidth(-2 + (32 + buttonHorizontalPadding) * numButtons - buttonHorizontalPadding);
	end

	function FooterFrameMixin:UpdateButton()

	end

	function FooterFrameMixin:UpdateAlpha()
		self.alpha = self:GetAlpha();
		if self:IsMouseMotionFocus() or self.BananaButton:IsMouseMotionFocus() then
			self:SetScript("OnUpdate", OnUpdate_FadeIn);
		else
			self:SetScript("OnUpdate", OnUpdate_FadeOut);
		end
	end

	function FooterFrameMixin:OnEnter()
		self:UpdateAlpha();
	end

	function FooterFrameMixin:OnLeave()
		self:UpdateAlpha();
	end

	function FooterFrameMixin:OnLoad()
		self:SetAlpha(0.5);
		self:SetScript("OnEnter", self.OnEnter);
		self:SetScript("OnLeave", self.OnLeave);
	end
end


local BananaButtonMixin = {};
do
	function BananaButtonMixin:OnEnter()
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
		GameTooltip:SetText(addon.L["Toggle Banana"]);
		GameTooltip:Show();
		self:GetParent():UpdateAlpha();
	end

	function BananaButtonMixin:OnLeave()
		GameTooltip:Hide();
		self:GetParent():UpdateAlpha();
	end

	function BananaButtonMixin:OnClick()
		ToggleRefs();
	end

	function BananaButtonMixin:OnMouseDown()
		self.Icon:SetPoint("CENTER", 1, -1);
	end

	function BananaButtonMixin:OnMouseUp()
		self.Icon:SetPoint("CENTER", 0, 0);
	end

	function BananaButtonMixin:OnShow()
		self:Update();
	end

	function BananaButtonMixin:Update()
		if SHOW_REF_MODEL then
			self.Icon:SetVertexColor(1, 1, 1);
			self.Icon:SetDesaturated(false);
		else
			self.Icon:SetVertexColor(0.72, 0.72, 0.72);
			self.Icon:SetDesaturated(true);
		end
	end

	function BananaButtonMixin:OnLoad()
		self.Icon:SetTexture("Interface/AddOns/Plumber/Art/Button/BananaButton.png");
		self.Icon:SetTexCoord(0, 48/128, 0, 48/128);

		self:SetScript("OnEnter", self.OnEnter);
		self:SetScript("OnLeave", self.OnLeave);
		self:SetScript("OnClick", self.OnClick);
		self:SetScript("OnMouseDown", self.OnMouseDown);
		self:SetScript("OnMouseUp", self.OnMouseUp);
		self:SetScript("OnShow", self.OnShow);

		addon.CallbackRegistry:RegisterSettingCallback(MODEL_DB_KEY, self.Update, self);
		self:Update();
	end
end


--Test SourceInfo
--[[
do
	--StoragePanel watcher
	local function Load()
		local f = HouseEditorFrame.StoragePanel;

		local function UpdateChatFrame()
			if f:IsVisible() then
				--if f:IsCollapsed() then
			else

			end
		end

		f:HookScript("OnShow", UpdateChatFrame)
		f:HookScript("OnHide", UpdateChatFrame);
	end

	EventUtil.ContinueOnAddOnLoaded("Blizzard_HouseEditor", Load);
	--]]


	--[[    --ElvUI Chat Fix
	local f = CreateFrame("Frame");
	f:RegisterEvent("HOUSE_EDITOR_MODE_CHANGED");

	f:SetScript("OnEvent", function(self)
		local isActive = C_HouseEditor.IsHouseEditorActive();
		if isActive ~= self.isActive then
			self.isActive = isActive;
			if isActive then
				if LeftChatPanel then
					LeftChatPanel:SetParent(HousingControlsFrame);
				end
			else
				if LeftChatPanel then
					LeftChatPanel:SetParent(ElvUIParent);
				end
			end
		end
	end);
end
--]]


local function ModelScene_OnUpdate(self, elapsed)
	if self.activeCamera then
		local yawDirection = self.yawDirection;
		local increment = self.increment;
		if yawDirection == "left" then
			self.activeCamera:AdjustYaw(-1, 0, increment);  --AdjustYaw(-1, -1, increment)
		elseif yawDirection == "right" then
			self.activeCamera:AdjustYaw(1, 0, increment);   --AdjustYaw(1, 1, increment)
		end

		self.activeCamera:OnUpdate(elapsed);
	end
end

local function SharedPreviewFrame_OnLoad(previewFrame)
	local modelScene = previewFrame.ModelScene;

	local tag = "decor";
	local actor = modelScene:GetActorByTag(tag);
	if not actor then return end;


	--NEW_ACTOR = ModelScene:CreateActor(nil, "PlumberHousingDecorActorTemplate");
	--ModelScene.tagToActor[tag] = NEW_ACTOR;
	actor:SetOnModelLoadedCallback(OnModelLoadedCallback);


	local refActor = modelScene:CreateActor();
	refActor:SetModelByFileID(647739);    --528752
	refActor:SetYaw(math.pi * 0.5);
	refActor:Hide();
	actor.plumberRefActor = refActor;
	table.insert(RefActors, refActor);


	if previewFrame.PreviewCatalogEntryInfo then
		hooksecurefunc(previewFrame, "PreviewCatalogEntryInfo", function(_, catalogEntryInfo)
			refActor:Hide();
		end);
	end

	if previewFrame.ClearPreviewData then
		hooksecurefunc(previewFrame, "ClearPreviewData", function()
			refActor:Hide();
		end);
	end

	modelScene:SetScript("OnUpdate", ModelScene_OnUpdate);


	local activeCamera = modelScene:GetActiveCamera();
	if activeCamera then
		activeCamera.GetDeltaModifierForCameraMode = GetDeltaModifierForCameraMode;
		activeCamera:SetLeftMouseButtonYMode(ORBIT_CAMERA_MOUSE_MODE_PITCH_ROTATION, true);
	end


	local controlFrame = previewFrame.ModelSceneControls;
	controlFrame:SetPoint("BOTTOM", 0, 8);


	local FooterFrame = CreateFrame("Frame", nil, modelScene);
	FooterFrame:SetSize(24, 32);
	FooterFrame:SetPoint("BOTTOM", previewFrame, "BOTTOM", 0, 32);
	Mixin(FooterFrame, FooterFrameMixin);
	FooterFrame:OnLoad();
	table.insert(FooterFrames, FooterFrame);
	FooterFrame.controlFrame = controlFrame;
	refActor.FooterFrame = FooterFrame;

	FooterFrame.Text = FooterFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
	FooterFrame.Text:SetPoint("LEFT", FooterFrame, "LEFT", 0, 0);

	local BananaButton = CreateFrame("Button", nil, FooterFrame, "PlumberModelSceneControlButtonTemplate");
	FooterFrame.BananaButton = BananaButton;
	BananaButton:SetPoint("LEFT", controlFrame.resetButton, "RIGHT", -2, 0);
	BananaButton:Hide();
	Mixin(BananaButton, BananaButtonMixin);
	BananaButton:OnLoad();


	--Slightly adjust default pitch
	hooksecurefunc(modelScene, "TransitionToModelSceneID", function()
		if MODULE_ENABLED then
			local camera = modelScene:GetActiveCamera();
			if camera then
				camera:SetPitch(15/180*3.14);
			end
		end
	end);
end

local function HousingDashboard_OnLoad()
	local modelScene = API.GetGlobalObject("HousingDashboardFrame.CatalogContent.PreviewFrame.ModelScene");
	if not modelScene then return end;
	SharedPreviewFrame_OnLoad(HousingDashboardFrame.CatalogContent.PreviewFrame);
end

local function HousingModelPreview_OnLoad()
	local modelScene = API.GetGlobalObject("HousingModelPreviewFrame.ModelPreview.ModelScene");
	if not modelScene then return end;
	SharedPreviewFrame_OnLoad(HousingModelPreviewFrame.ModelPreview);
end


local BlizzardAddOns = {
	{name = "Blizzard_HousingDashboard", callback = HousingDashboard_OnLoad},
	{name = "Blizzard_HousingModelPreview", callback = HousingModelPreview_OnLoad},
};


do
	local function EnableModule(state)
		SHOW_REF_MODEL = addon.GetDBBool(MODEL_DB_KEY);
		if state then
			for _, v in ipairs(BlizzardAddOns) do
				if not v.registered then
					v.registered = true;
					if C_AddOns.IsAddOnLoaded(v.name) then
						v.callback();
					else
						EventUtil.ContinueOnAddOnLoaded(v.name, v.callback);
					end
				end
			end
			for _, frame in ipairs(FooterFrames) do
				frame:Show();
			end
			MODULE_ENABLED = true;
		else
			MODULE_ENABLED = false;
			ShowRefs(false);
			for _, frame in ipairs(FooterFrames) do
				frame:Hide();
			end
		end
	end

	local moduleData = {
		name = addon.L["ModuleName DecorModelScaleRef"],
		dbKey ="DecorModelScaleRef",
		description = addon.L["ModuleDescription DecorModelScaleRef"],
		toggleFunc = EnableModule,
		categoryID = 1,
		uiOrder = 1,
		moduleAddedTime = 1764600000,
		categoryKeys = {
			"Housing",
		},
		searchTags = {
			"Housing",
		},
	};

	addon.ControlCenter:AddModule(moduleData);
end


--[[
PlumberHousingDecorActorMixin = CreateFromMixins(ModelSceneActorMixin);
do
	function PlumberHousingDecorActorMixin:OnModelLoaded()
		print("LOADED")
	end
end
--]]
