--[[
  Name: Recount DeathTrack Module
    Author: Elsia
]]
 
if not Recount then return end --  Forget about this if no Recount is present

local Recount = Recount

RecountDeathTrack = LibStub("AceAddon-3.0"):NewAddon("RecountDeathTrack")

local RL = LibStub("AceLocale-3.0"):GetLocale("Recount")
local L = LibStub("AceLocale-3.0"):GetLocale("RecountDeathTrack")

RecountDeathTrack.Version = tonumber(string.sub("$Revision: 31 $", 12, -3))

RecountDeathTrack.store = nil
if not RecountDeathTrack.store then
	RecountDeathTrack.db2 = {}
end

local _, _, _, tocversion =  GetBuildInfo()

-- global OnInit function, only called once during addon loading
function RecountDeathTrack:OnInitialize()
end

-- global OnEnable, called everytime the user switches to the Threat Module
function RecountDeathTrack:OnEnable()

	if not Recount then return end -- No recount found

	if Recount.MainWindow and Recount.MainWindow.Rows and Recount.MainWindow.Rows[0] then
	   RecountDeathTrack:AddDropDown(Recount.MainWindow.Rows[0])
	end

	if Recount.db.profile.DeathTrackWindowVis then
	   RecountDeathTrack:ShowDeathTrack(L["Death Track"])
	end

	RecountDeathTrack:SetFight(Recount.db.profile.CurDataSet)
	
Recount.consoleOptions2.args.report.args.deathtrack = {
					name = L["Death Track"],
					desc = L["Report the DeathTrack Window Data"],
					type = 'execute',
					func = function()  Recount:ShowReport("DeathTrack",RecountDeathTrack.ReportData) end
				}
end

-- global OnDisable
function RecountDeathTrack:OnDisable()
end

function RecountDeathTrack:ShowDeathTrack(name)
	 Recount.db.profile.DeathTrackWindowVis = true
	 if not RecountDeathTrack.DeathTrackWindow then
	 	 RecountDeathTrack:CreateDeathTrackWindow()
	 else
		RecountDeathTrack.DeathTrackWindow:Show()
	end
end

function RecountDeathTrack:CreateDeathTrackWindow()
	RecountDeathTrack.DeathTrackWindow=Recount:CreateFrame("RecountDeathTrack_DeathTrackWindow",L["Death Track"],140,200,function() Recount.db.profile.DeathTrackWindowVis=true end, function() Recount.db.profile.DeathTrackWindowVis=false end)

	local theFrame=RecountDeathTrack.DeathTrackWindow

	theFrame:SetResizable(true)
	theFrame:SetMinResize(140,63)
	theFrame:SetMaxResize(400,520)		

	theFrame.SaveDeathTrackWindowPosition = RecountDeathTrack.SaveDeathTrackWindowPosition
	
	theFrame:SetScript("OnSizeChanged", function(self)
						if ( self.isResizing ) then
							RecountDeathTrack:ResizeDeathTrackWindow()
							
							Recount.db.profile.DeathTrackWindowHeight=self:GetHeight()
							Recount.db.profile.DeathTrackWindowWidth=self:GetWidth()
						end
					end)
					
	theFrame.ScrollBar=CreateFrame("SCROLLFRAME","RecountDeathTrack_DeathTrackWindow_ScrollBar",theFrame,"FauxScrollFrameTemplate")
	theFrame.ScrollBar:SetScript("OnVerticalScroll", function(self,offset) FauxScrollFrame_OnVerticalScroll(self,offset,20, RecountDeathTrack.RefreshDeathTrackWindow) end)
	Recount:SetupScrollbar("RecountDeathTrack_DeathTrackWindow_ScrollBar")

	theFrame.DragBottomRight = CreateFrame("Button", "RecountResizeGripRight", theFrame) -- Grip Buttons from Omen2
	theFrame.DragBottomRight:Show()
	theFrame.DragBottomRight:SetFrameLevel( theFrame:GetFrameLevel() + 10)
	theFrame.DragBottomRight:SetNormalTexture("Interface\\AddOns\\Recount\\ResizeGripRight")
	theFrame.DragBottomRight:SetHighlightTexture("Interface\\AddOns\\Recount\\ResizeGripRight")
	theFrame.DragBottomRight:SetWidth(16)
	theFrame.DragBottomRight:SetHeight(16)
	theFrame.DragBottomRight:SetPoint("BOTTOMRIGHT", theFrame, "BOTTOMRIGHT", 0, 0)
	theFrame.DragBottomRight:EnableMouse(true)
	theFrame.DragBottomRight:SetScript("OnMouseDown", function(self,button) if ((( not self:GetParent().isLocked ) or ( self:GetParent().isLocked == 0 ) ) and ( button == "LeftButton" ) ) then self:GetParent().isResizing = true; self:GetParent():StartSizing("BOTTOMRIGHT") end end ) -- Elsia: disallow resizing when locked.
	theFrame.DragBottomRight:SetScript("OnMouseUp", function(self,button) if self:GetParent().isResizing == true then self:GetParent():StopMovingOrSizing(); self:GetParent():SaveDeathTrackWindowPosition(); self:GetParent().isResizing = false; end end )
	theFrame.DragBottomLeft = CreateFrame("Button", "RecountResizeGripLeft", theFrame)
	theFrame.DragBottomLeft:Show()
	theFrame.DragBottomLeft:SetFrameLevel( theFrame:GetFrameLevel() + 10)
	theFrame.DragBottomLeft:SetNormalTexture("Interface\\AddOns\\Recount\\ResizeGripLeft")
	theFrame.DragBottomLeft:SetHighlightTexture("Interface\\AddOns\\Recount\\ResizeGripLeft")
	theFrame.DragBottomLeft:SetWidth(16)
	theFrame.DragBottomLeft:SetHeight(16)
	theFrame.DragBottomLeft:SetPoint("BOTTOMLEFT", theFrame, "BOTTOMLEFT", 0, 0)
	theFrame.DragBottomLeft:EnableMouse(true)
	theFrame.DragBottomLeft:SetScript("OnMouseDown", function(self,button) if ((( not self:GetParent().isLocked ) or ( self:GetParent().isLocked == 0 ) ) and ( button == "LeftButton" ) ) then self:GetParent().isResizing = true; self:GetParent():StartSizing("BOTTOMLEFT") end end ) -- Elsia: disallow resizing when locked.
	theFrame.DragBottomLeft:SetScript("OnMouseUp", function(self,button) if self:GetParent().isResizing == true then self:GetParent():StopMovingOrSizing(); self:GetParent():SaveDeathTrackWindowPosition(); self:GetParent().isResizing = false; end end )
	
	if not Recount.db.profile.Locked then
		theFrame.DragBottomRight:Show()
		theFrame.DragBottomLeft:Show()
	else
		theFrame.DragBottomRight:Hide()
		theFrame.DragBottomLeft:Hide()
	end
	
	theFrame.ReportButton=CreateFrame("Button",nil,theFrame)
	theFrame.ReportButton:SetNormalTexture("Interface\\Buttons\\UI-GuildButton-MOTD-Up.blp")
	theFrame.ReportButton:SetHighlightTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight.blp")
	theFrame.ReportButton:SetWidth(16)
	theFrame.ReportButton:SetHeight(16)
	theFrame.ReportButton:SetPoint("TOPRIGHT",theFrame,"TOPRIGHT",-40,-12)
--	theFrame.ReportButton:SetPoint("RIGHT",theFrame.ConfigButton,"LEFT",0,0)
	theFrame.ReportButton:SetScript("OnClick",function() Recount:ShowReport("DeathTrack",RecountDeathTrack.ReportData) end)
	theFrame.ReportButton:SetFrameLevel(theFrame.ReportButton:GetFrameLevel()+1)
				
	RecountDeathTrack.DeathTrackWindow.Rows={}
	RecountDeathTrack.DeathTrackWindow.CurRows=0
	RecountDeathTrack.DeathTrackWindow.RowsCreated=0
	
	RecountDeathTrack.DeathTrackWindow.DispTableSorted={}
	RecountDeathTrack.DeathTrackWindow.DispTableLookup={}

	theFrame.SavePosition=RecountDeathTrack.SaveDeathTrackWindowPosition
	if not Recount.db.profile.DeathTrackWindow then
	   theFrame:SavePosition()
	end
	RecountDeathTrack:RestoreDeathTrackWindowPosition(Recount.db.profile.DeathTrackWindow.Position.x,Recount.db.profile.DeathTrackWindow.Position.y,Recount.db.profile.DeathTrackWindow.Position.w,Recount.db.profile.DeathTrackWindow.Position.h)

	if not Recount.db.profile.DeathTrackWindowVis then
		theFrame:Hide()
	end

	Recount:AddWindow(theFrame)
end


function RecountDeathTrack:BarDropDownOpen(myframe)

	RecountDeathTrack_BarDropDownMenu = CreateFrame("Frame", "RecountDeathTrack_BarDropDownMenu", myframe);
	RecountDeathTrack_BarDropDownMenu.displayMode = "MENU";
	RecountDeathTrack_BarDropDownMenu.initialize	= RecountDeathTrack_CreateBarDropdown;
	local leftPos = myframe:GetLeft() -- Elsia: Side code adapted from Mirror
	local rightPos = myframe:GetRight()
	local side
	local oside
	if not rightPos then
		rightPos = 0
	end
	if not leftPos then
		leftPos = 0
	end

	local rightDist = GetScreenWidth() - rightPos

	if leftPos and rightDist < leftPos then
		side = "TOPLEFT"
		oside = "TOPRIGHT"
	else
		side = "TOPRIGHT"
		oside = "TOPLEFT"
	end
		UIDropDownMenu_SetAnchor(RecountDeathTrack_BarDropDownMenu , 0, 0, oside, myframe, side)
end


function RecountDeathTrack:AddDropDown(row)
	row.Name="Death Track"
	row.TooltipData="Show Death Track (Left Click)"
	row.clickData=true
	row.clickFunc=RecountDeathTrack.ShowDeathTrack
		row:SetScript("OnClick", function(self,button) 
						if button=="RightButton" then
							RecountDeathTrack:BarDropDownOpen(self)
							CloseDropDownMenus(1)
							ToggleDropDownMenu(1, nil, RecountDeathTrack_BarDropDownMenu)
						else
							RecountDeathTrack:ShowDeathTrack()						
						end
					end)
		row:SetScript("OnEnter", function(self) GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT");Recount.MainWindow:TooltipFunc(self.Name,self.TooltipData);GameTooltip:Show() end)
		row:SetScript("OnLeave", function() GameTooltip:Hide() end)
		row:EnableMouse(true)
		row:RegisterForClicks("LeftButtonDown","RightButtonUp")
end

local info = {}
function RecountDeathTrack_CreateBarDropdown(self,level)
	if (not level) then return end
	for k in pairs(info) do info[k] = nil end
	if (level == 1) then
	if self then
		info.isTitle		= 1
		info.text		= L["Death Track"]
		info.notCheckable	= 1
		UIDropDownMenu_AddButton(info, level)

		info = {}
		
		info.isTitle		= nil
		info.notCheckable	= 1
		info.disabled		= nil

		info.text		= L["Show Death Track (Left Click)"]
		info.notCheckable	= 1
		info.func = RecountDeathTrack.ShowDeathTrack
		--info.arg1 = RecountDeathTrack
		info.arg1 = self.relativeTo.name
		UIDropDownMenu_AddButton(info, level)

	end
	end
end

function RecountDeathTrack:SaveDeathTrackWindowPosition()
	local xOfs, yOfs = self:GetCenter()  -- Elsia: This is clean code straight from ckknight's pitbull
	local s = self:GetEffectiveScale()
	local uis = UIParent:GetScale()
	xOfs = xOfs*s - GetScreenWidth()*uis/2
	yOfs = yOfs*s - GetScreenHeight()*uis/2
	
	if not Recount.db.profile.DeathTrackWindow then
	   Recount.db.profile.DeathTrackWindow = {}
	   Recount.db.profile.DeathTrackWindow.Position = {}
	end

	Recount.db.profile.DeathTrackWindow.Position.x=xOfs/uis
	Recount.db.profile.DeathTrackWindow.Position.y=yOfs/uis
	Recount.db.profile.DeathTrackWindow.Position.w=self:GetWidth()
	Recount.db.profile.DeathTrackWindow.Position.h=self:GetHeight()
end

function RecountDeathTrack:RestoreDeathTrackWindowPosition(x, y, width, height)
	local f = RecountDeathTrack.DeathTrackWindow
	local s = f:GetEffectiveScale() -- Elsia: Fixed position code, with inspiration from ckknight's handing in pitbull
	local uis = UIParent:GetScale()
	f:SetPoint("CENTER", UIParent, "CENTER", x*uis/s, y*uis/s)
	f:SetWidth(width)
	f:SetHeight(height)
	RecountDeathTrack:ResizeDeathTrackWindow()
	f:SavePosition()
end

function RecountDeathTrack:ResizeDeathTrackWindow()
	--How many bars do we have now?
	local Bars=math.floor((RecountDeathTrack.DeathTrackWindow:GetHeight()-32.95)/(Recount.db.profile.MainWindow.RowHeight+Recount.db.profile.MainWindow.RowSpacing))
	
	local minbar
	
	minbar = 1

	if Bars<RecountDeathTrack.DeathTrackWindow.CurRows then
		for i=Bars+1,RecountDeathTrack.DeathTrackWindow.CurRows do
			RecountDeathTrack.DeathTrackWindow.Rows[i]:Hide()
		end
	elseif Bars>RecountDeathTrack.DeathTrackWindow.RowsCreated then
		for i=RecountDeathTrack.DeathTrackWindow.RowsCreated+1,Bars do
			RecountDeathTrack:AddDeathBar("TEST","0.0","0")
		end
	end

	RecountDeathTrack.DeathTrackWindow.CurRows=Bars
	
	--Update all the bar widths
	local CurWidth=RecountDeathTrack.DeathTrackWindow:GetWidth()-4
	for i=minbar,Bars do
		RecountDeathTrack.DeathTrackWindow.Rows[i]:Show()
		RecountDeathTrack.DeathTrackWindow.Rows[i]:SetWidth(CurWidth)
	end

	RecountDeathTrack.DeathTrackWindow.ScrollBar:SetPoint("TOPLEFT", RecountDeathTrack.DeathTrackWindow.Rows[1], "TOPLEFT", -4, 0)
	RecountDeathTrack.DeathTrackWindow.ScrollBar:SetPoint("BOTTOMRIGHT", RecountDeathTrack.DeathTrackWindow.Rows[Bars], "BOTTOMRIGHT", -4, 0)

	RecountDeathTrack:RefreshDeathTrackWindow()
end

function RecountDeathTrack:RefreshDeathTrackWindow()
	if not RecountDeathTrack.DeathTrackWindow then
		return
	end

	 if not RecountDeathTrack.CurrentDeathTrack then
	    RecountDeathTrack.CurrentDeathTrack = {}
	 end
	 local CurrentDeathTrack = RecountDeathTrack.CurrentDeathTrack
	 local Rows = RecountDeathTrack.DeathTrackWindow.Rows

	local size
	
	if CurrentDeathTrack then
		size = #CurrentDeathTrack
	else
		size = 0
	end
		
	FauxScrollFrame_Update(RecountDeathTrack.DeathTrackWindow.ScrollBar, size, RecountDeathTrack.DeathTrackWindow.CurRows, 20)

	local offset = FauxScrollFrame_GetOffset(RecountDeathTrack.DeathTrackWindow.ScrollBar)

	local vismax = math.min(#CurrentDeathTrack,RecountDeathTrack.DeathTrackWindow.CurRows)

	--Recount:DPrint(offset)
	--Recount:DPrint(vismax)
	
	 for i=1, vismax do
	     RecountDeathTrack:SetDeathRow(i,CurrentDeathTrack[i+offset])
	     Rows[i]:Show()
	 end
	 for i=vismax+1,RecountDeathTrack.DeathTrackWindow.RowsCreated do
	     Rows[i]:Hide()
	 end
end


local RowHeight=14
function RecountDeathTrack:AddDeathBar(name, deathtime, damage)

	 local i = RecountDeathTrack.DeathTrackWindow.RowsCreated + 1
	 local DeathTrack=RecountDeathTrack.DeathTrackWindow

		local Row=CreateFrame("FRAME",nil,DeathTrack)

		Row.id=i
		Row:EnableMouse(true)
		Row:SetScript("OnEnter", function(self) Row.Highlighted:Show(); RecountDeathTrack:ShowToolTip(self) end)
		Row:SetScript("OnLeave",function(self) Row.Highlighted:Hide(); GameTooltip:Hide() end)
		Row:SetScript("OnMouseDown",function(self,button) Recount:SetDeathDetails(self.Who, self.DeathLog) Recount:SetDeathLogDetails(1) end)
		
		Row:SetWidth(125+25+25-10)
		Row:SetHeight(RowHeight)
		Row:SetPoint("TOPLEFT",DeathTrack,"TOPLEFT",2,-32-(Recount.db.profile.MainWindow.RowHeight+Recount.db.profile.MainWindow.RowSpacing)*(i-1))

		Row.Selected=Row:CreateTexture(nil,"BACKGROUND")
		Row.Selected:SetAllPoints(Row)
		Row.Selected:SetTexture(1,1,0,0.3)
		Row.Selected:Hide()

		Row.Highlighted=Row:CreateTexture(nil,"BACKGROUND")
		Row.Highlighted:SetAllPoints(Row)
		Row.Highlighted:SetTexture(1,0,0,0.3)
		Row.Highlighted:Hide()

		Row.Time=Row:CreateFontString(nil,"OVERLAY","GameFontHighlightSmall")
		Row.Time:SetPoint("LEFT",Row,"LEFT",0,0)
		Row.Time:SetText(string.format("+%.2f",deathtime))
		Row.Time:SetTextColor(1.0,1.0,1.0,1.0)
		Recount:AddFontString(Row.Time)
		
		Row.Name=Row:CreateFontString(nil,"OVERLAY","GameFontNormal")
		Row.Name:SetPoint("RIGHT",Row,"RIGHT",-10,0)
		Row.Name:SetText(name)
		Row.Name:SetTextColor(1.0,1.0,1.0,1.0)
		Recount:AddFontString(Row.Name)

		Row.Damage = damage or 0
		
		RecountDeathTrack.DeathTrackWindow.Rows[i]=Row

		RecountDeathTrack.DeathTrackWindow.RowsCreated = i

end

function RecountDeathTrack:ShowToolTip(myframe)
	GameTooltip:SetOwner(myframe, "ANCHOR_TOPRIGHT")
	GameTooltip:ClearLines()
	GameTooltip:AddLine("Death",1,0.82,0)
	GameTooltip:AddDoubleLine(myframe.Name:GetText(),myframe.Time:GetText(),1,0.82,0,1,0.82,0)
	GameTooltip:AddDoubleLine(myframe.Ability,-myframe.Damage,1,1,1,1,1,1)
	GameTooltip:AddLine("<"..RL["Click for more Details"]..">",0,0.9,0)
	GameTooltip:Show()
end

function RecountDeathTrack:SetDeathRow(i, DeathTrack)
	 local Row = RecountDeathTrack.DeathTrackWindow.Rows[i]

	 Row.Name:SetText(DeathTrack.Name)
	 Row.Time:SetText(string.format("+%.2f",DeathTrack.Time))
	 Row.Who = DeathTrack.Name
	 Row.DeathLog = DeathTrack.DeathLog
	 Row.Ability = DeathTrack.Ability
	 Row.Damage = DeathTrack.Damage or 0
end

function RecountDeathTrack:AddDeath(name, deathtime, damage, who, DeathLog)

--	Recount:DPrint(name.." "..deathtime.." "..(damage or "nil"))

	local owner = name:match("<(.-)>")

	if owner then
		return
	end

	if not RecountDeathTrack.CurrentDeathTrack then
		RecountDeathTrack.CurrentDeathTrack = {}
	end

	local CurrentDeathTrack = RecountDeathTrack.CurrentDeathTrack
	local DeathTrack = {}

	DeathTrack.Name=name
	DeathTrack.Time=deathtime
	DeathTrack.Damage=damage or 0
	DeathTrack.Who=who
	DeathTrack.DeathLog=DeathLog
	DeathTrack.Ability=who.LastDamageAbility

	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	
	if not db2.DeathTrack then
		db2.DeathTrack = {}
		db2.DeathTrack.CurrentFightData = {}
	end

	if not db2.DeathTrack.CurrentFightData then
		db2.DeathTrack.CurrentFightData = {}
	end
	tinsert(db2.DeathTrack.CurrentFightData,1,DeathTrack)
	if CurrentDeathTrack ~= db2.DeathTrack.CurrentFightData then
		tinsert(CurrentDeathTrack,1,DeathTrack)
	end

	 if RecountDeathTrack.DeathTrackWindow then
	    if #CurrentDeathTrack > RecountDeathTrack.DeathTrackWindow.RowsCreated then
	       RecountDeathTrack:AddDeathBar(name, deathtime, damage,who,DeathLog)
		end

		RecountDeathTrack:RefreshDeathTrackWindow()
	end
end

function RecountDeathTrack:SetFight(fight)

	if fight == "OverallData" then
		fight = "CurrentFightData"
	end

	if not Recount.InCombat and fight == "CurrentFightData" then
		fight = "LastFightData"
	end

	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	local DeathTrack = db2.DeathTrack
	
	if DeathTrack then

		RecountDeathTrack.CurrentDeathTrack = DeathTrack[fight]
		RecountDeathTrack:RefreshDeathTrackWindow()
	end
end

function RecountDeathTrack:CopyFight()
	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	 local fights = db2.DeathTrack
	 
	 if not fights then
	    db2.DeathTrack = {}
	    fights = db2.DeathTrack
	 end

	 fights.LastFightData = fights.CurrentFightData

	if not Recount.db.profile.SegmentBosses or Recount.FightingLevel == -1 then
		fights.FightsSaved = fights.FightsSaved or 0
		if fights.FightsSaved==Recount.db.profile.MaxFights then
			ReuseFight=fights["Fight"..fights.FightsSaved]
		end
		 for i=math.min(fights.FightsSaved,Recount.db.profile.MaxFights-1),1,-1 do
		      fights["Fight"..i+1]=fights["Fight"..i]
	 	 end

	 	fights["Fight1"]=fights.CurrentFightData
		if fights.FightsSaved<Recount.db.profile.MaxFights then
			fights.FightsSaved=fights.FightsSaved+1
		end
	end
	fights["CurrentFightData"]=Recount:GetTable()
end

function RecountDeathTrack:DeleteDeathTrackEntry(i)
	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	 db2.DeathTrack["Fight"..i]=nil
end

function RecountDeathTrack:DeleteAllTracks()
	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	db2.DeathTrack = {}
	if Recount.db2 and not RecountDeathTrack.store then
		Recount.db2.DeathTrack = nil
	end
end

function RecountDeathTrack:ReportData(amount,loc,loc2)
	SendChatMessage("Recount - Death Track",loc,nil,loc2)

	local DeathTrack

	local db2 = RecountDeathTrack.store and Recount.db2 or RecountDeathTrack.db2
	if db2.DeathTrack then
	   DeathTrack = db2.DeathTrack.CurrentFightData
	end
	local Entries = 0
	if DeathTrack then Entries = math.min(#DeathTrack,amount) end

	for i=1,Entries do
	    SendChatMessage(string.format("+%.2f - "..DeathTrack[i].Name,DeathTrack[i].Time),loc,nil,loc2)
	end
end

