QuestGuru_History = {};
QuestGuru_HistoryHeaders = {};
QuestGuru_numHistory = 0;
QuestGuru_currHistory = 2;
QuestGuru_LastCompleteQuest = {};
QuestGuru_LastXPRep = {};

StaticPopupDialogs["QUESTGURU_DELETEHISTORYTITLE"] = {
  text = QG_HISTORY_DELETE,
  button1 = YES,
  button2 = NO,
  OnAccept = function()
	local qhTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame));
	local i, qH;
   	for i, qH in ipairs(QuestGuru_History) do
   		if (qH.qID == qhTitle.qID) then
   			tremove(QuestGuru_History, i)
			QuestGuru_Quests[QuestGuru_RealmName][qH.qID][QuestGuru_Player] = nil;
			break;
		end
	end
	QuestGuru_UpdateHistory();
  end,
  timeout = 0,
  whileDead = 1,
  hideOnEscape = 1
};

function QuestGuru_QuestHistoryTitleMenu_OnLoad()
	local info = UIDropDownMenu_CreateInfo();
	info.func = QuestGuru_QuestHistoryTitleMenu_OnClick;
	info.checked = nil;
	info.icon = nil;

	info.text = QG_DELETE_QUEST;
	info.value = "delete";
	UIDropDownMenu_AddButton(info, 1);

	info.text = "-----------------";
	info.value = "-";
	info.isTitle = 1;
	UIDropDownMenu_AddButton(info, 1);

	info = UIDropDownMenu_CreateInfo();
	info.func = QuestGuru_QuestHistoryTitleMenu_OnClick;
	info.checked = nil;
	info.icon = nil;
	info.text = CANCEL;
	info.value = "cancel";
	UIDropDownMenu_AddButton(info, 1);

end

function QuestGuru_QuestHistoryTitleMenu_OnClick()
	local qhTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame));
	if (this.value == "delete") then
		StaticPopup_Show("QUESTGURU_DELETEHISTORYTITLE", qhTitle:GetText());
	end
end

function QuestGuru_QuestHistoryTitleButton_OnLoad(self)
	self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
	self:RegisterEvent("UNIT_QUEST_LOG_CHANGED");
	self:RegisterEvent("PARTY_MEMBER_ENABLE");
	self:RegisterEvent("PARTY_MEMBER_DISABLE");
end

function QuestGuru_QuestHistoryTitleButton_OnEvent(self, event, ...)
	if ( GameTooltip:IsOwned(self) ) then
		GameTooltip:Hide();
		QuestGuru_UpdateHistoryPartyInfoTooltip();
	end
end

function QuestGuru_QuestHistoryTitleButton_OnClick(self, button, down)
	local questName = self:GetText();
	local questIndex = self:GetID() + FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	
	QuestLog_SetHistorySelection(questIndex)
	if (button == "LeftButton") then
		if ( IsShiftKeyDown() ) then
			-- If header then return
			if ( self.isHeader ) then
				return;
			end
			-- Otherwise try to put it into chat
			if ( ChatFrameEditBox:IsVisible() ) then
				local n, qH, currHead;
				local c = 0;
				for n, qH in ipairs(QuestGuru_History) do
					if (qH.Header ~= currHead) then
						currHead = qH.Header;
						c = c + 1;
					end
					if (QuestGuru_HistoryHeaders[currHead] ~= false) then
						c = c + 1;
					end
					if (c == questIndex) then
					    if (QuestGuru_History[n].Link) then
					        ChatFrameEditBox:Insert(QuestGuru_History[n].Link);
						else
							ChatFrameEditBox:Insert(strtrim("["..QuestGuru_History[n].Level.."] "..QuestGuru_History[n].Title));
						end
					end
				end
			end
		end
	elseif (button == "RightButton") then
		ToggleDropDownMenu(1, nil, QuestGuru_QuestHistoryTitleMenu, self:GetName(), 0, 0)
	end	
	QuestGuru_UpdateHistory();
end

function QuestGuru_QuestHistoryTitleButton_OnEnter(self, motion)
	-- Set highlight
	getglobal(self:GetName().."Tag"):SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
	getglobal(self:GetName().."Level"):SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);

	-- Set group info tooltip
	QuestGuru_UpdateHistoryPartyInfoTooltip();
end

function QuestGuru_UpdateHistoryPartyInfoTooltip()
	if (this.isHeader) then return; end
	if (not QuestGuru_Settings.ShowAltStatus) then return; end

	local index = this:GetID() + FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	GameTooltip_SetDefaultAnchor(GameTooltip, this);
	
	local lastHeader = "";
	local altOnQuest;
	for i, questHistory in ipairs(QuestGuru_History) do
		if (questHistory.Header ~= lastHeader) then
			lastHeader = questHistory.Header;
			index = index - 1;
		end
		if (not QuestGuru_HistoryHeaders[questHistory.Header]) then
			index = index + 1;
		end
		if (i == index) then
			local questTitleText = questHistory.Title;
			GameTooltip:SetText(questTitleText);

			local i, v;
			local questDescription = questHistory.Description;
			local questObjectives = questHistory.ObjectiveText;
			local qID = this.qID;
	
			if (QuestGuru_Quests[QuestGuru_RealmName][qID] ~= nil) then
				for i, v in pairs(QuestGuru_Quests[QuestGuru_RealmName][qID]) do
					if ((i ~= "level") and (i ~= QuestGuru_Player) and (i ~= "_link")) then
						if (not altOnQuest) then
							GameTooltip:AddLine(QG_ALT_STATUS_HEAD);
							altOnQuest = true;
						end
						if (v == "Complete") then
							GameTooltip:AddDoubleLine(i, COMPLETE, 1, 1, 1, 0, 1, 0);
						elseif (v == "Abandoned") then
							GameTooltip:AddDoubleLine(i, QG_ABANDONED, 1, 1, 1, 1, 0, 0);
						else
							GameTooltip:AddDoubleLine(i, QG_ACTIVE, 1, 1, 1, 0, 1, 1);
							local currStatus = { strsplit(";", v) };

							local numObjectives = questHistory.Objectives;
			
							if (numObjectives ~= nil) then
								for j=1, numObjectives, 1 do
									local text = questHistory.Objective[j].Description;
									local type = questHistory.Objective[j].Type;
				
									if (type == "item") then
										local numNeeded = questHistory.Objective[j].numNeeded;
								    	GameTooltip:AddDoubleLine("  - "..text, currStatus[j+1].."/"..numNeeded, 1, 1, 1, 1, 1, 1);
								    elseif ((type == "monster") or (type == "object")) then
										local x, y, name, numItems, numNeeded = string.find(text, QG_ITEM_REQ_STR);
								    	GameTooltip:AddDoubleLine("  - "..name, currStatus[j+1].."/"..numNeeded, 1, 1, 1, 1, 1, 1);
									else
										if (currStatus[j+1] == 1) then
											GameTooltip:AddDoubleLine("  - "..text, COMPLETE, 1, 1, 1, 0, 1, 0);
										else
											GameTooltip:AddDoubleLine("  - "..text, QG_INCOMPLETE, 1, 1, 1, 1, 0, 0);
										end
									end
								end
							end
						end
					end
				end
			end
		end
	end
	if (altOnQuest) then
		GameTooltip:Show();
	else
		GameTooltip:Hide();
	end
end

function QuestGuru_QuestHistoryStart_OnClick(self, button, down)
	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local questTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset);
	local qID;
	if (not questTitle) then
		local n, qH, currHead;
		local c = 0;
		for n, qH in ipairs(QuestGuru_History) do
			if (qH.Header ~= currHead) then
				currHead = qH.Header;
				c = c + 1;
			end
			if (QuestGuru_HistoryHeaders[currHead] ~= false) then
				c = c + 1;
			end
			if (c == QuestGuru_currHistory) then
				qID = qH.qID;
			end
		end
	else
		qID = questTitle.qID;
	end
	if (not qID) then return; end
	for i, questHistory in ipairs(QuestGuru_History) do
		if (questHistory.qID == qID) then
			if (questHistory.Daily == 1) then
				QuestGuru_WorldmapIconTexture:SetTexCoord(0.375, 0.5, 0.5, 1);
			else
				QuestGuru_WorldmapIconTexture:SetTexCoord(0.125, 0.25, 0.5, 1);
			end
			QuestGuru_ShowMap(questHistory.StartNPCZone, questHistory.StartPosX, questHistory.StartPosY, questHistory.StartNPCName, questHistory.Title);
		end
	end
end

function QuestGuru_QuestHistoryStart_OnEnter(self, motion)
	local tempWidth, maxWidth;
	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local questTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset);
	local qID;
	if (not questTitle) then
		local n, qH, currHead;
		local c = 0;
		for n, qH in ipairs(QuestGuru_History) do
			if (qH.Header ~= currHead) then
				currHead = qH.Header;
				c = c + 1;
			end
			if (QuestGuru_HistoryHeaders[currHead] ~= false) then
				c = c + 1;
			end
			if (c == QuestGuru_currHistory) then
				qID = qH.qID;
			end
		end
	else
		qID = questTitle.qID;
	end
	if (not qID) then return; end

	local NPCColor, AreaColor;
	if (QuestGuru_Settings.Colorize.NPCNames.Enabled) then
		NPCColor = QuestGuru_Settings.Colorize.NPCNames.Color;
	else
		NPCColor = { r=0, g=0, b=0 };
	end
	if (QuestGuru_Settings.Colorize.AreaNames.Enabled) then
		AreaColor = QuestGuru_Settings.Colorize.AreaNames.Color;
	else
		AreaColor = { r=0, g=0, b=0 };
	end
	local i, questHistory;

	for i, questHistory in ipairs(QuestGuru_History) do
		if (questHistory.qID == qID) then
			QuestGuru_QuestStartInfoFrame:ClearAllPoints();
	        QuestGuru_QuestStartInfoFrame:SetPoint("BOTTOM", QuestGuru_QuestHistoryStart, "TOP");
	        QuestGuru_QuestStartInfoTitle:SetText(QG_QSTART_HEAD);
	        maxWidth = QuestGuru_QuestStartInfoTitle:GetWidth();

	        QuestGuru_QuestStartInfoNPC:SetText(questHistory.StartNPCName);
			QuestGuru_QuestStartInfoNPC:SetTextColor(NPCColor.r, NPCColor.g, NPCColor.b);

	        QuestGuru_QuestStartInfoPOS:SetText("("..questHistory.StartPosX..","..questHistory.StartPosY..")");
			QuestGuru_QuestStartInfoPOS:SetTextColor(AreaColor.r, AreaColor.g, AreaColor.b);
			tempWidth = QuestGuru_QuestStartInfoNPC:GetWidth() + QuestGuru_QuestStartInfoPOS:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

	        QuestGuru_QuestStartInfoArea:SetText(questHistory.StartNPCZone);
			QuestGuru_QuestStartInfoArea:SetTextColor(AreaColor.r, AreaColor.g, AreaColor.b);
			tempWidth = QuestGuru_QuestStartInfoArea:GetWidth();
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoTimeLabel:SetText(QG_QSTART_TIME);
			QuestGuru_QuestStartInfoTime:SetText(questHistory.StartTime);
			tempWidth = QuestGuru_QuestStartInfoTimeLabel:GetWidth() + QuestGuru_QuestStartInfoTime:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoLevelLabel:SetText(QG_QSTART_LEVEL);
			QuestGuru_QuestStartInfoLevel:SetText(questHistory.StartLevel);
			tempWidth = QuestGuru_QuestStartInfoLevelLabel:GetWidth() + QuestGuru_QuestStartInfoLevel:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoFrame:SetWidth(maxWidth + 18);
	        QuestGuru_QuestStartInfoFrame:Show();
        end
	end
end

function QuestGuru_QuestHistoryFinish_OnClick(self, button, down)
	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local questTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset);
	local qID;
	if (not questTitle) then
		local n, qH, currHead;
		local c = 0;
		for n, qH in ipairs(QuestGuru_History) do
			if (qH.Header ~= currHead) then
				currHead = qH.Header;
				c = c + 1;
			end
			if (QuestGuru_HistoryHeaders[currHead] ~= false) then
				c = c + 1;
			end
			if (c == QuestGuru_currHistory) then
				qID = qH.qID;
			end
		end
	else
		qID = questTitle.qID;
	end
	if (not qID) then return; end
	for i, questHistory in ipairs(QuestGuru_History) do
		if (questHistory.qID == qID) then
			if (questHistory.Daily == 1) then
				QuestGuru_WorldmapIconTexture:SetTexCoord(0.5, 0.625, 0.5, 1);
			else
				QuestGuru_WorldmapIconTexture:SetTexCoord(0.25, 0.375, 0.5, 1);
			end
			QuestGuru_ShowMap(questHistory.FinishNPCZone, questHistory.FinishPosX, questHistory.FinishPosY, questHistory.FinishNPCName, questHistory.Title);
		end
	end
end

function QuestGuru_QuestHistoryFinish_OnEnter(self, motion)
	local tempWidth, maxWidth;
	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local questTitle = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset);
	local qID;
	if (not questTitle) then
		local n, qH, currHead;
		local c = 0;
		for n, qH in ipairs(QuestGuru_History) do
			if (qH.Header ~= currHead) then
				currHead = qH.Header;
				c = c + 1;
			end
			if (QuestGuru_HistoryHeaders[currHead] ~= false) then
				c = c + 1;
			end
			if (c == QuestGuru_currHistory) then
				qID = qH.qID;
			end
		end
	else
		qID = questTitle.qID;
	end
	if (not qID) then return; end

	local NPCColor, AreaColor;
	if (QuestGuru_Settings.Colorize.NPCNames.Enabled) then
		NPCColor = QuestGuru_Settings.Colorize.NPCNames.Color;
	else
		NPCColor = { r=0, g=0, b=0 };
	end
	if (QuestGuru_Settings.Colorize.AreaNames.Enabled) then
		AreaColor = QuestGuru_Settings.Colorize.AreaNames.Color;
	else
		AreaColor = { r=0, g=0, b=0 };
	end
	local i, questHistory;

	for i, questHistory in ipairs(QuestGuru_History) do
		if (questHistory.qID == qID) then
			QuestGuru_QuestStartInfoFrame:ClearAllPoints();
	        QuestGuru_QuestStartInfoFrame:SetPoint("BOTTOM", QuestGuru_QuestHistoryFinish, "TOP");
	        QuestGuru_QuestStartInfoTitle:SetText(QG_QFINISH_HEAD);
	        maxWidth = QuestGuru_QuestStartInfoTitle:GetWidth();

	        QuestGuru_QuestStartInfoNPC:SetText(questHistory.FinishNPCName);
			QuestGuru_QuestStartInfoNPC:SetTextColor(NPCColor.r, NPCColor.g, NPCColor.b);

	        QuestGuru_QuestStartInfoPOS:SetText("("..questHistory.FinishPosX..","..questHistory.FinishPosY..")");
			QuestGuru_QuestStartInfoPOS:SetTextColor(AreaColor.r, AreaColor.g, AreaColor.b);
			tempWidth = QuestGuru_QuestStartInfoNPC:GetWidth() + QuestGuru_QuestStartInfoPOS:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

	        QuestGuru_QuestStartInfoArea:SetText(questHistory.FinishNPCZone);
			QuestGuru_QuestStartInfoArea:SetTextColor(AreaColor.r, AreaColor.g, AreaColor.b);
			tempWidth = QuestGuru_QuestStartInfoArea:GetWidth();
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoTimeLabel:SetText(QG_QFINISH_TIME);
			QuestGuru_QuestStartInfoTime:SetText(questHistory.FinishTime);
			tempWidth = QuestGuru_QuestStartInfoTimeLabel:GetWidth() + QuestGuru_QuestStartInfoTime:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoLevelLabel:SetText(QG_QFINISH_LEVEL);
			QuestGuru_QuestStartInfoLevel:SetText(questHistory.FinishLevel);
			tempWidth = QuestGuru_QuestStartInfoLevelLabel:GetWidth() + QuestGuru_QuestStartInfoLevel:GetWidth() + 8;
			if (tempWidth > maxWidth) then maxWidth = tempWidth; end

			QuestGuru_QuestStartInfoFrame:SetWidth(maxWidth + 18);
	        QuestGuru_QuestStartInfoFrame:Show();
        end
	end
end

function QuestGuru_SaveLastQuest()
	if (QuestGuru_LastCompleteQuest.Link == nil) then return; end
	local lastHeader;
	local numEntries, numQuests = GetNumQuestLogEntries();
	local i, j;
	local lqi, lqj, lqNum = string.find(QuestGuru_LastCompleteQuest.Link, (":(%d+):"));
	if (not lqNum) then return; end
	
	local prevQuestLogEntry = GetQuestLogSelection();
	for i=1, numEntries do
		local qLink = GetQuestLink(i);
		local qi, qj, qNum;
		if (qLink) then
			qi, qj, qNum = string.find(qLink, (":(%d+):"));
		end
		local questTitle, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily = GetQuestLogTitle(i);
		if (isHeader) then
			QuestGuru_LastCompleteQuest.Header = questTitle;
		elseif (qNum == lqNum) then
			SelectQuestLogEntry(i);
			QuestGuru_LastCompleteQuest.Title = questTitle;
			QuestGuru_LastCompleteQuest.Level = level;
			QuestGuru_LastCompleteQuest.Tag = questTag;
			QuestGuru_LastCompleteQuest.SuggestedGroup = suggestedGroup;
			QuestGuru_LastCompleteQuest.Daily = isDaily;
			if (QuestGuru_LastCompleteQuest.Daily == 1) then
				QuestGuru_LastCompleteQuest.Count = 1;
			end

			QuestGuru_LastCompleteQuest.FinishTime = date(QG_DATETIME);
			QuestGuru_LastCompleteQuest.FinishLevel = UnitLevel("player");
			SetMapToCurrentZone();
			local player_x, player_y = GetPlayerMapPosition("player");
			QuestGuru_LastCompleteQuest.FinishPosX = floor(player_x * 10000) / 100;
			QuestGuru_LastCompleteQuest.FinishPosY = floor(player_y * 10000) / 100;

			if (not UnitName("npc") or UnitIsPlayer("npc")) then
				QuestGuru_LastCompleteQuest.FinishNPCName = QG_UNKNOWN;
				QuestGuru_LastCompleteQuest.FinishNPCZone = QG_UNKNOWN;
			else
				QuestGuru_LastCompleteQuest.FinishNPCName = UnitName("npc");
				local mmzText = GetMinimapZoneText();
				local zText = GetRealZoneText();
				if (mmzText == zText) then
					QuestGuru_LastCompleteQuest.FinishNPCZone = zText;
				else
					QuestGuru_LastCompleteQuest.FinishNPCZone = mmzText .. ", " .. zText;
				end
			end

			if (QuestGuru_QuestStart[questTitle] == nil) then
				QuestGuru_QuestStart[questTitle] = {};
				QuestGuru_QuestStart[questTitle].StartTime = date(QG_DATETIME);
				QuestGuru_QuestStart[questTitle].NPCName = QG_UNKNOWN;
				QuestGuru_QuestStart[questTitle].NPCZone = QG_UNKNOWN;
				QuestGuru_QuestStart[questTitle].PosX = 0;
				QuestGuru_QuestStart[questTitle].PosY = 0;
				QuestGuru_QuestStart[questTitle].Level = 0;
			end
			QuestGuru_LastCompleteQuest.StartTime = QuestGuru_QuestStart[questTitle].StartTime;
			QuestGuru_LastCompleteQuest.StartNPCName = QuestGuru_QuestStart[questTitle].NPCName;
			QuestGuru_LastCompleteQuest.StartNPCZone = QuestGuru_QuestStart[questTitle].NPCZone;
			QuestGuru_LastCompleteQuest.StartPosX = QuestGuru_QuestStart[questTitle].PosX;
			QuestGuru_LastCompleteQuest.StartPosY = QuestGuru_QuestStart[questTitle].PosY;
			QuestGuru_LastCompleteQuest.StartLevel = QuestGuru_QuestStart[questTitle].Level;

			local questDescription, questObjectives = GetQuestLogQuestText();
			QuestGuru_LastCompleteQuest.Description = gsub(questDescription,QuestGuru_Player,"<name>");
			QuestGuru_LastCompleteQuest.ObjectiveText = gsub(questObjectives,QuestGuru_Player,"<name>");
			QuestGuru_LastCompleteQuest.qID = QuestGuru_GetQuestID(QuestGuru_LastCompleteQuest.Title, QuestGuru_LastCompleteQuest.ObjectiveText, QuestGuru_LastCompleteQuest.Description);

			local numObjectives = GetNumQuestLeaderBoards();
			QuestGuru_LastCompleteQuest.Objectives = numObjectives;
			QuestGuru_LastCompleteQuest.Objective = {};
			for j=1, numObjectives do
				local desc, type, done = GetQuestLogLeaderBoard(j, i);
				QuestGuru_LastCompleteQuest.Objective[j] = {};
				QuestGuru_LastCompleteQuest.Objective[j].Type = type;
				if (type == "item") then
					local itemLink = QuestGuru_GetQuestItemLink(j, i);
					local x, y, name, numItems, numNeeded = string.find(desc, QG_ITEM_REQ_STR);
					if (itemLink == nil) then
						itemLink = name;
					end
					QuestGuru_LastCompleteQuest.Objective[j].Description = itemLink;
					QuestGuru_LastCompleteQuest.Objective[j].numNeeded = numNeeded;
				else
					QuestGuru_LastCompleteQuest.Objective[j].Description = desc;
				end

			end

			QuestGuru_LastCompleteQuest.RequiredMoney = GetQuestLogRequiredMoney();

			local numRewards = GetNumQuestLogRewards();
			QuestGuru_LastCompleteQuest.Rewards = numRewards;
			QuestGuru_LastCompleteQuest.Reward = {};
			for j=1, numRewards do
				name, texture, numItems, quality, isUsable = GetQuestLogRewardInfo(j);
				QuestGuru_LastCompleteQuest.Reward[j] = {};
				QuestGuru_LastCompleteQuest.Reward[j].Link = GetQuestLogItemLink("reward", j);
				QuestGuru_LastCompleteQuest.Reward[j].Count = numItems;
			end

			local numChoices = GetNumQuestLogChoices();
			QuestGuru_LastCompleteQuest.Choices = numChoices;
			QuestGuru_LastCompleteQuest.Choice = {};
			for j=1, numChoices do
				name, texture, numItems, quality, isUsable = GetQuestLogChoiceInfo(j);
				QuestGuru_LastCompleteQuest.Choice[j] = {};
				QuestGuru_LastCompleteQuest.Choice[j].Link = GetQuestLogItemLink("choice", j);
				QuestGuru_LastCompleteQuest.Choice[j].Count = numItems;
			end

			if (GetRewardSpell()) then
			    QuestGuru_LastCompleteQuest.SpellRewards = 1;
			    QuestGuru_LastCompleteQuest.SpellReward = {};
				texture, name, isTradeskillSpell, isSpellLearned = GetQuestLogRewardSpell();
				QuestGuru_LastCompleteQuest.SpellReward.Texture = texture;
				QuestGuru_LastCompleteQuest.SpellReward.Name = name;
			else
			    QuestGuru_LastCompleteQuest.SpellRewards = 0;
			end
			
			QuestGuru_LastCompleteQuest.RewardMoney = GetRewardMoney();
			QuestGuru_LastCompleteQuest.Honor = GetRewardHonor();
			QuestGuru_LastCompleteQuest.Talents = GetRewardTalents();
			QuestGuru_LastCompleteQuest.RewardTitle = GetQuestLogRewardTitle();
			return;
		end
	end
	SelectQuestLogEntry(prevQuestLogEntry);
	QuestGuru_LastCompleteQuest = {};
	QuestGuru_UpdateHistoryDB();
end

function QuestGuru_SaveLastXPRep(qLink)
	local i, j, qH, XPRep;

	for i, qH in ipairs(QuestGuru_History) do
		if (qH.Link == qLink) then
		    for j, XPRep in pairs(QuestGuru_LastXPRep) do
		        if (j == "XP") then -- experience gain
					qH.XP = XPRep;
				else -- Faction
				    if (qH.FactionGain == nil) then
				        qH.FactionGain = {};
					end
					qH.FactionGain[j] = XPRep;
				end
		    end
		end
	end
	QuestGuru_LastXPRep = {};
end

function QuestGuru_UpdateHistory()
	local count=0;
	local headCount = 0;
	local titleCount = 0;
	local currHistory = 1;
	local lastHeader = 0;
	local currHeadCount = 0;
	local currHeader = "";
	local questHistory;
	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	
	local questIndex, questHistoryTitle, questTitleTag, questLevel, questNormalText, questHighlight;
	local questLogTitleText, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily, color;
	local numPartyMembers, partyMembersOnQuest, tempWidth, textWidth;
	local questTagText, strLvl, textLeft;
	
	QuestGuru_QuestHistoryHighlightFrame:Hide();

	for i, questHistory in ipairs(QuestGuru_History) do
		if ((titleCount+headCount >= scrollOffset) or (questHistory.Header ~= currHeader and titleCount+headCount+1==scrollOffset)) then
			if (currHistory <= QUESTGURU_QUESTS_DISPLAYED) then

				if ((titleCount+headCount+1) == scrollOffset and questHistory.Header ~= currHeader) then
					currHeader = questHistory.Header;
					headCount = headCount + 1;
				else
					if (questHistory.Header ~= currHeader) then
						if (lastHeader > 0) then
							lastHeadTitle = getglobal("QuestGuru_QuestHistoryTitle"..lastHeader);
							if (QuestGuru_Settings.HeaderQuests) then lastHeadTitle:SetText(currHeader.." ("..currHeadCount..")"); end
						end
						currHeadCount = 0;
						lastHeader = currHistory;
						questHistoryTitle = getglobal("QuestGuru_QuestHistoryTitle"..currHistory);
						questTitleTag = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Tag");
						questLevel = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Level");
						questNormalText = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."NormalText");
						questHighlight = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Highlight");
						questHistoryTitle:SetText(questHistory.Header);
						if (QuestGuru_HistoryHeaders[questHistory.Header] ~= false) then
							questHistoryTitle:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
							QuestGuru_HistoryHeaders[questHistory.Header] = true;
						else
							questHistoryTitle:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
						end
						questHighlight:SetTexture("Interface\\Buttons\\UI-PlusButton-Hilight");
						questHistoryTitle.isHeader = true;
						questHistoryTitle.qID = "";
						currHeader = questHistory.Header;
						color = QuestDifficultyColor["header"];
						questTitleTag:SetText("");
						questTitleTag:SetTextColor(color.r, color.g, color.b);
						questLevel:SetText("");
						questHistoryTitle:SetNormalFontObject(color.font);
						questHistoryTitle.r = color.r;
						questHistoryTitle.g = color.g;
						questHistoryTitle.b = color.b;
						questHistoryTitle:Show();
						textLeft = 20;
						questNormalText:SetPoint("LEFT", textLeft, 0);
						headCount = headCount + 1;
						currHistory = currHistory + 1;
					end
				end

				if ((currHistory <= QUESTGURU_QUESTS_DISPLAYED) and (QuestGuru_HistoryHeaders[questHistory.Header] ~= false) and (strfind(strlower(questHistory.Title),strlower(QuestGuru_QuestHistorySearch:GetText())))) then
					questHistoryTitle = getglobal("QuestGuru_QuestHistoryTitle"..currHistory);
					questTitleTag = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Tag");
					questLevel = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Level");
					questNormalText = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."NormalText");
					questHighlight = getglobal("QuestGuru_QuestHistoryTitle"..currHistory.."Highlight");
	
					strLvl = questHistory.Level
					if (questHistory.Daily) then
					    strLvl = strLvl.."Y";
					end
					if (questHistory.Tag ~= nil) then
						if ((questHistory.Tag == "Group") and (questHistory.SuggestedGroup > 0)) then
							strLvl = strLvl.."G"..questHistory.SuggestedGroup;
						elseif (questHistory.Tag == "Dungeon") then
							strLvl = strLvl.."D";
						else
							strLvl = strLvl.."+"
						end
					end
					questLevel:SetText(strLvl);
					local s = questHistory.Title;
					if (questHistory.Count ~= nil and questHistory.Daily) then
						s = s.." ("..questHistory.Count..")";
					end
					questHistoryTitle:SetText(s);

					if (QuestGuru_Settings.ShowLevels == nil) then
					    QuestGuru_Settings.ShowLevels = {};
					end
					if (QuestGuru_Settings.ShowLevels.History) then
					    questLevel:Show();
					    textLeft = 40;
					else
					    questLevel:Hide();
					    textLeft = 16;
					end
					questNormalText:SetPoint("LEFT", textLeft, 0);

					QuestGuru_QuestLogDummyText:SetText(s);
	
					questHistoryTitle:SetNormalTexture("");
					questHighlight:SetTexture("");
    	
					-- Save if its a header or not
					questHistoryTitle.isHeader = false;
					
					if (questHistory.qID == nil) then
						questHistory.qID = QuestGuru_GetQuestID(questHistory.Title, questHistory.ObjectiveText, questHistory.Description);
					end
					questHistoryTitle.qID = questHistory.qID;
					if (QuestGuru_Quests[QuestGuru_RealmName][questHistory.qID] == nil) then
					    QuestGuru_Quests[QuestGuru_RealmName][questHistory.qID] = {};
					end
					
					if (questHistory.Link == nil) then
					    questHistory.Link = QuestGuru_Quests[QuestGuru_RealmName][questHistory.qID]["_link"];
					end
					if (questHistory.Link) then
						local qIDi, qIDj, qNum = string.find(questHistory.Link, (":(%d+):"));
					    if (QuestGuru_Quests[QuestGuru_RealmName][qNum] == nil) then
					        QuestGuru_Quests[QuestGuru_RealmName][qNum] = {};
						end
						QuestGuru_Quests[QuestGuru_RealmName][qNum][questHistory.qID] = 1;
					end
    	
					questTag = questHistory.Tag;
					if ( questTag ) then
					    if ((questTag == "Group") and (questHistory.SuggestedGroup == 0)) then
					        questTag = "Elite";
						end
						questTagText = "("..questTag
						if ((questHistory.SuggestedGroup ~= nil) and (questHistory.SuggestedGroup > 0)) then
							questTagText = questTagText..":"..questHistory.SuggestedGroup;
						end
						questTagText = questTagText..")";
						questTitleTag:SetText(questTagText);
						-- Shrink text to accomdate quest tags without wrapping
						tempWidth = 300 - textLeft - 8 - questTitleTag:GetWidth();
					
						if ( QuestGuru_QuestLogDummyText:GetWidth() > tempWidth ) then
							textWidth = tempWidth;
						else
							textWidth = QuestGuru_QuestLogDummyText:GetWidth();
						end
					
						questNormalText:SetWidth(tempWidth);
					else
						questTitleTag:SetText("");
						questNormalText:SetWidth(300 - textLeft);
					end
    	
					-- Color the quest title and highlight according to the difficulty level
					local playerLevel = UnitLevel("player");
					color = GetDifficultyColor(questHistory.Level);
					questTitleTag:SetTextColor(color.r, color.g, color.b);
					questHistoryTitle:SetNormalFontObject(color.font);
					questLevel:SetTextColor(color.r, color.g, color.b);
					questHistoryTitle.r = color.r;
					questHistoryTitle.g = color.g;
					questHistoryTitle.b = color.b;
					questHistoryTitle:Show();
        	
					-- Place the highlight and lock the highlight state
					if ( QuestGuru_currHistory == currHistory + scrollOffset ) then
						QuestGuru_QuestHistoryHighlightFrame:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryTitle"..currHistory, "TOPLEFT", 0, 0);
						QuestGuru_QuestHistorySkillHighlight:SetVertexColor(questHistoryTitle.r, questHistoryTitle.g, questHistoryTitle.b);
						QuestGuru_QuestHistoryHighlightFrame:Show();
						questTitleTag:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
						questLevel:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
						questHistoryTitle:LockHighlight();
					else
						questHistoryTitle:UnlockHighlight();
					end

					currHistory = currHistory + 1;
				end
			else
				if (questHistory.Header ~= currHeader) then
					if (lastHeader > 0) then
						lastHeadTitle = getglobal("QuestGuru_QuestHistoryTitle"..lastHeader);
						if (QuestGuru_Settings.HeaderQuests) then lastHeadTitle:SetText(currHeader.." ("..currHeadCount..")"); end
					end
					currHeadCount = 0;
					lastHeader = 0;
					currHeader = questHistory.Header;
					headCount = headCount + 1;
				end
			end
		else
			if (questHistory.Header ~= currHeader) then
				if (lastHeader > 0) then
					lastHeadTitle = getglobal("QuestGuru_QuestHistoryTitle"..lastHeader);
					if (QuestGuru_Settings.HeaderQuests) then lastHeadTitle:SetText(currHeader.." ("..currHeadCount..")"); end
				end
				currHeadCount = 0;
				lastHeader = 0;
				currHeader = questHistory.Header;
				headCount = headCount + 1;
			end
		end
		if (QuestGuru_HistoryHeaders[questHistory.Header] ~= false) then
			titleCount = titleCount + 1;
		end
		currHeadCount = currHeadCount + 1;
		count = count + 1;
	end
	if (lastHeader > 0) then
		lastHeadTitle = getglobal("QuestGuru_QuestHistoryTitle"..lastHeader);
		if (QuestGuru_Settings.HeaderQuests) then lastHeadTitle:SetText(currHeader.." ("..currHeadCount..")"); end
	end

	-- ScrollFrame update
	FauxScrollFrame_Update(QuestGuru_QuestHistoryListScrollFrame, titleCount + headCount, QUESTGURU_QUESTS_DISPLAYED, QUESTLOG_QUEST_HEIGHT, nil, nil, nil, QuestGuru_QuestHistoryHighlightFrame, 293, 316 )
	local currTab = PanelTemplates_GetSelectedTab(QuestGuru_QuestLogFrame);
	if ( count == 0 ) then
	    if (currTab == 2) then
	        QuestGuru_QuestLogNoQuestsText:SetText(QG_HISTORY_NONE);
			QuestGuru_EmptyQuestLogFrame:Show();
		end
		QuestGuru_QuestHistoryDetailScrollFrame:Hide();
	else
	    if (currTab == 2) then
			QuestGuru_EmptyQuestLogFrame:Hide();
		end
		QuestGuru_QuestHistoryDetailScrollFrame:Show();
	end
	QuestGuru_QuestLogFrameTab2:SetText(QG_TAB_HISTORY.." ("..count..")");
	QuestGuru_UpdateTabs();

	for i=currHistory, QUESTGURU_QUESTS_DISPLAYED do
		getglobal("QuestGuru_QuestHistoryTitle"..i):Hide();
	end
end

function QuestLog_SetHistorySelection(questID)
	local selectedQuest;

	QuestGuru_currHistory = questID;

	if ( questID == 0 ) then
		QuestGuru_QuestHistoryDetailScrollFrame:Hide();
		QuestGuru_UpdateHistory();
		return;
	end

	-- Get xml id
	local id = questID - FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);

	local titleButton = getglobal("QuestGuru_QuestHistoryTitle"..id);
	local titleButtonTag = getglobal("QuestGuru_QuestHistoryTitle"..id.."Tag");

	if ( titleButton.isHeader ) then
		local n, qH, currHead;
		local c = 0;
		for n, qH in ipairs(QuestGuru_History) do
			if (qH.Header ~= currHead) then
				currHead = qH.Header;
				c = c + 1;
				if (c == questID) then
					if ( QuestGuru_HistoryHeaders[currHead] == true ) then
						QuestGuru_HistoryHeaders[currHead] = false;
					else
						QuestGuru_HistoryHeaders[currHead] = true;
					end
				end
			end
			if (QuestGuru_HistoryHeaders[currHead] ~= false) then
				c = c + 1;
			end
		end
		QuestGuru_UpdateHistory();
	else
		-- Set newly selected quest and highlight it
		local scrollFrameOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
		if ( questID > scrollFrameOffset and questID <= (scrollFrameOffset + QUESTGURU_QUESTS_DISPLAYED) ) then
			titleButton:LockHighlight();
			titleButtonTag:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
			QuestGuru_QuestHistorySkillHighlight:SetVertexColor(titleButton.r, titleButton.g, titleButton.b);
			QuestGuru_QuestHistoryHighlightFrame:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryTitle"..id, "TOPLEFT", 5, 0);
			QuestGuru_QuestHistoryHighlightFrame:Show();
		end
		QuestLog_UpdateQuestHistoryDetails();
	end
end

function QuestLog_UpdateQuestHistoryDetails(doNotScroll)
	local questHistory;
	local questFound = false;
	local i, qH, NPCColor, PosColor;

	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local qID = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset).qID;
	
	for i, qH in ipairs(QuestGuru_History) do
		if (qH.qID == qID) then
			questHistory = qH;
			questFound = true;
			break;
		end
	end
	
	if (not questFound) then return; end
	
	if (not questHistory.Link) then
		QuestGuru_CommSendPGMessage("0201", qID);
	end
	
	local questTitle = questHistory.Title;
	local lastObjective;

-- Added LightHeaded support
if (IsAddOnLoaded("LightHeaded")) then
	if (PanelTemplates_GetSelectedTab(QuestGuru_QuestLogFrame) == 2) then
		if (questHistory.Link) then
			local i, j, qNum = string.find(questHistory.Link, (":(%d+):"));
			if LightHeaded.db.profile.singlepage then
				LightHeaded:UpdateFrame(tonumber(qNum), nil)
			else
				LightHeaded:UpdateFrame(tonumber(qNum), 1)
			end
		else
			LightHeaded:UpdateFrame(0, nil);
		end
	end
end
-- End LightHeaded support

	if ( not questTitle ) then
		questTitle = "";
	end
	QuestGuru_QuestHistoryQuestTitle:SetText(questTitle);

	local questDescription = gsub(questHistory.Description,"<name>",QuestGuru_Player);

	QuestGuru_QuestHistoryObjectivesText:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryQuestTitle", "BOTTOMLEFT", 0, -5);
	QuestGuru_QuestHistoryStart:Hide();
	QuestGuru_QuestHistoryFinish:Hide();
	if (questHistory ~= nil) then
		if ((questHistory.StartNPCName == nil) or (questHistory.StartNPCName == "Unknown") or (questHistory.StartNPCName == QG_UNKNOWN)) then
			if (questHistory.Link) then
				local qhi, qhj, qNum = string.find(questHistory.Link, (":(%d+):"));
				if (qNum and QuestGuru_Quests[QuestGuru_RealmName][qNum] and QuestGuru_Quests[QuestGuru_RealmName][qNum].StartInfo) then
					local qsi, qsj, qsNPC, qsZone, qsX, qsY = string.find(QuestGuru_Quests[QuestGuru_RealmName][qNum].StartInfo, "(.*);(.*);(.*);(.*)");
					if (qsi and qsj) then
						questHistory.StartNPCName = qsNPC;
						questHistory.StartNPCZone = qsZone;
						questHistory.StartPosX = qsX;
						questHistory.StartPosY = qsY;
					end
				end
			end
		end
		if ((questHistory.StartNPCName ~= nil) and (questHistory.StartNPCName ~= QG_UNKNOWN) and (questHistory.StartNPCName ~= "Unknown") and (questHistory.StartPosX ~= nil) and (questHistory.StartPosY ~= nil)) then
			QuestGuru_QuestHistoryStartNPCName:SetText(questHistory.StartNPCName);
			if (QuestGuru_Settings.Colorize.NPCNames.Enabled) then
				NPCColor = QuestGuru_Settings.Colorize.NPCNames.Color;
			else
				NPCColor = { r=0, g=0, b=0 };
			end
			QuestGuru_QuestHistoryStartNPCName:SetTextColor(NPCColor.r, NPCColor.g, NPCColor.b);
			QuestGuru_QuestHistoryStartPos:SetText("(" .. floor(questHistory.StartPosX) .. "," .. floor(questHistory.StartPosY) .. ")");
			if (QuestGuru_Settings.Colorize.AreaNames.Enabled) then
				PosColor = QuestGuru_Settings.Colorize.AreaNames.Color;
			else
				PosColor = { r=0, g=0, b=0 };
			end
			QuestGuru_QuestHistoryStartPos:SetTextColor(PosColor.r, PosColor.g, PosColor.b);
			local tempWidth = QuestGuru_QuestHistoryStartLabel:GetWidth() + QuestGuru_QuestHistoryStartPos:GetWidth();
			QuestGuru_QuestHistoryStartNPCName:SetWidth(285 - tempWidth);
			QuestGuru_QuestHistoryStart:Show();
			QuestGuru_QuestHistoryObjectivesText:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryStart", "BOTTOMLEFT", 0, -8);
		else
			if (questHistory.Link) then
				local qhi, qhj, qNum = string.find(questHistory.Link, (":(%d+):"));
				if (qNum) then QuestGuru_CommSendPGMessage("0209", qNum); end
			end
		end
	    if ((questHistory.FinishNPCName == nil) or (questHistory.FinishNPCName == "Unknown") or (questHistory.FinishNPCName == QG_UNKNOWN)) then
			if (questHistory.Link) then
				local qhi, qhj, qNum = string.find(questHistory.Link, (":(%d+):"));
	        	if (qNum and QuestGuru_Quests[QuestGuru_RealmName][qNum] and QuestGuru_Quests[QuestGuru_RealmName][qNum].FinishInfo) then
	        	    local qsi, qsj, qsNPC, qsZone, qsX, qsY = string.find(QuestGuru_Quests[QuestGuru_RealmName][qNum].FinishInfo, "(.*);(.*);(.*);(.*)");
	        	    if (qsi and qsj) then
	        	        questHistory.FinishNPCName = qsNPC;
	        	        questHistory.FinishNPCZone = qsZone;
	        	        questHistory.FinishPosX = qsX;
	        	        questHistory.FinishPosY = qsY;
	        	    end
	        	end
	        end
	    end
		if ((questHistory.FinishNPCName ~= nil) and (questHistory.FinishNPCName ~= QG_UNKNOWN) and (questHistory.FinishNPCName ~= "Unknown") and (questHistory.FinishPosX ~= nil) and (questHistory.FinishPosY ~= nil)) then
			QuestGuru_QuestHistoryFinishNPCName:SetText(questHistory.FinishNPCName);
			if (QuestGuru_Settings.Colorize.NPCNames.Enabled) then
				NPCColor = QuestGuru_Settings.Colorize.NPCNames.Color;
			else
				NPCColor = { r=0, g=0, b=0 };
			end
			QuestGuru_QuestHistoryFinishNPCName:SetTextColor(NPCColor.r, NPCColor.g, NPCColor.b);
			QuestGuru_QuestHistoryFinishPos:SetText("(" .. floor(questHistory.FinishPosX) .. "," .. floor(questHistory.FinishPosY) .. ")");
			if (QuestGuru_Settings.Colorize.AreaNames.Enabled) then
				PosColor = QuestGuru_Settings.Colorize.AreaNames.Color;
			else
				PosColor = { r=0, g=0, b=0 };
			end
			QuestGuru_QuestHistoryFinishPos:SetTextColor(PosColor.r, PosColor.g, PosColor.b);
			local tempWidth = QuestGuru_QuestHistoryFinishLabel:GetWidth() + QuestGuru_QuestHistoryFinishPos:GetWidth();
			QuestGuru_QuestHistoryFinishNPCName:SetWidth(285 - tempWidth);
			QuestGuru_QuestHistoryFinish:Show();
			QuestGuru_QuestHistoryObjectivesText:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryFinish", "BOTTOMLEFT", 0, -8);
		else
			if (questHistory.Link) then
				local qhi, qhj, qNum = string.find(questHistory.Link, (":(%d+):"));
				if (qNum) then QuestGuru_CommSendPGMessage("020B", qNum); end
			end
		end
	end

	local questObjectives = gsub(questHistory.ObjectiveText,"<name>",QuestGuru_Player);

	questObjectives = QuestGuru_ColorizeText(questObjectives);
	QuestGuru_QuestHistoryObjectivesText:SetText(questObjectives);

	QuestGuru_QuestHistoryTimerText:Hide();
	QuestGuru_QuestHistoryObjective1:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectivesText", "BOTTOMLEFT", 0, -10);

	local numObjectives = questHistory.Objectives;
	local currObj = 0;

	for i=1, 10 do
		getglobal("QuestGuru_QuestHistoryObjective"..i):Hide();
		getglobal("QuestGuru_QuestHistoryObjectiveItem"..i):Hide();
	end

	for i=1, numObjectives, 1 do
		local text = questHistory.Objective[i].Description;
		local type = questHistory.Objective[i].Type;
		if (type ~= "item") then
			currObj = currObj + 1;
			local string = getglobal("QuestGuru_QuestHistoryObjective"..currObj);
			if ( not text or strlen(text) == 0 ) then
				text = type;
			end
			string:SetTextColor(0, 0, 0);
			string:SetText(text);
			string:Show();
			QuestFrame_SetAsLastShown(string);
			lastObjective = string;
		end
	end

	local currObjItem = 0;
	for i=1, numObjectives, 1 do
		local text = questHistory.Objective[i].Description;
		local type = questHistory.Objective[i].Type;
		local texture, link;
		if (type == "item") then
			currObjItem = currObjItem + 1;
			local questItem = getglobal("QuestGuru_QuestHistoryObjectiveItem"..currObjItem);
			questItem.type = "required";
			numItems = 1;
			local itemLink = text;
			local numNeeded = questHistory.Objective[i].numNeeded;
			if (not itemLink) then
				texture = "Interface\\Icons\\INV_Misc_QuestionMark";
			else
				name, link, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(itemLink);
				if ((texture == nil) and string.find(itemLink, "Hitem:")) then
					GameTooltip:SetHyperlink(itemLink);
					GameTooltip:Show();
					GameTooltip:Hide();
					questItem.timerEnabled = true;
				elseif (not string.find(itemLink, "Hitem:")) then
				    texture = GetItemIcon(itemLink);
				    if (not texture) then texture = "Interface\\Icons\\INV_Misc_QuestionMark"; end
				    name = itemLink;
				    itemLink = nil;
				end
			end
			questItem:SetID(currObjItem)
			-- For the tooltip
			questItem.rewardType = "item"
			questItem.link = itemLink;
			QuestFrame_SetAsLastShown(questItem, QuestGuru_QuestHistorySpacerFrame);
			getglobal(questItem:GetName().."Name"):SetText(name);
			SetItemButtonCount(questItem, tonumber(numNeeded));
			SetItemButtonTexture(questItem, texture);
			SetItemButtonTextureVertexColor(questItem, 1, 1, 1);
			SetItemButtonNameFrameVertexColor(questItem, 1, 1, 1);
			if ( currObjItem > 1 ) then
				if ( mod(currObjItem, 2) == 1 ) then
					questItem:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectiveItem"..(currObjItem - 2), "BOTTOMLEFT", 0, -2);
					lastObjective = questItem;
				else
					questItem:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectiveItem"..(currObjItem - 1), "TOPRIGHT", 1, 0);
					lastObjective = getglobal("QuestGuru_QuestHistoryObjectiveItem"..(currObjItem - 1));
				end
			else
				if (currObj > 0) then
					questItem:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjective"..currObj, "BOTTOMLEFT", 0, -5);
				else
					questItem:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectivesText", "BOTTOMLEFT", 0, -10);
				end
				lastObjective = questItem;
			end
			questItem:Show();
		end
	end


	-- If there's money required then anchor and display it
	if ( questHistory.RequiredMoney > 0 ) then
		if ( numObjectives > 0 ) then
			QuestGuru_QuestHistoryRequiredMoneyText:SetPoint("TOPLEFT", lastObjective, "BOTTOMLEFT", 0, -4);
		else
			QuestGuru_QuestHistoryRequiredMoneyText:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectivesText", "BOTTOMLEFT", 0, -10);
		end

		MoneyFrame_Update("QuestGuru_QuestHistoryRequiredMoneyFrame", questHistory.RequiredMoney);

		QuestGuru_QuestHistoryRequiredMoneyText:SetTextColor(0.2, 0.2, 0.2);
		SetMoneyFrameColor("QuestGuru_QuestHistoryRequiredMoneyFrame", 1.0, 1.0, 1.0);

		QuestGuru_QuestHistoryRequiredMoneyText:Show();
		QuestGuru_QuestHistoryRequiredMoneyFrame:Show();
	else
		QuestGuru_QuestHistoryRequiredMoneyText:Hide();
		QuestGuru_QuestHistoryRequiredMoneyFrame:Hide();
	end

	if ( questHistory.SuggestedGroup > 0 ) then
		local suggestedGroupString = format(QUEST_SUGGESTED_GROUP_NUM, questHistory.SuggestedGroup);
		QuestGuru_QuestHistorySuggestedGroupNum:SetText(suggestedGroupString);
		QuestGuru_QuestHistorySuggestedGroupNum:Show();
		QuestGuru_QuestHistorySuggestedGroupNum:ClearAllPoints();
		if ( questHistory.RequiredMoney > 0 ) then
			QuestGuru_QuestHistorySuggestedGroupNum:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryRequiredMoneyText", "BOTTOMLEFT", 0, -4);
		elseif ( numObjectives > 0 ) then
			QuestGuru_QuestHistorySuggestedGroupNum:SetPoint("TOPLEFT", lastObjective, "BOTTOMLEFT", 0, -4);
		else
			QuestGuru_QuestHistorySuggestedGroupNum:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectivesText", "BOTTOMLEFT", 0, -10);
		end
	else
		QuestGuru_QuestHistorySuggestedGroupNum:Hide();
	end

	if ( questHistory.SuggestedGroup > 0 ) then
		QuestGuru_QuestHistoryDescriptionTitle:SetPoint("TOPLEFT", "QuestGuru_QuestHistorySuggestedGroupNum", "BOTTOMLEFT", 0, -10);
	elseif ( questHistory.RequiredMoney > 0 ) then
		QuestGuru_QuestHistoryDescriptionTitle:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryRequiredMoneyText", "BOTTOMLEFT", 0, -10);
	elseif ( numObjectives > 0 ) then
		QuestGuru_QuestHistoryDescriptionTitle:SetPoint("TOPLEFT", lastObjective, "BOTTOMLEFT", 0, -10);
	else
		QuestGuru_QuestHistoryDescriptionTitle:SetPoint("TOPLEFT", "QuestGuru_QuestHistoryObjectivesText", "BOTTOMLEFT", 0, -10);
	end
	if ( questDescription ) then
	    questDescription = QuestGuru_ColorizeText(questDescription);
		QuestGuru_QuestHistoryQuestDescription:SetText(questDescription);
		QuestFrame_SetAsLastShown(QuestGuru_QuestHistoryQuestDescription);
	end
	local numRewards = questHistory.Rewards;
	local numChoices = questHistory.Choices;
	local money = questHistory.RewardMoney;
	local honor = questHistory.Honor;
	local talents = questHistory.Talents;
	local playerTitle = questHistory.RewardTitle;
	local XP = questHistory.XP;
	if (XP == nil) then XP = 0; end

	if ( playerTitle or (numRewards + numChoices + money + honor + talents + XP) > 0 ) then
		QuestGuru_QuestHistoryRewardTitleText:Show();
		QuestFrame_SetAsLastShown(QuestGuru_QuestHistoryRewardTitleText);
	else
		QuestGuru_QuestHistoryRewardTitleText:Hide();
	end

	QuestGuru_QuestHistoryFrameItems_Update("QuestHistory");
	if ( not doNotScroll ) then
		QuestGuru_QuestHistoryDetailScrollFrameScrollBar:SetValue(0);
	end
	QuestGuru_QuestHistoryDetailScrollFrame:UpdateScrollChildRect();
end

function QuestGuru_QuestHistoryFrameItems_Update(questState)
	local isQuestLog = 0;
	local questHistory;
	local i, j, qH;
	
	if ( questState == "QuestHistory" ) then
		isQuestLog = 1;
		questState = "QuestGuru_QuestHistory";
	end

   	local scrollOffset = FauxScrollFrame_GetOffset(QuestGuru_QuestHistoryListScrollFrame);
	local qID = getglobal("QuestGuru_QuestHistoryTitle"..QuestGuru_currHistory - scrollOffset).qID;

	for i, qH in ipairs(QuestGuru_History) do
		if (qH.qID == qID) then
			questHistory = qH;
			questFound = true;
			break;
		end
	end
	
	if (not questFound) then
	    return
	end

	local numQuestRewards = questHistory.Rewards;
	local numQuestChoices = questHistory.Choices;
	local numQuestSpellRewards = questHistory.SpellRewards;
	local money = questHistory.RewardMoney;
	local honor = questHistory.Honor;
	local talents = questHistory.Talents;
	local playerTitle = questHistory.RewardTitle;
	local XP = questHistory.XP;
	if (XP == nil) then XP=0; end
	local spacerFrame = QuestGuru_QuestHistorySpacerFrame;

	local totalRewards = numQuestRewards + numQuestChoices + numQuestSpellRewards;
	local questItemName = questState.."Item";
	local material = QuestFrame_GetMaterial();
	local moneyFrame = getglobal(questState.."MoneyFrame");
	local honorFrame = getglobal(questState.."HonorFrame");
	local talentFrame = getglobal(questState.."TalentFrame");
	local playerTitleFrame = getglobal(questState.."PlayerTitleFrame");
	local questItemReceiveText = getglobal(questState.."ItemReceiveText")
	local anchorFrame = nil;
	
	anchorFrame = getglobal(questState.."RewardTitleText");
	if ((totalRewards == 0) and (money == 0) and (honor == 0) and (talents == 0) and (XP == 0) and (not playerTitle)) then
		anchorFrame:Hide();
	else
		anchorFrame:Show();
		QuestFrame_SetTitleTextColor(anchorFrame, material);
		QuestFrame_SetAsLastShown(anchorFrame, spacerFrame);
	end
	if ( money == 0 ) then
		moneyFrame:Hide();
	else
		anchorFrame = questItemReceiveText;
		moneyFrame:Show();
		QuestFrame_SetAsLastShown(moneyFrame, spacerFrame);
		MoneyFrame_Update(questState.."MoneyFrame", money);
	end

	if (honor == 0) then
		honorFrame:Hide();
	else
		honorFrame:Show();
		QuestHonorFrame_Update(questState.."HonorFrame", honor);
		honorFrame:ClearAllPoints();
		if (money == 0) then
			honorFrame:SetPoint("LEFT", questItemReceiveText, "RIGHT", 15, 0);
			anchorFrame = questItemReceiveText;
		else
			honorFrame:SetPoint("LEFT", moneyFrame, "RIGHT", -5, 0);
			anchorFrame = honorFrame;
		end
		QuestFrame_SetAsLastShown(honorFrame, spacerFrame);
	end

	if (talents == 0) then
		talentFrame:Hide();
	else
		if ( honor ~= 0 ) then
			talentFrame:SetPoint("TOPLEFT", honorFrame, "BOTTOMLEFT", 0, -5);
		end
		talentFrame:Show();
		anchorFrame = talentFrame;
		QuestTalentFrame_Update(questState.."TalentFrame", talents);
		QuestFrame_SetAsLastShown(talentFrame, spacerFrame);
	end

	if ( not playerTitle ) then
		playerTitleFrame:Hide();
	else
		playerTitleFrame:SetPoint("TOP", anchorFrame, "BOTTOM", 0, -5);
		playerTitleFrame:SetPoint("LEFT", questState.."ItemReceiveText", "LEFT", -3, -5);
		getglobal(questState.."PlayerTitleFrameTitle"):SetText(playerTitle);
		playerTitleFrame:Show();
		anchorFrame = playerTitleFrame;
		QuestFrame_SetAsLastShown(playerTitleFrame, spacerFrame);
	end
	
	-- Hide unused rewards
	for i = 1, 10 do
		getglobal(questItemName..i):Hide();		
	end

	local questItem, name, texture, isTradeskillSpell, isSpellLearned, quality, isUsable, numItems;
	local rewardsCount = 0;

	-- Setup choosable rewards
	QuestHistoryItemHighlight:Hide();
	if ( numQuestChoices > 0 ) then
		local itemChooseText = getglobal(questState.."ItemChooseText");
		itemChooseText:Show();
		QuestFrame_SetTextColor(itemChooseText, material);
		QuestFrame_SetAsLastShown(itemChooseText, spacerFrame);

		local index;
		local baseIndex = rewardsCount;
		for i=1, numQuestChoices, 1 do
			index = i + baseIndex;
			questItem = getglobal(questItemName..index);
			questItem.type = "choice";
			if (questHistory.Choice[i].Link) then
				name, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(questHistory.Choice[i].Link)
				if (texture == nil) then
					GameTooltip:SetHyperlink(questHistory.Choice[i].Link);
					GameTooltip:Show();
					GameTooltip:Hide();
					questItem.timerEnabled = true;
				end
			else
				texture = "Interface\\Icons\\INV_Misc_QuestionMark";
				name = "Unknown";
			end
			numItems = questHistory.Choice[i].Count;
			if (not numItems) then numItems = 1; end

			questItem:SetID(i)
			questItem:Show();
			-- For the tooltip
			questItem.rewardType = "item"
			QuestFrame_SetAsLastShown(questItem, spacerFrame);
			getglobal(questItemName..index.."Name"):SetText(name);
			SetItemButtonCount(questItem, numItems);
			SetItemButtonTexture(questItem, texture);
			questItem.link = questHistory.Choice[i].Link;
			if (questHistory.Choice[i].Selected) then
				QuestHistoryItemHighlight:SetPoint("TOPLEFT", questItem, "TOPLEFT", -8, 7);
				QuestHistoryItemHighlight:Show();
			end
			if ( i > 1 ) then
				if ( mod(i,2) == 1 ) then
					questItem:SetPoint("TOPLEFT", questItemName..(index - 2), "BOTTOMLEFT", 0, -2);
					anchorFrame = getglobal(questItemName..index);
				else
					questItem:SetPoint("TOPLEFT", questItemName..(index - 1), "TOPRIGHT", 1, 0);
					anchorFrame = getglobal(questItemName..(index - 1));
				end
			else
				questItem:SetPoint("TOPLEFT", itemChooseText, "BOTTOMLEFT", -3, -5);
				anchorFrame = getglobal(questItemName..index);
			end
			rewardsCount = rewardsCount + 1;
		end
	else
		getglobal(questState.."ItemChooseText"):Hide();
	end

	-- Setup spell rewards
	if ( numQuestSpellRewards > 0 ) then
		local learnSpellText = getglobal(questState.."SpellLearnText");
		learnSpellText:Show();
		QuestFrame_SetTextColor(learnSpellText, material);
		QuestFrame_SetAsLastShown(learnSpellText, spacerFrame);

		--Anchor learnSpellText if there were choosable rewards
		if ( rewardsCount > 0 ) then
			learnSpellText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 3, -5);
		else
			learnSpellText:SetPoint("TOPLEFT", questState.."RewardTitleText", "BOTTOMLEFT", 0, -5);
		end

		texture = questHistory.SpellReward.Texture;
		name = questHistory.SpellReward.Name;

		learnSpellText:SetText(REWARD_SPELL);

		rewardsCount = rewardsCount + 1;
		questItem = getglobal(questItemName..rewardsCount);
		questItem:Show();
		-- For the tooltip
		questItem.link = GetSpellLink(name);
		questItem.rewardType = "spell";
		SetItemButtonCount(questItem, 0);
		SetItemButtonTexture(questItem, texture);
		getglobal(questItemName..rewardsCount.."Name"):SetText(name);
		questItem:SetPoint("TOPLEFT", learnSpellText, "BOTTOMLEFT", -3, -5);
		anchorFrame = getglobal(questItemName..rewardsCount);
	else
		getglobal(questState.."SpellLearnText"):Hide();
	end

	-- Setup mandatory rewards
	if ( numQuestRewards > 0 or money > 0 or honor > 0 or talents > 0) then
		QuestFrame_SetTextColor(questItemReceiveText, material);
		-- Anchor the reward text differently if there are choosable rewards
		if ( numQuestSpellRewards > 0  ) then
			questItemReceiveText:SetText(REWARD_ITEMS);
			questItemReceiveText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 3, -5);
		elseif ( numQuestChoices > 0  ) then
			questItemReceiveText:SetText(REWARD_ITEMS);
			local index = numQuestChoices;
			if ( mod(index, 2) == 0 ) then
				index = index - 1;
			end
			questItemReceiveText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 3, -5);
		else
			questItemReceiveText:SetText(REWARD_ITEMS_ONLY);
			questItemReceiveText:SetPoint("TOPLEFT", questState.."RewardTitleText", "BOTTOMLEFT", 3, -5);
		end
		anchorFrame = questItemReceiveText;
		if (money ~=0 and honor ~=0) then anchorFrame = honorFrame; end
		if (talents ~= 0) then anchorFrame = talentFrame; end
		if (playerTitle) then achorFrame = playerTitleFrame; end
		questItemReceiveText:Show();
		QuestFrame_SetAsLastShown(questItemReceiveText, spacerFrame);
		-- Setup mandatory rewards
		local index;
		local baseIndex = rewardsCount;
		for i=1, numQuestRewards, 1 do
			index = i + baseIndex;
			questItem = getglobal(questItemName..index);

			questItem.type = "reward";
			name, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(questHistory.Reward[i].Link);
			if (texture == nil) then
				GameTooltip:SetHyperlink(questHistory.Reward[i].Link);
				GameTooltip:Show();
				GameTooltip:Hide();
				questItem.timerEnabled = true;
			end
			numItems = questHistory.Reward[i].Count;

			questItem:SetID(i)
			questItem:Show();
			-- For the tooltip
			questItem.link = questHistory.Reward[i].Link;
			questItem.rewardType = "item";
			QuestFrame_SetAsLastShown(questItem, spacerFrame);
			getglobal(questItemName..index.."Name"):SetText(name);
			SetItemButtonCount(questItem, numItems);
			SetItemButtonTexture(questItem, texture);
			SetItemButtonTextureVertexColor(questItem, 1.0, 1.0, 1.0);
			SetItemButtonNameFrameVertexColor(questItem, 1.0, 1.0, 1.0);

			anchorFrame = getglobal(questItemName..index);
			if ( i > 1 ) then
				if ( mod(i,2) == 1 ) then
					questItem:SetPoint("TOPLEFT", questItemName..(index - 2), "BOTTOMLEFT", 0, -2);
				else
					questItem:SetPoint("TOPLEFT", questItemName..(index - 1), "TOPRIGHT", 1, 0);
					anchorFrame = getglobal(questItemName..(index-1));
				end
			elseif (talents > 0) then
				questItem:SetPoint("TOPLEFT", talentFrame, "BOTTOMLEFT", -3, -5);
			elseif (honor > 0) then
				questItem:SetPoint("TOPLEFT", questState.."HonorFrame", "BOTTOMLEFT", -3, -5);
			else
				questItem:SetPoint("TOPLEFT", questState.."ItemReceiveText", "BOTTOMLEFT", -3, -5);
			end
			rewardsCount = rewardsCount + 1;
		end
	else
		questItemReceiveText:Hide();
	end
		
	if (questHistory.XP) then
		QuestGuru_QuestHistoryXPText:SetText(QG_HISTORY_EXPGAIN..questHistory.XP);
		if (rewardsCount > 0) then
			QuestGuru_QuestHistoryXPText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 3, -5)
		else
			QuestGuru_QuestHistoryXPText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 0, -5)
		end
		QuestGuru_QuestHistoryXPText:Show();
		anchorFrame = QuestGuru_QuestHistoryXPText;
	else
		QuestGuru_QuestHistoryXPText:SetText("");
		QuestGuru_QuestHistoryXPText:Hide();
	end
		
	if (questHistory.FactionGain) then
		local tmp = QG_HISTORY_REPGAIN;
		for i, j in pairs (questHistory.FactionGain) do
			tmp = tmp.."\n"..i..": ";
			if (tonumber(j) > 0) then tmp = tmp.."+"; end
			tmp = tmp..j;
		end
		QuestGuru_QuestHistoryRepText:SetText(tmp);
		QuestGuru_QuestHistoryRepText:SetPoint("TOPLEFT", anchorFrame, "BOTTOMLEFT", 0, -4);
		QuestGuru_QuestHistoryRepText:Show();
	else
		QuestGuru_QuestHistoryRepText:SetText("");
		QuestGuru_QuestHistoryRepText:Hide();
	end
end

function QuestGuru_CheckHistoryVersion()
	local i, qH, prevH, z, ls, rs;
	
	if (QuestGuru_History.Version == nil) then
		for i, qH in ipairs(QuestGuru_History) do
			qH.Description = gsub(qH.Description, QuestGuru_Player, "<name>");
			qH.ObjectiveText = gsub(qH.ObjectiveText, QuestGuru_Player, "<name>");
			if (qH.Daily == 1 and qH.Count == nil) then qH.Count = 1; end
		end
		QuestGuru_History.Version = 2;
	end
	
	if (QuestGuru_History.Version == 2) then
		for i, qH in ipairs(QuestGuru_History) do
			if (qH.Honor == nil) then qH.Honor = 0; end
		end
		QuestGuru_History.Version = 3;
	end
	
	for i, qH in ipairs(QuestGuru_History) do
		if (qH.Talents == nil) then qH.Talents = 0; end
		if (qH.StartTime == nil) then qH.StartTime = date(QG_DATETIME); end
		if (qH.FinishTime == nil) then qH.FinishTime = date(QG_DATETIME); end
		if (qH.Daily == 1 and qH.Count == nil) then qH.Count = 1; end
		if (qH.StartNPCName == nil) then qH.StartNPCName = QG_UNKNOWN; end
		if (qH.StartNPCZone == nil) then qH.StartNPCZone = QG_UNKNOWN; end
		if (qH.StartPosX == nil) then qH.StartPosX = 0; end
		if (qH.StartPosY == nil) then qH.StartPosY = 0; end
		if (qH.StartLevel == nil) then qH.StartLevel = 0; end
		if (qH.FinishNPCName == nil) then qH.FinishNPCName = QG_UNKNOWN; end
		if (qH.FinishNPCZone == nil) then qH.FinishNPCZone = QG_UNKNOWN; end
		if (qH.FinishPosX == nil) then qH.FinishPosX = 0; end
		if (qH.FinishPosY == nil) then qH.FinishPosY = 0; end
		if (qH.FinishLevel == nil) then qH.FinishLevel = 0; end
		if (qH.Honor == nil) then qH.Honor = 0; end
		if (qH.RewardMoney == nil) then qH.RewardMoney = 0; end
		if (qH.XP == nil) then qH.XP = 0; end
   		if (qH.qID == nil) then
   			local qID = QuestGuru_GetQuestID(qH.Title, qH.ObjectiveText, qH.Description);
   			qH.qID = qID;
   		end

   		local questObjectives = qH.ObjectiveText;
		if (string.find(questObjectives, "Quest initiated by:")) then
		    -- Convert QuestInitiators data to QuestStart data
		    local qii, qij, qiNPC, qiArea, qiZone, qiX, qiY = string.find(questObjectives, "Quest initiated by: %c(.-), in (.-) of (.-). %(([%d]+),([%d]+)%)|r%c%c");
		    if (qii and qij) then
				qH.StartNPCName = qiNPC;
				qH.StartPosX = qiX;
				qH.StartPosY = qiY;
				qH.StartNPCZone = qiArea..", "..qiZone;
				qH.ObjectiveText = string.sub(questObjectives, qij+1);
	   			qH.qID = QuestGuru_GetQuestID(qH.Title, qH.ObjectiveText, qH.Description);
	   		else
				qii, qij = string.find(questObjectives, "Quest initiated by: %cPlayer or Item. Exact location unknown.|r%c%c");
				if (qii and qij) then
					qH.ObjectiveText = string.sub(questObjectives, qij+1);
		   			qH.qID = QuestGuru_GetQuestID(qH.Title, qH.ObjectiveText, qH.Description);					
				end
		    end
		end

		if (qH.StartNPCZone) then
			z = string.find(qH.StartNPCZone, " in ");
			if (z) then
				ls = strsub(qH.StartNPCZone, 1, z - 1);
				rs = strsub(qH.StartNPCZone, z + 4);
				qH.StartNPCZone = ls..", "..rs;
			end
		end
		if (qH.FinishNPCZone) then
			z = string.find(qH.FinishNPCZone, " in ");
			if (z) then
				ls = strsub(qH.FinishNPCZone, 1, z - 1);
				rs = strsub(qH.FinishNPCZone, z + 4);
				qH.FinishNPCZone = ls..", "..rs;
			end
		end

		if (i>1) then
			if (qH.qID == prevH.qID) then
				if (prevH.Count == nil) then prevH.Count = 1; end
				prevH.Count = prevH.Count + 1;
				tremove(QuestGuru_History, i);
				i = i - 1;
			else
				prevH = qH;
			end
		else
			prevH = qH;
		end
	end
end

function QuestGuru_UpdateHistoryDB()
	if (QuestGuru_Quests[QuestGuru_RealmName] == nil) then return; end
	if (QuestGuru_Items[QuestGuru_RealmName] == nil) then return; end

	local i, j, qH, qID;

   	for i, qH in ipairs(QuestGuru_History) do
   		if (qH.qID == nil) then
   			qID = QuestGuru_GetQuestID(qH.Title, qH.ObjectiveText, qH.Description);
   			qH.qID = qID;
   		else
   			qID = qH.qID;
   		end
   		if (qID == nil) then return; end
		if (QuestGuru_Quests[QuestGuru_RealmName][qID] == nil) then
			QuestGuru_Quests[QuestGuru_RealmName][qID] = {};
			QuestGuru_Quests[QuestGuru_RealmName][qID].level = qH.Level;
		end
		QuestGuru_Quests[QuestGuru_RealmName][qID][QuestGuru_Player] = "Complete";
		
		local qIDLink = QuestGuru_Quests[QuestGuru_RealmName][qID]["_link"];
		if (qIDLink) then
			local qIDi, qIDj, qNum = string.find(qIDLink, (":(%d+):"));
			if (qNum) then
				if ((QuestGuru_Quests[QuestGuru_RealmName][qNum].StartInfo == nil) and qH.StartNPCName and (qH.StartNPCName ~= "Unknown") and (qH.StartNPCName ~= QG_UNKNOWN) and qH.StartNPCZone and (qH.StartNPCZone ~= "Unknown") and (qH.StartNPCZone ~= QG_UNKNOWN) and qH.StartPosX and qH.StartPosY) then
				    QuestGuru_Quests[QuestGuru_RealmName][qNum].StartInfo = qH.StartNPCName..";"..qH.StartNPCZone..";"..qH.StartPosX..";"..qH.StartPosY;
				end
				if ((QuestGuru_Quests[QuestGuru_RealmName][qNum].FinishInfo == nil) and qH.FinishNPCName and (qH.FinishNPCName ~= "Unknown") and (qH.FinishNPCName ~= QG_UNKNOWN) and qH.FinishNPCZone and (qH.FinishNPCZone ~= "Unknown") and (qH.FinishNPCZone ~= QG_UNKNOWN) and qH.FinishPosX and qH.FinishPosY) then
				    QuestGuru_Quests[QuestGuru_RealmName][qNum].FinishInfo = qH.FinishNPCName..";"..qH.FinishNPCZone..";"..qH.FinishPosX..";"..qH.FinishPosY;
				end
			end
		end

		for j=1, qH.Objectives do
		    if ((qH.Objective[j].Type == "item") and qH.Objective[j].Description) then
				name, link, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, texture = GetItemInfo(qH.Objective[j].Description);
				if (name and link) then
					QuestGuru_Items[QuestGuru_RealmName][name] = link;
				end
			end
		end
	end
end