--[[
************************************************************************

achievement.lua

File date: 2010-07-11T21:24:31Z
File revision: 236
Project revision: 237
Project version: Locale update


Author: Angelike

************************************************************************
] ]--


local beql = LibStub("AceAddon-3.0"):GetAddon("beql");
local L = LibStub("AceLocale-3.0"):GetLocale("beql");

local minwidth = 175;

beql.achievementLineIndex = 1;

-- local framecache
--local frames = {};

local leftclicktime, rightclicktime = 0,0

--  Initial functions

function beql:AchievementTracker_Toggle(status)

	-- first unload Achievementtracker

	-- hooks
	beql:Unhook("RemoveTrackedAchievement")
	beql:Unhook("AddTrackedAchievement")
	beql:Unhook("AchievementButton_ToggleTracking", function(id) return beql:Hooks_AchievementButton_ToggleTracking(id) end, true)

	-- events
	local events = {'ACHIEVEMENT_EARNED','TRACKED_ACHIEVEMENT_UPDATE','PLAYER_ENTERING_WORLD',}
	for k in ipairs(events) do
		beql:UnregisterEvent(events[k])
	end

	beqlAchievementWatchFrame:Hide()

	WatchFrame_AddObjectiveHandler(WatchFrame_HandleDisplayTrackedAchievements);


	if status then
		-- Hooks
		beql:SecureHook("RemoveTrackedAchievement", beql.Hooks_RemoveTrackedAchievement)
		beql:SecureHook("AddTrackedAchievement", beql.Hooks_AddTrackedAchievement)
		beql:RawHook("AchievementButton_ToggleTracking", function(id) return beql:Hooks_AchievementButton_ToggleTracking(id) end, true)

		-- Scripts
		-- try to restore old achievements
		beql:AchievementTracker_DisplayAchievements()
		--
		-- Events
		for k in ipairs(events) do
			beql:RegisterEvent(events[k], "Event_" .. events[k])
		end

		WatchFrame_RemoveObjectiveHandler(WatchFrame_HandleDisplayTrackedAchievements)
		
		if beql.db.char.AchievementWatchMinimized then
			beql:AchievementTracker_Minimize()
		else
			beql:AchievementTracker_Maximize()
		end
	end

	-- clear Watchframe Display
	WatchFrame_ClearDisplay();
	WatchFrame_Update(WatchFrame);

end

function beql:AchievementTracker_OnMouseUp(frame, button)
	if beql.db.char.AcheivementWatchMinimized then
		return;
	end
	if button == "LeftButton" and (GetTime() - frame.leftclicktime) < 1 then
		beql:AchievementTracker_Click(frame, button)
	elseif button == "RightButton" and (GetTime() - frame.rightclicktime) < 1 then
		beql:AchievementTracker_Click(frame, button)
	end
end

--
-- Hooks
--

function beql:Hooks_AchievementButton_ToggleTracking(id)

	if beql:AchievementTracker_IsTracked(id) then
		RemoveTrackedAchievement(id)
		AchievementFrameAchievements_ForceUpdate();
		return
	end

	if GetNumTrackedAchievements() == WATCHFRAME_MAXACHIEVEMENTS then
		-- wh have reached the limit, exit
		UIErrorsFrame:AddMessage(format(ACHIEVEMENT_WATCH_TOO_MANY, WATCHFRAME_MAXACHIEVEMENTS), 1.0, 0.1, 0.1, 1.0);
		return;
	end

	-- check if we can add it
	local Achievements = {}
	local AchievementIDs = {GetTrackedAchievements()};
	table.insert(AchievementIDs, id)
	local numTrackedAchievements = #AchievementIDs

	-- beql.db.profile.AchievementTracker.ManageLines
	-- beql.db.profile.AchievementTracker.NumLines

	local usedlines = 0
	local achievementusedlines
	local maxlines = 0
	local numCriteria

	for _, achievementID in pairs(AchievementIDs) do
		Achievements[achievementID] = {}
		Achievements[achievementID].criteria = {}
		numCriteria = GetAchievementNumCriteria(achievementID)
		usedlines = usedlines + 1 -- title
		achievementusedlines = 0
		for j=1, numCriteria, 1 do
			if not select(3, GetAchievementCriteriaInfo(achievementID, j)) then
				achievementusedlines = achievementusedlines + 1
				table.insert(Achievements[achievementID].criteria, j)
			end
			if numCriteria == 1 and ( bit.band(select(7, GetAchievementCriteriaInfo(achievementID, j)), ACHIEVEMENT_CRITERIA_PROGRESS_BAR) == ACHIEVEMENT_CRITERIA_PROGRESS_BAR ) then
				achievementusedlines = achievementusedlines + 1
			end
		end

		usedlines = usedlines + achievementusedlines

		if numCriteria == 0 then
			-- Achievement with no objective, we need 1 line for discription
			usedlines = usedlines + 1
		end
		if achievementusedlines > maxlines then
			maxlines = achievementusedlines
		end
		Achievements[achievementID].NumLines = achievementusedlines;
	end

	if not beql.db.profile.AchievementTracker.ManageLines and usedlines > 60 then
		-- will use more lines the avalible, don't add item
		UIErrorsFrame:AddMessage(OBJECTIVES_WATCH_TOO_MANY, 1.0, 0.1, 0.1, 1.0);
		return
	end


	AddTrackedAchievement(id)
	AchievementFrameAchievements_ForceUpdate();
	return true

end

function beql:Hooks_AddTrackedAchievement(id)

	-- clean up old data
	for k,v in next, beql.db.char.AchievementWatchIDs do
		beql.db.char.AchievementWatchIDs[k] = nil
	end

	-- get new data
	beql.db.char.AchievementWatchIDs = { GetTrackedAchievements() }
end

function beql:Hooks_RemoveTrackedAchievement(id)

	-- clean up old data
	for k,v in next, beql.db.char.AchievementWatchIDs do
		beql.db.char.AchievementWatchIDs[k] = nil
	end

	-- get new data
	beql.db.char.AchievementWatchIDs = { GetTrackedAchievements() }
end

--
--  EVENTS
--

function beql:Event_PLAYER_ENTERING_WORLD()

	-- this is needed, bacause add/remove a achievement will overwrite beql.db.char.AchievementWatchIDs
	local AchievementIDs = {unpack(beql.db.char.AchievementWatchIDs)}

	-- restore last tracked achievements
	if beql.db.profile.AchievementTracker.savelast then
		for k,id in pairs(AchievementIDs) do
			if not select(4, GetAchievementInfo(id)) then
				AddTrackedAchievement(id)
			end
		end
	end

	beql:UnregisterEvent("PLAYER_ENTERING_WORLD")
end

function beql:Event_TRACKED_ACHIEVEMENT_UPDATE()

	if not beql.db.profile.AchievementTracker.Enable then
		return;
	end

	beql:AchievementTracker_DisplayAchievements()
end

-- Remove tracked achievement
function beql:Event_ACHIEVEMENT_EARNED ()
	local lastfinished = GetLatestCompletedAchievements()
	if GetTrackedAchievements() == lastfinished then
		SetTrackedAchievement(0)
	end
end


-- Addon funktions

function beql:AchievementTracker_IsTracked(id)
	local Achievements = { GetTrackedAchievements() }

	for k, aID in ipairs(Achievements) do
		if id == aID then
			return true
		end
	end
	return false
end

function beql:AchievementTracker_Minimize(button)
	button = button or beqlAchievementWatchFrame.TitleFrame.Minimize
	beql.db.char.AchievementWatchMinimized = true;

	button:SetNormalTexture("Interface\\AddOns\\beql\\Images\\restore_up")
	button:SetPushedTexture("Interface\\AddOns\\beql\\Images\\restore_down")

	beqlAchievementWatchFrame:SetHeight(1)
	beqlAchievementWatchFrame:SetWidth(beqlAchievementWatchFrame.TitleFrame.Text:GetWidth()+32)
	beqlAchievementWatchFrame.Backdrop:Hide()
	beqlAchievementWatchFrame.LineFrame:Hide()
end

function beql:AchievementTracker_Maximize(button)
	button = button or beqlAchievementWatchFrame.TitleFrame.Minimize
	beql.db.char.AchievementWatchMinimized = false;

	button:SetNormalTexture("Interface\\AddOns\\beql\\Images\\minimize_up")
	button:SetPushedTexture("Interface\\AddOns\\beql\\Images\\minimize_down")

	beqlAchievementWatchFrame.Backdrop:Show()
	beqlAchievementWatchFrame.LineFrame:Show()

	beql:AchievementTracker_DisplayAchievements()
end

--[ [
--------------------------------------------
-- Notes:
-- Update base stats of Achievementtracker
--
-- Returns:
-- * true for updated or nil
--------------------------------------------] ]
function beql:AchievementTracker_UpdateFrame()
	if not beql or not beql.db then
		return
	end
	
	local Options = CopyTable(beql.db.profile.AchievementTracker)

	if Options.Locked then
		beqlAchievementWatchAnchor:SetMovable(nil);
	else
		beqlAchievementWatchAnchor:SetMovable(true);
	end

	-- title
	local title = beqlAchievementWatchFrame.TitleFrame
	if Options.ShowHeader then
		title:Show();
		local t1, _, t2 = beqlAchievementWatchFrame.TitleFrame.Text:GetFont();
		beqlAchievementWatchFrame.TitleFrame.Text:SetFont(t1, beql.db.profile.AchievementTracker.FontSize + 2 , t2);
		beqlAchievementWatchFrame.TitleFrame:SetHeight(beql.db.profile.AchievementTracker.FontSize + 18)
	else
		title:Hide();
		if beql.db.char.AchievementWatchMinimized then
			beql:AchievementTracker_Maximize();
			beql.db.char.AchievementWatchMinimized = false;
		end
	end
	
	
	
	if Options.Locked then
		title:EnableMouse(nil);
		title:RegisterForDrag(nil);
	else
		title:EnableMouse(true);
		title:RegisterForDrag("LeftButton");
	end
	if Options.showbg then
		if not Options.ownbgcolor then
		-- Set Tooltipcolor as BG color
			title:SetBackdropBorderColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,TOOLTIP_DEFAULT_BACKGROUND_COLOR.g,TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
			title:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,TOOLTIP_DEFAULT_BACKGROUND_COLOR.g,TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
		else
		-- Set own Colors
			title:SetBackdropColor(Options.Colors.BgColor.r, Options.Colors.BgColor.g, Options.Colors.BgColor.b, Options.Colors.BgColor.a)
			title:SetBackdropBorderColor(Options.Colors.BgCornerColor.r, Options.Colors.BgCornerColor.g, Options.Colors.BgCornerColor.b, Options.Colors.BgCornerColor.a)
		end
	else
		title:SetBackdropColor(0,0,0,0)
		title:SetBackdropBorderColor(0,0,0,0)
	end

	
	if Options.Locked then
		beqlAchievementWatchFrame:EnableMouse(true);
		beqlAchievementWatchFrame:RegisterForDrag(nil);
	else
		beqlAchievementWatchFrame:EnableMouse(true);
		beqlAchievementWatchFrame:RegisterForDrag("LeftButton");
	end
	
	if Options.showbg then
		if not Options.ownbgcolor then
		-- Set Tooltipcolor as BG color
			beqlAchievementWatchFrame.Backdrop:SetBackdropBorderColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,TOOLTIP_DEFAULT_BACKGROUND_COLOR.g,TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
			beqlAchievementWatchFrame.Backdrop:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r,TOOLTIP_DEFAULT_BACKGROUND_COLOR.g,TOOLTIP_DEFAULT_BACKGROUND_COLOR.b)
		else
		-- Set own Colors
			beqlAchievementWatchFrame.Backdrop:SetBackdropColor(Options.Colors.BgColor.r, Options.Colors.BgColor.g, Options.Colors.BgColor.b, Options.Colors.BgColor.a)
			beqlAchievementWatchFrame.Backdrop:SetBackdropBorderColor(Options.Colors.BgCornerColor.r, Options.Colors.BgCornerColor.g, Options.Colors.BgCornerColor.b, Options.Colors.BgCornerColor.a)
		end
	else
		beqlAchievementWatchFrame.Backdrop:SetBackdropColor(0,0,0,0)
		beqlAchievementWatchFrame.Backdrop:SetBackdropBorderColor(0,0,0,0)
	end

	if not Options.showtooltip and Options.Locked and not Options.clickleft and not Options.clickright then
		beqlAchievementWatchFrame:EnableMouse(nil);
	end
	if Options.Locked and not Options.clickleft and not Options.clickright then
		beqlAchievementWatchFrame:EnableMouse(nil);
	end
	
	-- Alpha
	beqlAchievementWatchFrame:SetAlpha(beql.db.profile.AchievementTracker.alpha)
	
	if beqlAchievementWatchFrame:IsShown() then
		beql:AchievementTracker_DisplayAchievements()
	end

	return true
end

function beql:AchievementTracker_GetLine (addsize)

	local line = beqlFrameCache.AchievementLines[beqlFrameCache.AchievementLineIndex];
	if ( not line ) then
		beqlFrameCache.AchievementLines[beqlFrameCache.AchievementLineIndex] = beqlFrameCache.Lines:GetFrame();
		line = beqlFrameCache.AchievementLines[beqlFrameCache.AchievementLineIndex];
	end

	line:Reset();

	line.type = 'a'
	-- reset icon
	line.iconframe:Hide()

	local t1,_ , t2 = line.text:GetFont()
	local t3,_ , t4 = line.statusBar.text:GetFont()
	local t5,_ , t6 = line.dash:GetFont()
	if addsize and type(addsize) == 'number' then
		local fontsize = beql.db.profile.AchievementTracker.FontSize + addsize
		line.text:SetFont(t1, fontsize, t1)
		line.dash:SetFont(t5, fontsize, t6)
		line:SetHeight( fontsize + (fontsize/4))
		line.statusBar.text:SetFont(t3, fontsize-2, t4)
	else
		line.text:SetFont(t1, beql.db.profile.AchievementTracker.FontSize, t1)
		line.dash:SetFont(t5, beql.db.profile.AchievementTracker.FontSize, t6)
		line:SetHeight(beql.db.profile.AchievementTracker.FontSize + (beql.db.profile.AchievementTracker.FontSize/4))
		line.statusBar.text:SetFont(t3, beql.db.profile.AchievementTracker.FontSize * (10/12), t4)
	end

	line:SetParent(beqlAchievementWatchFrame.LineFrame)
	beqlFrameCache.AchievementLineIndex = beqlFrameCache.AchievementLineIndex + 1;
	return line;
end

function beql:AchievementTracker_ReleaseUnusedLines ()
	local line
	for i = beqlFrameCache.AchievementLineIndex, #beqlFrameCache.AchievementLines do
		line = beqlFrameCache.AchievementLines[i];
		line:Hide();
		line.frameCache:ReleaseFrame(line);
		beqlFrameCache.AchievementLines[i] = nil;
	end

	beqlFrameCache.AchievementLineIndex = 1
end

--local 

function beql:AchievementTracker_DisplayAchievements()
	beqlDebug.a = (beqlDebug.a or 0) + 1
	beqlDebugAchievement:SetText("AchievementNr: " .. beqlDebug.a)

	if beql.db.char.AchievementWatchMinimized then
		-- tracker minimized, exit
		if beql.db.profile.AchievementTracker.ShowHeader then
			beqlAchievementWatchFrame:Show();
			beqlAchievementWatchFrame.TitleFrame.Text:SetText(L["Achievement Tracker"] .. " ("..select("#", GetTrackedAchievements()) .. "/" .. WATCHFRAME_MAXACHIEVEMENTS .. ")")
		else
			beqlAchievementWatchFrame:Hide();
		end
		return
	end


	local _; -- Doing this here thanks to IBLJerry!
	local TrackedAchievements = {GetTrackedAchievements()}
	local numTrackedAchievements = #TrackedAchievements--elect("#", );

	--HACK:
	lineFrame = beqlAchievementWatchFrame.LineFrame
	initialOffset = 0
	local WATCHFRAME_CRITERIA_PER_ACHIEVEMENT = WATCHFRAME_CRITERIA_PER_ACHIEVEMENT + 1; -- + 1 iss a dummy, because we handle the latst line in an other way
	local Achievements = {}


--	local maxWidth = 0;

	local achievementID;
	local achievementName, completed, description, icon;

	-- line variables
	local line, achievementTitle, previousLine;

	local numCriteria, criteriaDisplayed;
	local criteriaString, criteriaType, criteriaCompleted, quantity, totalQuantity, name, flags, assetID, quantityString, criteriaID, achievementCategory;

	-- get used lines per achievement
	local maxlines = 0
	local extralines = 0;
	local usedlines = 0
	local achievementusedlines
	for i = 1 , numTrackedAchievements, 1 do
		achievementID = TrackedAchievements[i] --select(i, GetTrackedAchievements());
		Achievements[achievementID] = {}
		Achievements[achievementID].criteria = {}
		numCriteria = GetAchievementNumCriteria(achievementID)
		usedlines = usedlines + 1 -- title
		achievementusedlines = 0
		for j=1, numCriteria, 1 do
			if not select(3, GetAchievementCriteriaInfo(achievementID, j)) then
				usedlines = usedlines + 1
				achievementusedlines = achievementusedlines + 1
				table.insert(Achievements[achievementID].criteria, j)
			end
			if numCriteria == 1 and ( bit.band(select(7, GetAchievementCriteriaInfo(achievementID, j)), ACHIEVEMENT_CRITERIA_PROGRESS_BAR) == ACHIEVEMENT_CRITERIA_PROGRESS_BAR ) then
				extralines = extralines + 1
			end
		end

		if numCriteria == 0 then
			-- Achievement with no objective, we need 1 line for discription
			usedlines = usedlines + 1
		end
		if achievementusedlines > maxlines then
			maxlines = achievementusedlines
		end
		Achievements[achievementID].NumLines = achievementusedlines;
	end

	-- calc optimal lines per achievement
	if beql.db.profile.AchievementTracker.ManageLines and type(beql.db.profile.AchievementTracker.NumLines) == 'number' then
		WATCHFRAME_CRITERIA_PER_ACHIEVEMENT = 0
		for i = maxlines, 1, -1 do
			usedlines = 0
			for k in pairs(Achievements) do
				if Achievements[k].NumLines > i then
					usedlines = usedlines + i
				else
					usedlines = usedlines + Achievements[k].NumLines
				end

				if Achievements[k].NumLines == 0 then
					-- Achievement with no objective, we need 1 line for discription
					usedlines = usedlines + 1
				end
			end

			if (usedlines + numTrackedAchievements) <= beql.db.profile.AchievementTracker.NumLines then
				beql:debugprint("break at " .. i .. " Line(s) per Achievement, " .. (usedlines + numTrackedAchievements) .. " Lines total, " .. (beql.db.profile.AchievementTracker.NumLines - (usedlines + numTrackedAchievements)).. " Lines in reserve")
				extralines = beql.db.profile.AchievementTracker.NumLines - (usedlines + numTrackedAchievements)
				WATCHFRAME_CRITERIA_PER_ACHIEVEMENT = i
				break
			end
		end
	end

	local displayOnlyArena = (not WatchFrame:IsUserPlaced()) and ArenaEnemyFrames and ArenaEnemyFrames:IsShown();
	for i = 1, numTrackedAchievements do
		achievementID = TrackedAchievements[i] --select(i, GetTrackedAchievements());
		achievementCategory = GetAchievementCategory(achievementID);
		if ( (not displayOnlyArena) or achievementCategory == WATCHFRAME_ACHIEVEMENT_ARENA_CATEGORY ) then
			_, achievementName, _, completed, _, _, _, description, _, icon = GetAchievementInfo(achievementID);

			--
			-- Title
			--

			line = beql:AchievementTracker_GetLine(1);
			line.isHeader = true;
			line.aID = achievementID
			achievementTitle = line;
			line.text:SetText(achievementName);
			line.mouseover:SetWidth(line.text:GetStringWidth())
			if ( completed ) then
				line.text:SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
			else
				line.text:SetTextColor(0.75, 0.61, 0);
			end
			line:Show()
			local lineWidth = line.text:GetStringWidth()
			if ( previousLine ) then -- If this isn't the first displayed title, our position is relative to the last displayed line.
				local yOffset = 0;
				if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
					yOffset = -5
				end

				line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset - WATCHFRAME_QUEST_OFFSET);
				line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset - WATCHFRAME_QUEST_OFFSET);
			else
				line:SetPoint("TOPRIGHT", lineFrame, "TOPRIGHT", 0, initialOffset);
				line:SetPoint("TOPLEFT", lineFrame, "TOPLEFT", 0, initialOffset);
			end
			
			--
			-- LinkButton
			--
			if icon then
				line.icon:SetTexture(icon)
				local iconsize = select(2,line.text:GetFont())*1.5
				lineWidth = lineWidth + iconsize - 6
				line.icon:SetHeight(iconsize)
				line.icon:SetWidth(iconsize)
				line.icon:ClearAllPoints()
				line.icon:SetPoint("LEFT", line, "LEFT", 3, 0)
				line.dash:SetWidth(iconsize + 6)
--				line.text:ClearAllPoints();
--				line.text:SetPoint("LEFT", line, "LEFT", iconsize + 6 ,0)
--				line.text:SetPoint("RIGHT", line, "RIGHT", 0,0)

				-- calc border offset
				local offset = line.icon:GetHeight()/3.2

				line.iconborder:ClearAllPoints()
				line.iconborder:SetPoint("TOPLEFT", line.icon, "TOPLEFT", -offset, offset)
				line.iconborder:SetPoint("BOTTOMRIGHT", line.icon, "BOTTOMRIGHT", offset, -offset)
				line.iconframe:Show()
			end
--			maxWidth = max(maxWidth, lineWidth)

			previousLine = line;

			--
			-- Details (Criteria)
			--

			numCriteria = Achievements[achievementID].NumLines;
			if numCriteria > WATCHFRAME_CRITERIA_PER_ACHIEVEMENT then
				if extralines > 0 then
					-- we have empty lines over, so we use them
					numCriteria = WATCHFRAME_CRITERIA_PER_ACHIEVEMENT + 1
					extralines = extralines - 1
				else
					numCriteria = WATCHFRAME_CRITERIA_PER_ACHIEVEMENT
				end
			end

			if ( numCriteria > 0 ) then

				--
				-- Achivements with Criteria
				--
				criteriaDisplayed = 0;
				for j = 1, numCriteria do
					criteriaString, criteriaType, criteriaCompleted, quantity, totalQuantity, name, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(achievementID, Achievements[achievementID].criteria[j]);
					if ( j == numCriteria and (numCriteria < Achievements[achievementID].NumLines) ) then
						-- We ran out of space to display incomplete criteria >_<
						line = beql:AchievementTracker_GetLine();
						line.aID = achievementID
						line.dash:SetText(" - ");
--						line.mouseover:SetWidth(line.text:GetStringWidth())
						line.dash:SetWidth(line.dash:GetStringWidth());
						line.dash:SetText("")
-- great idea, but why we must move the whole line if we can only need to move the font string?
--						line.text:SetPoint("TOPLEFT", line, "TOPLEFT", dashWidth, 0)
						line.text:SetText("...");
						line.mouseover:SetWidth(line.text:GetStringWidth())
						line.text:SetTextColor(0.8, 0.8, 0.8);
						line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0 , 3);
						line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, 3);
						line:Show();
--						maxWidth = max(maxWidth, line.text:GetStringWidth()); -- I can't imagine this happening anytime soon really
						criteriaDisplayed = criteriaDisplayed + 1;
						previousLine = line;
					else

						--
						-- Timed Criteria
						--
						if ( WATCHFRAME_TIMEDCRITERIA[criteriaID] ) then
							local timedCriteria = WATCHFRAME_TIMEDCRITERIA[criteriaID]
							line = beql:AchievementTracker_GetLine();
							line.criteriaID = criteriaID;
							line.duration = timedCriteria.duration;
							line.startTime = timedCriteria.startTime;

							local yOffset = WATCHFRAMELINES_FONTSPACING;
							if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
								yOffset = yOffset - 5;
							end
							line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset);
							line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset);
							line:Show()
							criteriaDisplayed = criteriaDisplayed + 1;
							previousLine = line;
							WatchFrameLines_AddUpdateFunction(WatchFrame_UpdateTimedAchievements);
						end

						--
						-- Criteria with Statusbar
						--
						if ( bit.band(flags, ACHIEVEMENT_CRITERIA_PROGRESS_BAR) == ACHIEVEMENT_CRITERIA_PROGRESS_BAR ) then
							line = beql:AchievementTracker_GetLine();
							line.aID = achievementID
							line.statusBar:Show();
							line.statusBar:GetStatusBarTexture():SetVertexColor(0, 0.6, 0, 1);
							line.statusBar:SetMinMaxValues(0, totalQuantity);
							line.statusBar:SetValue(quantity);
							line.statusBar.text:SetText(quantityString);
							line.mouseover:ClearAllPoints()
							line.mouseover:SetAllPoints(line.statusBar)

							local yOffset = -5;
							if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
								yOffset = -10;
							end

							line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset);
							line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset);
							line:Show();
--							maxWidth = max(maxWidth, 200);
							criteriaDisplayed = criteriaDisplayed + 2;
							previousLine = line;
						else

							--
							-- Normal Achievements with objectives
							--
							line = beql:AchievementTracker_GetLine();
							line.aID = achievementID
							line.text:SetText(" - " .. criteriaString);
							line.mouseover:SetWidth(line.text:GetStringWidth())
							line.text:SetTextColor(0.8, 0.8, 0.8);
							local yOffset = WATCHFRAMELINES_FONTSPACING;
							if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
								yOffset = yOffset - 5;
							end

							if criteriaType == 8 then
								line.subaID = assetID
								line.iconframe:Show()
								line.icon:SetTexture(select(10, GetAchievementInfo(assetID)))
								line.icon:ClearAllPoints()
								line.icon:SetPoint("LEFT", line.text,"LEFT",line.text:GetStringWidth()+3,0)
								local iconsize = beql.db.profile.AchievementTracker.FontSize
								line.icon:SetHeight(iconsize)
								line.icon:SetWidth(iconsize)
								--line.iconborder:Show()
								line.iconborder:SetHeight((iconsize/4)*6.5)
								line.iconborder:SetWidth((iconsize/4)*6.5)

								line.iconframe.aID = assetID
--								maxWidth = max(maxWidth, line.text:GetStringWidth() + iconsize + 6);

							end
							line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset);
							line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset);
							line:Show();
--							maxWidth = max(maxWidth, line.text:GetStringWidth());
							criteriaDisplayed = criteriaDisplayed + 1;
							previousLine = line;
						end
					end
				end
			else

				--
				-- Achievement with no criteria, display Discription
				--
				line = beql:AchievementTracker_GetLine();
				line.dash:SetText(" - ");
				line.dash:SetTextColor(0.8, 0.8, 0.8);
				local yOffset = WATCHFRAMELINES_FONTSPACING;
				if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
					yOffset = yOffset - 5;
				end

				local dashWidth = line.dash:GetStringWidth();

				line.aID = achievementID
				line.text:SetText(description);
				line.mouseover:ClearAllPoints()
				line.mouseover:SetAllPoints(line.text)
				line.text:SetTextColor(0.8, 0.8, 0.8);
				line.aType = true;

--				local stringWidth = line.text:GetStringWidth();
--				local desiredWidth = math.ceil(stringWidth + dashWidth); -- This is how long we want the line to be with no wrapping

--				local MAX_LONG_CRITERIA_WIDTH = 250;
				--if ( desiredWidth > maxWidth ) then
					--maxWidth = min(desiredWidth, MAX_LONG_CRITERIA_WIDTH);
				--end

--				line.text:ClearAllPoints()
--				line.text:SetPoint("TOPLEFT", line.dash, "TOPRIGHT",0,0)
				--line.text:SetPoint("TOPRIGHT", line, "TOPRIGHT",0,0)
				
--[ [				local linesNeeded = math.ceil(stringWidth / 250);
				line.text:SetWidth(250)
				print("need " .. linesNeeded .. " lines")

				--line:SetHeight((beql.db.profile.AchievementTracker.FontSize - WATCHFRAMELINES_FONTSPACING) + (beql.db.profile.AchievementTracker.FontSize * (linesNeeded - 1)));
				line:SetHeight((beql.db.profile.AchievementTracker.FontSize - WATCHFRAMELINES_FONTSPACING) + (beql.db.profile.AchievementTracker.FontSize * (linesNeeded)));
				--] ]
				line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset);
				line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset);
				line:Show();

				previousLine = line;

				for criteriaID, timedCriteria in next, WATCHFRAME_TIMEDCRITERIA do
					if ( timedCriteria.achievementID == achievementID ) then
						line = beql:AchievementTracker_GetLine();
						line.criteriaID = criteriaID;
						line.duration = timedCriteria.duration;
						line.startTime = timedCriteria.startTime;

						local yOffset = WATCHFRAMELINES_FONTSPACING;
						if ( previousLine.statusBar:IsShown() or previousLine.isHeader ) then
							yOffset = yOffset - 5;
						end
						line:SetPoint("TOPRIGHT", previousLine, "BOTTOMRIGHT", 0, yOffset);
						line:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, yOffset);
						line:Show()
						previousLine = line;
						WatchFrameLines_AddUpdateFunction(WatchFrame_UpdateTimedAchievements);
					end
				end
			end
		end
	end

	
	
	beql:AchievementTracker_ReleaseUnusedLines();

	if previousLine then
		beqlAchievementWatchFrame:Show()
	else
		beqlAchievementWatchFrame:Hide()
		return;
	end


	-- titlebar
	beqlAchievementWatchFrame.TitleFrame.Text:SetText(L["Achievement Tracker"] .. " ("..numTrackedAchievements .. "/" .. WATCHFRAME_MAXACHIEVEMENTS .. ")")
	
	-- calc out width
	local maxWidth = beqlAchievementWatchFrame.TitleFrame.Text:GetStringWidth() + 32
	local speciallines = {}
	for lineNr, line in pairs(beqlFrameCache.AchievementLines) do
		if line.statusBar:IsShown() then
			maxWidth = max(maxWidth, 212)
		elseif (line.iconframe:IsShown() and not line.isHeader) then
			maxWidth = max(maxWidth, (line.dash:GetWidth() + line.text:GetStringWidth() + line.iconframe:GetWidth() + 6))
		elseif (line.aType) then
			maxWidth = max(maxWidth, (line.dash:GetWidth() + 250))
			table.insert(speciallines, lineNr)
		else
			maxWidth = max(maxWidth, (line.dash:GetWidth() + line.text:GetStringWidth()))
		end
	end
	beqlAchievementWatchFrame:SetWidth(maxWidth)
	
	-- adjust lines without an criteria
	for _, k in ipairs(speciallines) do
		local line = beqlFrameCache.AchievementLines[k]
		line.text:SetWidth(maxWidth - line.dash:GetWidth())
		line.text:SetHeight(line.text:GetStringHeight())
		line:SetHeight(line.text:GetStringHeight()+2)
	end

	-- calc out height
	local height = 0
	for _, line in pairs(beqlFrameCache.AchievementLines) do
		height = height - select(5, line:GetPoint(0)) + line:GetHeight()
	end
	
	if previousLine.statusBar:IsShown() then
		height = height + 5
	end

	--beqlAchievementWatchFrame:SetPoint("BOTTOM", previousLine, "BOTTOM",0,0)
	beqlAchievementWatchFrame:SetHeight(height)

	beqlAchievementWatchFrame.width = beqlAchievementWatchFrame:GetWidth()
	beqlAchievementWatchFrame.height = beqlAchievementWatchFrame:GetHeight()

end

--- EOF ---]]