
KLHTM_IsLoaded = false
KLHTM_FontHackDone = false

-- Saved Variables
KLHTM_SavedVariables = 
{
	["GlobalScale"] = 18,
	["RaidRowsVisible"] = 10,
	["IsMainWindowVisible"] = true,
	["IsRaidWindowVisible"] = true,
}

KLHTM_GlobalScale = 18			-- The size of buttons and fonts
KLHTM_TableScale = 0.75			-- Multiplier of scale for table fonts
KLHTM_TableHeaderScale = 0.85	-- Multiplier of scale for tabler header fonts

-- Windows
KLHTM_MainWindow = nil
KLHTM_RaidWindow = nil

-- ggf = get global formatted
local function ggf(String, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
	return getglobal(string.format(String, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9))
end

------------------------------------------------------------------------------
--		KLHTM_Frame Events. These are called from KLHThreatMeter.xml		--
------------------------------------------------------------------------------

-- #A Called when the program starts. This is the mod's insertion point.
function KLHTM_Frame_OnLoad()
	
	this:RegisterEvent("VARIABLES_LOADED")
	-- Now go to KLHTM_OnEvent() in KLHThreatMeterMain.lua, which will go to KLHTM_StartupAfterVariablesLoaded()
	
end

function KLHTM_StartupAfterVariablesLoaded()
	
	-- Check for a saved GlobalScale
	if KLHTM_SavedVariables.GlobalScale ~= nil and KLHTM_SavedVariables.GlobalScale >= 10 and KLHTM_SavedVariables.GlobalScale <= 30 then
		KLHTM_GlobalScale = KLHTM_SavedVariables.GlobalScale
	end
	
	-- Setup the main window
	KLHTM_SetupFrame(KLHTM_Frame)
	KLHTM_MainWindow = KLHTM_NewWindowLayoutData("KLHTM_Frame", KLHTM_GetSimpleColumns())
	KLHTM_MainWindow.Label = "KLHThreatMeter " .. KLHTM_Release .. "." .. KLHTM_Revision
	KLHTM_MainWindow.ShortLabel = "KTM" .. KLHTM_Release
	KLHTM_FrameTextMain:SetText(KLHTM_MainWindow.ShortLabel)
	
	-- Setup the raid window
	KLHTM_SetupFrame(KLHTM_RaidFrame)
	KLHTM_RaidWindow = KLHTM_NewWindowLayoutData("KLHTM_RaidFrame", KLHTM_GetRaidColumns())
	KLHTM_RaidWindow.Table.IgnoreEmptyRows = false
	KLHTM_RaidWindow.Label = KLHTM_String("gui", "raidlabel")
	KLHTM_RaidWindow.ShortLabel = KLHTM_String("gui", "raidshortlabel")
	KLHTM_RaidWindow.Table.SortDirection = -1
	KLHTM_RaidFrameTextMain:SetText(KLHTM_RaidWindow.ShortLabel)
	
	-- load RowsVisible, if it's valid
	if KLHTM_SavedVariables.RaidRowsVisible > 0 and KLHTM_SavedVariables.RaidRowsVisible <= KLHTM_TableMaxRows then
		KLHTM_RaidWindow.Table.RowsVisible = KLHTM_SavedVariables.RaidRowsVisible
	end
	
	KLHTM_SetGlobalScale(KLHTM_GlobalScale) -- This will size all the fonts and buttons
	
	-- apply saved window visibility states
	if KLHTM_SavedVariables.IsMainWindowVisible == false then
		KLHTM_MainWindow.IsShown = false
		KLHTM_Frame:Hide()
	end
	
	if KLHTM_SavedVariables.IsRaidWindowVisible == false then
		KLHTM_RaidWindow.IsShown = false
		KLHTM_RaidFrame:Hide()
	end
	
	KLHTM_Startup() -- in KLHThreatMeterMain.lua
	KLHTM_MainWindow.Table.DataSource = KLHTM_MyData
	KLHTM_RaidWindow.Table.DataSource = KLHTM_RaidData
	KLHTM_IsLoaded = true
end

-- #B Those little commands that are run just once on startup for each window
function KLHTM_SetupFrame(Frame)

	-- these lines allow the form to be movable, and its position will be remembered on logout.
	Frame:RegisterForDrag("LeftButton") 
	Frame:SetMovable(true)
	Frame:SetUserPlaced(true)

	-- these are the same colours as the tooltip. 
	Frame:SetBackdropColor(0.09, 0.09, 0.19)
	Frame:SetBackdropBorderColor(1, 1, 1)
	
	-- lukon mod: initialise the bars
	for row = 1, KLHTM_TableMaxRows do
		local bar = ggf("%sTableRow%dBar", Frame:GetName(), row)
		bar:SetMinMaxValues(0, 100)
		bar:SetStatusBarColor(0.9, 0.9, 1.0, 0.9);
	end
			
end

-- #C This is called when you left click on one of the windows and start dragging.
function KLHTM_Frame_OnDragStart(Frame)
	
	local windowlayout = KLHTM_GetWindowLayoutDataFromFrame(Frame)
	
	if Frame:IsMovable() and (windowlayout.IsPinned == false) then 
		Frame:StartMoving()
	end
	
end

-- #D This is called when you release the left mouse button after dragging a window.
function KLHTM_Frame_OnDragStop(Frame)
	
	Frame:StopMovingOrSizing()
	
end

--[[ #E From XML events, we can only receive the name of the Frame that generated the event. For our own working we
need the layout data, so we have to work it out manually for each frame. ]]
function KLHTM_GetWindowLayoutDataFromFrame(Frame)

	if Frame == KLHTM_Frame then
		return KLHTM_MainWindow
	
	elseif Frame == KLHTM_RaidFrame then
		return KLHTM_RaidWindow
		
	else
		KLHTM_Print(string.format("KLHTM: The frame %s has no layout data!", Frame:GetName()))
	end

end


--------------------------------------
--		KLHTM_Frame_Button Events
--------------------------------------

-- #F Called when you click a button. Arguments are the parent frame, and a string that describes the button.
function KLHTM_Button_OnClick(Frame, Action)

	local windowlayout = KLHTM_GetWindowLayoutDataFromFrame(Frame)

	if Action == "Close" then
		windowlayout.IsShown = false
		Frame:Hide()
		
		-- redo saved variables
		if Frame == KLHTM_Frame then
			KLHTM_SavedVariables.IsMainWindowVisible = false
		else
			KLHTM_SavedVariables.IsRaidWindowVisible = false
		end
	
	elseif Action == "Pin" then
		
		windowlayout.IsPinned = not windowlayout.IsPinned
	
	elseif Action == "Minimise" then
		
		windowlayout.IsMinimised = not windowlayout.IsMinimised
		
		if windowlayout.IsMinimised == false then
			ggf("%sTextMain", windowlayout.Name):SetText(windowlayout.Label)
			KLHTM_RedrawTable(windowlayout)
			
		else
			ggf("%sTextMain", windowlayout.Name):SetText(windowlayout.ShortLabel)
		end
		
		KLHTM_UpdateFrameBounds(windowlayout)
	
	elseif Action == "ShowOther" then
		
		-- get the other frame
		if Frame == KLHTM_Frame then
			Frame = KLHTM_RaidFrame
		else
			Frame = KLHTM_Frame
		end
		
		-- get other layout
		windowlayout = KLHTM_GetWindowLayoutDataFromFrame(Frame)
		windowlayout.IsShown = not windowlayout.IsShown
		
		-- save variables
		if Frame == KLHTM_Frame then
			KLHTM_SavedVariables.IsMainWindowVisible = windowlayout.IsShown
		else
			KLHTM_SavedVariables.IsRaidWindowVisible = windowlayout.IsShown
		end
		
		if windowlayout.IsShown == true then
			Frame:Show()
		else
			Frame:Hide()
		end
		
	elseif Action == "Clear" then
				
		if Frame == KLHTM_RaidFrame then
			-- you can only clear everyone if you are leader / assist
			if KLHTM_IsPlayerOfficer(UnitName("player")) == true then
				KLHTM_SendMessage("clear")
			
			else
				KLHTM_ResetMyData("Raid")
			end
		
		else -- Main Frame
			KLHTM_ResetMyData("Main")
		end
		
	else
		KLHTM_Print(string.format("Unhandled Button Click! Frame = %s, Action = %s.", Frame:GetName(), Action))
	end

end

-- #G Called when the mouse enters the region of a button. Brings up the tooltip window. Doesn't really work yet.
function KLHTM_Button_OnEnter(id, description)

	GameTooltip_AddNewbieTip(id .. " Button", 1, 1, 1, description)
	return
	
end


function KLHTM_Button_OnLeave()

	GameTooltip:Hide()

end

---------------------------------------
--		GUI Layout Management
---------------------------------------

-- #H Update the border, mainly. Argument is a windowlayout structure. Also moves the buttons.
function KLHTM_UpdateFrameBounds(Window)

	-- Set TextMain length
	KLHTM_SizeFontStringToText(ggf("%sTextMain", Window.Name), KLHTM_GlobalScale, ggf(Window.Name))
		
	-- width: 5 + 5 for borders. 5 buttons. text box. + 5 gap after text box.
	local headerwidth = 15 + ggf("%sTextMain", Window.Name):GetWidth() + 5 * KLHTM_GlobalScale
	
	-- now see if the table width is more
	local tablewidth = 10 -- borders
	for x = 1, Window.Table.Columns do
		tablewidth = tablewidth + ggf("%sTableRowLabelText%d", Window.Name, x):GetWidth()
	end
	
	-- lukon mod: set bar widths
	for row = 1, KLHTM_TableMaxRows do
		bar = ggf("%sTableRow%dBar", Window.Name, row);
		bar:SetWidth(tablewidth - 13);
	end
	
	local headerheight = 10 + ggf("%sTextMain", Window.Name):GetHeight()
	local totalheight
	
	if Window.IsMinimised == true then
		totalheight = headerheight
		ggf("%sTable", Window.Name):Hide()
		ggf(Window.Name):SetWidth(headerwidth)
		
	else
		ggf(Window.Name):SetWidth(math.max(headerwidth, tablewidth))
		ggf("%sTable", Window.Name):SetWidth(math.max(headerwidth, tablewidth))
		totalheight = headerheight + KLHTM_GlobalScale * KLHTM_TableHeaderScale + Window.Table.Rows * (KLHTM_GlobalScale * KLHTM_TableScale)
		ggf("%sTable", Window.Name):Show()
	end
	
	ggf("%sTable", Window.Name):SetHeight(totalheight - headerheight)
	ggf(Window.Name):SetHeight(totalheight)
	
end

-- #I Makes everything bigger or smaller.
function KLHTM_SetGlobalScale(scale)
	KLHTM_GlobalScale = scale
	KLHTM_SavedVariables.GlobalScale = scale
	
	KLHTM_RescaleWindow(KLHTM_MainWindow)
	KLHTM_RescaleWindow(KLHTM_RaidWindow)
end

function KLHTM_RescaleWindow(Window)

	ggf("%sTextMain", Window.Name):SetTextHeight(KLHTM_GlobalScale)
	ggf("%sTextMain", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sPin", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sPin", Window.Name):SetWidth(KLHTM_GlobalScale)
	ggf("%sMinimise", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sMinimise", Window.Name):SetWidth(KLHTM_GlobalScale)
	ggf("%sClose", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sClose", Window.Name):SetWidth(KLHTM_GlobalScale)
	ggf("%sShowOther", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sShowOther", Window.Name):SetWidth(KLHTM_GlobalScale)
	ggf("%sClear", Window.Name):SetHeight(KLHTM_GlobalScale)
	ggf("%sClear", Window.Name):SetWidth(KLHTM_GlobalScale)
	
	Window.Table.DigitWidth = KLHTM_GetDigitLength(KLHTM_GlobalScale * KLHTM_TableScale)
	
	local row, column, fontstring;
	
	for column = 1, KLHTM_TableMaxColumns do 
		
		fontstring = ggf("%sTableRowLabelText%d", Window.Name, column)
		fontstring:SetTextHeight(KLHTM_GlobalScale * KLHTM_TableHeaderScale)
		fontstring:SetHeight(KLHTM_GlobalScale * KLHTM_TableHeaderScale)
				
		for row = 1, KLHTM_TableMaxRows do
			fontstring = ggf("%sTableRow%dText%d", Window.Name, row, column)
			fontstring:SetTextHeight(KLHTM_GlobalScale * KLHTM_TableScale)
			fontstring:SetHeight(KLHTM_GlobalScale * KLHTM_TableScale)
		end
	end
	
	-- lukon mod: resize the bar heights and reanchor
	for row = 1, KLHTM_TableMaxRows do
		text1 = ggf("%sTableRow%dText1", Window.Name, row);
		bar = ggf("%sTableRow%dBar", Window.Name, row);
		bar:SetHeight(KLHTM_GlobalScale * KLHTM_TableScale - 1); -- gap of 1 pixel between each row
		bar:SetPoint("TOPLEFT", text1 , "TOPLEFT", 2, 0);
	end
	
	local fontstring2
	
	-- reapply their anchors. "put the top left of fontstring where the bottom left of fontstring2 is."
	fontstring = ggf("%sTableRow1Text1", Window.Name)
	fontstring2 = ggf("%sTableRowLabelText1", Window.Name)
	fontstring:SetPoint("TOPLEFT", fontstring2, "BOTTOMLEFT")
	
	for x = 2, KLHTM_TableMaxRows do
		fontstring2 = fontstring
		fontstring = ggf("%sTableRow%dText1", Window.Name, x)
		fontstring:SetPoint("TOPLEFT", fontstring2, "BOTTOMLEFT")
	end
	
	KLHTM_RedrawTable(Window)
	KLHTM_UpdateFrameBounds(Window)
	
	ggf(Window.Name):SetScale(1.01)
	ggf(Window.Name):SetScale(1.00)
end


--------------------------------------------------------------
--	Finding the length of a string, given the font height	--
--------------------------------------------------------------

KLHTM_LastStringTesterHeight = 0

-- #J Finding how long the text in a fontstring would be, if it could stretch as long as possible.
function KLHTM_SizeFontStringToText(FontString, FontHeight)
	
	FontString:SetWidth(KLHTM_GetRealStringWidth(FontString:GetText(), FontHeight))
	
end

function KLHTM_GetRealStringWidth(Text, FontHeight)
	
	KLHTM_StringTesterText:SetText(Text)
	KLHTM_StringTesterText:SetWidth(500)
	KLHTM_StringTesterText:SetTextHeight(FontHeight)
	
	if KLHTM_LastStringTesterHeight ~= FontHeight then
		
		KLHTM_StringTester:SetScale(1.01)
		KLHTM_StringTester:SetScale(1.00)
		KLHTM_LastStringTesterHeight = FontHeight
	end

	return KLHTM_StringTesterText:GetStringWidth()
end

-- #K. From KLHThreatMeter.xml, to KLHThreatMeterMain.lua, to us.
KLHTM_IsClassKnown = false

function KLHTM_GuiOnUpdate()

	if KLHTM_MainWindow.Table.RedrawPending == true then
		KLHTM_RedrawTable(KLHTM_MainWindow)
	end
	
	if KLHTM_RaidWindow.Table.RedrawPending == true then
		KLHTM_RedrawTable(KLHTM_RaidWindow)
	end
	
	if KLHTM_IsLoaded == true and KLHTM_FontHackDone == false then
		KLHTM_FontHackDone = true
		KLHTM_SizeFontStringToText(KLHTM_FrameTextMain, KLHTM_GlobalScale)
	end
	
	if KLHTM_IsClassKnown == false then
		KLHTM_CheckClassRageColumn()
	end
	
end

-- This code will remove the rage column for non-(warriors and druids). Doing this way because i don't know
-- when your class becomes non-UnknownClass at startup. Will only run once, so not too terrible.
function KLHTM_CheckClassRageColumn()
	
	local classes = {"paladin", "hunter", "rogue", "shaman", "priest", "mage", "warlock"}
	local myclass = UnitClass("player")
	
	if myclass == KLHTM_String("class", "warrior") or myclass == KLHTM_String("class", "druid") then
		KLHTM_IsClassKnown = true
		return -- don't remove the rage column
	end
	
	local key
	local value
	
	for key, value in classes do
		if myclass == KLHTM_String("class", value) then
			
			-- remove rage column in KLHTM_MainWindow.Functions
			KLHTM_IsClassKnown = true
			
			local x
			for x = 1, table.getn(KLHTM_MainWindow.Table.Functions) do
				if KLHTM_MainWindow.Table.Functions[x].label == KLHTM_String("power", "rage") then
					table.remove(KLHTM_MainWindow.Table.Functions, x)
					return
				end
			end
			
			return
		end
	end
	
end
