local _

--//////////////////////////////////////////

local L = DugisLocals
local DGV = DugisGuideViewer
if not DGV then return end

local SmallFrame, Obj = DGV:RegisterModule("SmallFrame", "Objectives")--, "Guides")
DGV.SmallFrame = SmallFrame

--Table to keep information about tabs. 
-- { {guide = "", active = true, frame = {}, used = true, type = "P"}, {guide = "", active = false, frame = {}, used = true, type = "D"} }
SmallFrame.tabs = {}

if not DugisGuideUser.smallFrameTabs then
    DugisGuideUser.smallFrameTabs = {}
end

local function ObjectiveTracker_Expand(tracker)
	tracker.collapsed = nil
	tracker.BlocksFrame:Show()
	tracker.HeaderMenu.MinimizeButton:SetCollapsed(false)
	tracker.HeaderMenu.Title:Hide()
	DugisSmallFrameContainer.Background:Show()
end

local function ObjectiveTracker_Collapse(tracker)
	tracker.collapsed = true
	tracker.BlocksFrame:Hide()
	tracker.HeaderMenu.MinimizeButton:SetCollapsed(true)
	tracker.HeaderMenu.Title:Show()
	DugisSmallFrameContainer.Background:Hide()
end

function DugisSmallTracker_MinimizeButton_OnClick(self)
	PlaySound(SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON)
	local tracker = self:GetParent():GetParent()
	if tracker.collapsed then
		ObjectiveTracker_Expand(tracker);
	else
		ObjectiveTracker_Collapse(tracker);
	end
	SmallFrame:UpdateTracker()
end

local DBMUpdate
function SmallFrame:Initialize()
	if SmallFrame.initialized then return end
	SmallFrame.initialized = true
			
	local L = DugisLocals
	local flashGroup, flash
	local container = DugisSmallFrameContainer
	local tracker = container.TrackerFrame
	local header = tracker.BlocksFrame.Header
	local background = container.Background
	
	function SmallFrame:Reset()
		if DGV:IsSmallFrameFloating()	then
			container:ClearAllPoints()	
		end
	end

	function SmallFrame:OnClick(self, button)
		if button == "RightButton" then
			if DugisMainBorder:IsVisible() then
				DugisGuideViewer:HideLargeWindow()
			else
				--UIFrameFadeIn(DugisMainframe, 0.5, 0, 1)
				--UIFrameFadeIn(Dugis, 0.5, 0, 1)
				DugisGuideViewer:ShowLargeWindow()
			end
		elseif button == "LeftButton" and IsShiftKeyDown() then
			DugisGuideViewer.Modules.StickyFrame:AddRow(self.guideIndex) 
		elseif button == "LeftButton" and DGV.actions and DGV.actions[self.guideIndex] and strmatch(DGV.actions[self.guideIndex], "[CNKT]") then 
			local qid = DGV.qid[self.guideIndex]
			if qid then
				local questIndex = C_QuestLog.GetLogIndexForQuestID(qid)
				if questIndex and questIndex > 0 then 
					QuestLogPopupDetailFrame_Show( questIndex );
				end
			end
		end
	end
	
	function SmallFrame:CheckButton_OnEvent(self, event)
		local guideIndex = self:GetParent().guideIndex
		if DugisGuideUser.CurrentQuestIndex then --If a guide is loaded
			if DGV:ReturnTag("NT", guideIndex) then
				--self.Chk:SetChecked(false)
                DGV.UpdateGuideVisualRows()
			elseif guideIndex==DugisGuideUser.CurrentQuestIndex and guideIndex == DGV:GetLastUsedStepIndex() then--LastGuideNumRows then
				--self.Chk:SetChecked(false)
				DugisGuideViewer:LoadNextGuide()
                DGV.UpdateGuideVisualRows()
			else
				DugisGuideViewer:SetChkToComplete(guideIndex, true)
				if guideIndex then
                    LuaUtils:Delay(0.2, function()
                        if DugisGuideViewer:GuideOn() and DugisGuideViewer.chardb.EssentialsMode ~= 1 then
                            DugisGuideViewer:MoveToNextQuest(DugisGuideViewer:FindNextUnchecked())
                        end
                    end)
                    
                    LuaUtils:Delay(0.3, function()
                        DGV.UpdateGuideVisualRows()
                    end)
				end
			end
		end
	end

	local autoTooltipFadeTime = math.huge
	local function ResetAutoTooltip()
		if SmallFrameTooltip then SmallFrameTooltip:SetAlpha(1) end
		autoTooltipFadeTime = math.huge
	end

	local function UpdateAutoTooltip()
		local toEnd = autoTooltipFadeTime-GetTime()
		if toEnd <= 0 then 
			SmallFrameTooltip:Hide()
			ResetAutoTooltip()
		elseif toEnd <= 3 then 
			SmallFrameTooltip:SetAlpha(toEnd/3) 
		end
	end

	local tooltip = CreateFrame( "GameTooltip", "SmallFrameTooltip", nil, "GameTooltipTemplate" ); 
	local function SetTooltipOnUpdate(self, event)
		if 
			DugisGuideViewer:isValidGuide(CurrentTitle) == true and 
			DugisGuideUser.CurrentQuestIndex and
			not DGV:UserSetting(DGV_EMBEDDEDTOOLTIP)
		then

			local statusFrameTooltipText = DGV.Modules.Objectives.GetDescriptionText(self.guideIndex)
			local filename, _, _ = SmallFrameTooltipTextLeft1:GetFont() -- needed so that it doesn't overwrite font style when using other addons. 
			
			tooltip:SetOwner(self)
			tooltip:SetFrameStrata("TOOLTIP") 
			tooltip:SetParent(UIParent)
			SmallFrameTooltipTextLeft1:SetFont(filename, 12)
			tooltip:SetPadding(5, 5)
			tooltip:AddLine(statusFrameTooltipText, 1, 1, 1, 1,true)
			tooltip:Show()

			local ttwidth, ttheight, fwidth, fheight, pad = DugisGuideViewer:GetToolTipSize(tooltip)

			tooltip:ClearAllPoints()
			local anchorPoint = strupper(DugisGuideViewer:GetDB(DGV_TOOLTIPANCHOR)):gsub("%s", "")
			if anchorPoint=="DEFAULT" and DGV:IsSmallFrameFloating() then
				anchorPoint = "LEFT"
			elseif anchorPoint=="DEFAULT" then
				anchorPoint = "LEFT"
			end
			
			local toolAnchorPoint 	= ""
			toolAnchorPoint = toolAnchorPoint..((anchorPoint:find("BOTTOM.*") and "TOP") or "")
			toolAnchorPoint	= toolAnchorPoint..((anchorPoint:find("TOP.*") and "BOTTOM") or "")
			toolAnchorPoint = toolAnchorPoint..((anchorPoint:find("^RIGHT") and "LEFT") or "")
			toolAnchorPoint = toolAnchorPoint..((anchorPoint:find("^LEFT") and "RIGHT") or "")
			toolAnchorPoint = toolAnchorPoint..((anchorPoint:find(".+LEFT") and "LEFT") or "")
			toolAnchorPoint = toolAnchorPoint..((anchorPoint:find(".+RIGHT") and "RIGHT") or "")
			
			
			ResetAutoTooltip()
		end
	end
	
   
    local ticker = nil
    function SmallFrame.FadeInFadeOutTabs(speed)
        if ticker then
            ticker:Cancel()
        end

        ticker = C_Timer.NewTicker(speed or 0.02, function()
            local currentAlpha = SmallFrame.tabsBox:GetAlpha()
            
            local isMouseOver = container:IsMouseOver() or SmallFrame.tabsBox:IsMouseOver()
            
            if isMouseOver then
                currentAlpha = currentAlpha + 0.1
                if currentAlpha >= 1 then
                    currentAlpha = 1
                    ticker:Cancel()
                    ticker = nil
                end
                SmallFrame.tabsBox:SetAlpha(currentAlpha)
            else
                currentAlpha = currentAlpha - 0.1
                if currentAlpha <= 0 then
                    currentAlpha = 0
                    ticker:Cancel()
                    ticker = nil
                end
                SmallFrame.tabsBox:SetAlpha(currentAlpha)
            end
        end)
    end
    
	function SmallFrame:OnEnter(frame, event)
		SetTooltipOnUpdate(frame, event)
        self.FadeInFadeOutTabs()
        LuaUtils:Delay(2, SmallFrame.FadeInFadeOutTabs)
	end
	
	function SmallFrame:OnLeave(frame, event)
		DGV:ShowAutoTooltip(frame)
        self.FadeInFadeOutTabs()
        LuaUtils:Delay(2, SmallFrame.FadeInFadeOutTabs)
	end
	
	function SmallFrame:AlignToTop()
		local x, y = GUIUtils:GetRealFeamePos(container)
		container:ClearAllPoints()
		container:SetPoint("TOPLEFT", x, y)
	end	
	
	function SmallFrame:OnDragStart()
		if DGV:IsSmallFrameFloating() then
			container:StartMoving()
			container.isMoving = true
		end
	end

	function SmallFrame:OnDragStop()
		container:StopMovingOrSizing();
		container.isMoving = false;
		SmallFrame:AlignToTop()

		if DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP) then
			local leftTracker, topTracker = GUIUtils:GetRealFeamePos(container)
			topTracker = -topTracker
			topTracker = topTracker + container:GetHeight()
			local fromBottom = GetScreenHeight() - topTracker

			container:ClearAllPoints()
			container:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", leftTracker, fromBottom)
		end
	end	
	
	container:HookScript("OnMouseDown", SmallFrame.OnDragStart)
	container:HookScript("OnMouseUp", SmallFrame.OnDragStop)
	
	function DugisGuideViewer:ShowAutoTooltip(frame)
		frame = frame or DugisSmallFrameStatus1
		if not frame then return end
		--if 1 then return end
		if DugisGuideViewer:GetDB(DGV_SHOWTOOLTIP)==0 or (DGV.actions and DGV.actions[frame.guideIndex] and strmatch(DugisGuideViewer.actions[frame.guideIndex], "[CNK]")==nil) or DGV:UserSetting(DGV_EMBEDDEDTOOLTIP) then
			if tooltip then tooltip:Hide() end
			ResetAutoTooltip()
			return 
		end
		SetTooltipOnUpdate(frame)
		autoTooltipFadeTime = GetTime() + DugisGuideViewer:GetDB(DGV_SHOWTOOLTIP) + 3
		--SmallFrameTooltip:Show()
		tooltip:SetScript("OnUpdate", UpdateAutoTooltip)
	end
	
	function SmallFrame:PlayFlashAnimation(headerAnim)
		LuaUtils:Delay(0.1, function()
			--if header.animating then return end -- stop flash animation spam
			if not SmallFrame.FlashFrame then
				wf_flashGroup, _, SmallFrame.FlashFrame = DGV:CreateFlashFrame(background)
			end
			
			if DGV:UserSetting(DGV_SMALLFRAMEBORDER) and (DGV:UserSetting(DGV_SMALLFRAMETRANSITION) == L["Flash"] or DGV:UserSetting(DGV_SMALLFRAMETRANSITION) == L["Scroll"]) then				
				if headerAnim == true then 
					header.animating = true;
					header.HeaderOpenAnim:Stop();
					header.HeaderOpenAnim:Play();
				end 
				--DGV:DebugFormat("PlayFlashAnimation showing", "flashGroup", flashGroup)
				SmallFrame.FlashFrame:Show()
				SmallFrame.FlashFrame:SetWidth(background:GetWidth() - 14)
				SmallFrame.FlashFrame:SetHeight(background:GetHeight() - 17)
				wf_flashGroup:Stop()
				wf_flashGroup:Play()
			else
				SmallFrame.FlashFrame:Hide()
			end
		end)
	end
    
    local function GuideTypeIcon(type)
        if type == "Clear" or type == nil then
            return --"Interface\\AddOns\\DugisGuideViewerZ\\Artwork\\turnin_d"
        end
    
        for i=1, #DGV.tabs do
            local tab = DGV.tabs[i]
            if tab.guidetype == type then
                return tab.icon
            end
        end
        
        return "Interface\\Icons\\inv_level120"
    end

    function SmallFrame.ShowTabMenu(tab)
        local someGuideLoaded = (tab.type ~= "Clear" and tab.type ~= "" and tab.type ~= nil)
        local menu = {
            {text = someGuideLoaded and  "Clear Guide" or "Select Guide"  , isNotRadio = true, notCheckable = true
            , func = function() 
                if someGuideLoaded then
                    SmallFrame.SetGuideForTab(tab, "", "Clear")
                    if SmallFrame.GetActiveTab() == tab then
                    --    SmallFrame.ActivateTab(tab, true)
                    end
                    DGV.ClearGuide()
                else
                    DGV:ShowLargeWindow()
                end
            end},
            
            {text = "Close Menu", isNotRadio = true, notCheckable = true
            , func = function(itemInfo)   end}      
        }
        
        if not DugisTabMenu then
            CreateFrame("Frame", "DugisTabMenu", UIParent, "UIDropDownMenuTemplate, BackdropTemplate")
        end
        
        LuaUtils.DugisDropDown.LibDugi_EasyMenu(menu, DugisTabMenu, tab.frame, 30 , -3, "MENU", nil)
        LibDugi_DropDownList1:SetClampedToScreen(true)
        
    end
    
	local tabBorderShift = 
	{
		Default         = 0  
		,BlackGold       = 2
		,Bronze          = 0
		,DarkWood        = 0
		,ElvUI           = 3
		,Eternium        = 0
		,Gold            = 0
		,Metal           = 0
		,MetalRust       = 0
		,OnePixel        = 2
		,Stone           = 0
		,StonePattern    = 0
		,Thin            = 2
		,Wood            = 0 
	}
	function SmallFrame.UpdateTabs()
        if not DugisGuideUser.smallFrameTabs then
            DugisGuideUser.smallFrameTabs = {}
        end
    
        local buttonsY = -8
    
        local border = DugisGuideViewer:UserSetting(DGV_LARGEFRAMEBORDER)
        
        buttonsY = buttonsY - tabBorderShift[border]
        
        local tabsSpace = 37
        local lastX = -25
        for i = 1, #SmallFrame.tabs do
            local tab = SmallFrame.tabs[i]
            
            tab.frame.tab = tab
            tab.tabIndex = i
            
            if tab.used and i <= (DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_TABS_AMOUNT) or 3)+0.5 then
                tab.frame:ClearAllPoints()
                
                lastX = lastX + tabsSpace
                tab.frame:SetPoint("TOPLEFT", SmallFrame.tabsBox, "TOPLEFT", lastX, buttonsY)
                
                tab.frame.Icon:ClearAllPoints()
                tab.frame.Icon:SetSize(27, 27)
                tab.frame.Icon:SetPoint("BOTTOM", tab.frame, "BOTTOM", 1, 2)
                tab.frame.Icon:SetTexture(GuideTypeIcon(tab.type))
                
                tab.frame:Show()
            else
                tab.frame:Hide()
            end
            
            if tab.active then
                tab.frame.TabBg:SetTexCoord(0.01562500, 0.79687500, 0.78906250, 0.95703125);
            else
                tab.frame.TabBg:SetTexCoord(0.01562500, 0.79687500, 0.61328125, 0.78125000);
            end
			local tabInfo = DugisGuideUser.smallFrameTabs[i] or {}
			DugisGuideUser.smallFrameTabs[i] = tabInfo
			tabInfo.guide = tab.guide
			tabInfo.type = tab.type
			tabInfo.active = tab.active
        end
        
    end
    
	function SmallFrame.AddTab(type_, guide_, active)
    
        if  #SmallFrame.tabs >=6 then
            return 
        end
        
        local newTab = {guide = guide_ or "", used = true, active = active, type = type_}
        newTab.frame = CreateFrame("Frame", nil, SmallFrame.tabsBox, "SmallFrameTabTemplate")

        newTab.frame:SetFrameStrata("BACKGROUND")
        newTab.frame:SetFrameLevel(2)
        
        newTab.frame:SetScript("OnMouseDown", function(self, button)
            if LuaUtils:ThreadInProgress("DisplayViewTab") then
                return
            end        
            if button == "LeftButton" then
                SmallFrame.ActivateTab(newTab, true)
                if newTab.guide == "" or not newTab.guide then
                    DGV.ClearGuide()
                end                    
            else
                SmallFrame.ActivateTab(newTab, true)
                SmallFrame.ShowTabMenu(newTab)
            end
        end)
      
        SmallFrame.tabs[#SmallFrame.tabs + 1] = newTab
        
    end    
        
	function SmallFrame.ActivateTab(tab, setRelatedGuide)
        for i = 1, #SmallFrame.tabs do
            SmallFrame.tabs[i].active = false
        end
        tab.active = true
		SmallFrame.UpdateTabs()
        
        if setRelatedGuide then
            DGV:DisplayViewTabInThread(tab.guide or "", nil, true)
        end
    end  
    
	function SmallFrame.GetActiveTab()
        for i = 1, #SmallFrame.tabs do
            if SmallFrame.tabs[i].active then
                return SmallFrame.tabs[i]
            end
        end
        SmallFrame.tabs[1].active = true
        return SmallFrame.tabs[1]
    end  
    
    function SmallFrame.SetGuideForTab(tab, guide, type_)
        tab.guide = guide
        tab.type = type_
        SmallFrame.UpdateTabs()
    end     
    
	function SmallFrame.SetGuideForActiveTab(guide, type_)
        local activeTab = SmallFrame.GetActiveTab()
        SmallFrame.SetGuideForTab(activeTab, guide, type_)
    end 
    
    function SmallFrame.InitializeTabs()
    
        if not DugisGuideUser.smallFrameTabs then
            DugisGuideUser.smallFrameTabs = {}
        end
    
        if not SmallFrame.tabsBox then
            SmallFrame.tabsBox = CreateFrame("Frame", nil, Obj.ReferenceFrame)  
        end

        SmallFrame.tabsBox:ClearAllPoints()

        SmallFrame.tabsBox:SetSize(327, 67)
        SmallFrame.tabsBox:SetPoint("TOPLEFT", 1, 35)

        if DGV.chardb.EssentialsMode ~= 1 and DugisGuideViewer:GuideOn() then 
            SmallFrame.tabsBox:Show()
        end
        
        SmallFrame.tabsBox:SetAlpha(0)
            
        SmallFrame.tabsBox:SetScript("OnEnter", function(self, event)
            SmallFrame.FadeInFadeOutTabs()
            LuaUtils:Delay(2, SmallFrame.FadeInFadeOutTabs)
        end)
        
        SmallFrame.tabsBox:SetScript("OnLeave", function(self, event)
            SmallFrame.FadeInFadeOutTabs()
            LuaUtils:Delay(2, SmallFrame.FadeInFadeOutTabs)
        end)
        
        SmallFrame.tabsBox:SetFrameStrata("BACKGROUND")
        SmallFrame.tabsBox:SetFrameLevel(1)
        
        if DugisGuideUser.smallFrameTabs then
            for i=1, #DugisGuideUser.smallFrameTabs do
                local savedTabInfo = DugisGuideUser.smallFrameTabs[i]
                SmallFrame.AddTab(savedTabInfo.type, savedTabInfo.guide, savedTabInfo.active)
            end
        end
        
        SmallFrame.AddTab("Clear")
        SmallFrame.AddTab("Clear")
        SmallFrame.AddTab("Clear")
        SmallFrame.AddTab("Clear")
       
        SmallFrame.UpdateTabs()
    end
    
	SmallFrame.Load = function()
		if SmallFrame.loaded then return end
		SmallFrame.loaded = true
		
		local module = ObjectiveTracker_GetModuleInfoTable(
			"DGV_SMALL_TRACKER_MODULE", 
			DGV_TRACKER_MODULE, 
			"DugisObjectiveBlockTemplate")
		DGV_SMALL_TRACKER_MODULE = module
		module.BlocksFrame = tracker.BlocksFrame
		module:SetHeader(
			module.BlocksFrame.Header,
			L["Guides"], 
			OBJECTIVE_TRACKER_UPDATE_MODULE_DGV)

		tracker.HeaderMenu:ClearAllPoints();
		tracker.HeaderMenu:SetPoint("RIGHT", module.Header)
		tracker.HeaderMenu.Title:SetText(L["Guides"])
		--module.Header.MinimizeButton:SetPoint("RIGHT", module.Header, -20, 0)
		module.Header.MinimizeButton:Hide()

		function SmallFrame:UpdateTracker()
			if tracker.isUpdating then
				return;
			end
			tracker.isUpdating = true;
			tracker.BlocksFrame.maxHeight = math.huge
		
			tracker.BlocksFrame.currentBlock = nil;
			tracker.BlocksFrame.contentsHeight = 0;
		
			-- Gather existing headers, only newly added ones will animate
			local headerWasVisible = header.added and header:IsVisible()
		
			-- mark headers unused
			header.added = nil
		
			-- run module updates
			module:Update()
		
			module:UpdatePOIs()
			if not headerWasVisible then
				header:PlayAddAnimation()
			end
		
			-- hide unused headers
			ObjectiveTracker_CheckAndHideHeader(header)
		
			tracker.BlocksFrame.currentBlock = nil
			tracker.isUpdating = false
			container:SetHeight(tracker.BlocksFrame.contentsHeight + 30)
		end
		
		local function Shown()
			return not DGV:UserSetting(DGV_ANCHOREDSMALLFRAME) 
				and not PetBattleFrame:IsShown() 
				and not DBMUpdate
				and not DGV:IncompatibleAddonLoaded()
		end
		
		local UpdateSmallFrame_firstTime = true
		local updating
		function DGV:UpdateSmallFrame(headerAnim, dontPlayFlash)
		  DGV.DoOutOfCombatCancelOld("DGV:UpdateSmallFrame", function()
			if updating then return end
			updating = true
			local shown = Shown()
			container:SetShown(shown)
			SmallFrameTooltip:SetShown(shown)
			ObjectiveTracker_Update()
			SmallFrame:UpdateTracker()
			if not dontPlayFlash then
				SmallFrame:PlayFlashAnimation(headerAnim)
			end            

			DGV:ShowAutoTooltip()
			
			--Updating
			--container:RegisterForDrag(nil)  --argument is no longer nullable, may need to account for whatever this was meant to do
			
			DGV:SetSmallFrameBorder()

			--container:SetHeight
			DGV:WatchQuest()

			LuaUtils:Delay(1, function()
				if UpdateSmallFrame_firstTime then
					DGV.UpdateWorldQuestAutoGuide(UpdateSmallFrame_firstTime)
				end
				UpdateSmallFrame_firstTime = false
			end)
			updating = false
		  end)
		end

		function DGV:OnDBMUpdate()
			DBMUpdate = DBM.Options.HideObjectivesFrame and
				not ObjectiveTrackerFrame:IsVisible() 
			DGV:UpdateSmallFrame()
		end
		
        SmallFrame.InitializeTabs()
	end
	SmallFrame.Unload = function()
		if not SmallFrame.loaded then return end
		SmallFrame.loaded = false
		--SmallFrame:Reset()
		SmallFrameTooltip:Hide()
		container:Hide()
	end
        
    --This preloader is not visible. It just prevents mouse clicks.
    GUIUtils:CreatePreloader("SmallFramePreloader", container)
    SmallFramePreloader:SetFrameStrata("HIGH")
    SmallFramePreloader.Icon:Hide()  

	function SmallFrame:UpdateMovable()
		local floating = not DGV:UserSetting(DGV_LOCKSMALLFRAME)
		container:EnableMouse(floating)
		container:SetFrameLevel(2)
	end
    
	SmallFrame:UpdateMovable()
end