miVersionNo = ' 3.26'

MI2_Debug = 0
MI2_DebugItems = 0
MI2_DebugEvents = 0
MI2_DbgData = nil
MI2_DB_VERSION = 9
MI2_DB_SV = 1
MI2_IMPORT_DB_VERSION = 6

local MI2_RecentLoots, MI2_MobCache, MI2_MobCacheIdx, MI2_XRefItemTable
local MI2_NewCorpseIdx = 0
local MI2_CurrentCorpseIndex = nil
local MI2_RecentLoots = {}
local MI2_SpellToSchool = {}
local MI2_CACHE_SIZE = 30

local miSkinLoot = { [2934]=1, [2318]=1, [2319]=1, [4234]=1, [4304]=1, [8170]=1,
			[15423]=1,[15417]=1,[15422]=1,[15419]=1,[17012]=1, [5082]=1, [25699]=1,
			[21887]=1,[25649]=1,[20499]=1,[20498]=1,[25700]=1,[25707]=1,
			[783]=1, [4232]=1, [4235]=1, [8169]=1, [8171]=1, [7428]=1, [8368]=1,
			[8154]=1,[7287]=1, [8167]=1, [7286]=1,[12607]=1,
			[15416]=1,[15415]=1,[15414]=1,[15412]=1, [8165]=1,[15408]=1,
			[6470]=1, [6471]=1, [7392]=1, [8165]=1,
			[23107]=1, [24189]=1, [21929]=1,  }

local miClothLoot = { [2589]=1, [2592]=1, [4306]=1, [4338]=1, [14256]=1, [14047]=1, [14342]=1, [21877 ]=1 };

local MI2_ItemCollapseList = { [2725]=0, [2728]=0, [2730]=0, [2732]=0,
				[2734]=0, [2735]=0, [2738]=0, [2740]=0, [2742]=0,
				[2745]=0, [2748]=0, [2749]=0, [2750]=0, [2751]=0 }

mifontBlue = "|cff0000ff"
mifontItemBlue = "|cff2060ff"
mifontLightBlue = "|cff00e0ff"
mifontLightGreen = "|cff60ff60"
mifontGreen = "|cff00ff00"
mifontRed = "|cffff0000"
mifontLightRed = "|cffff8080"
mifontGold = "|cffffcc00"
mifontGray = "|cff888888"
mifontWhite = "|cffffffff"
mifontSubWhite = "|cffbbbbbb"
mifontMageta = "|cffe040ff"
mifontYellow  = "|cffffff00"
mifontCyan   = "|cff00ffff"
mifontOrange = "|cffff7000"
MI2_QualityColor = { [1]=mifontGray, [2]=mifontWhite, [3]=mifontGreen, [4]=mifontItemBlue, [5]=mifontMageta, [6]=mifontOrange, [7]=mifontRed }

function MI2_GetMobData( mobName, mobLevel, unitId )
	if not mobName or not mobLevel then return end
	local mobData = {}
	local mobIndex = mobName..":"..mobLevel
	MI2_GetUnitBasedMobData( mobIndex, mobData, unitId, mobLevel )
	local mobInfo = MobInfoDB[mobIndex]
	if  mobInfo then
		MI2_GetMobDataFromMobInfo( mobInfo, mobData )
	end
	return mobData
end

function MI2_GetMobDataFromMobInfo( mobInfo, mobData )
	MI2_DecodeBasicMobData( mobInfo, mobData )
	MI2_DecodePlayerSpecificData( mobInfo, mobData, MI2_PlayerName )
	MI2_DecodeQualityOverview( mobInfo, mobData )
	MI2_DecodeMobLocation( mobInfo, mobData )
	MI2_DecodeItemList( mobInfo, mobData )
	MI2_DecodeResists( mobInfo, mobData )
end

function MI2_GetUnitBasedMobData( mobIndex, mobData, unitId, mobLevel )
	local mobPPP = MobHealth_PPP(mobIndex)
	if mobPPP <= 0 then mobPPP = 1 end
	mobData.healthMax = floor(mobPPP * 100 + 0.5)
	if unitId then
		mobData.class = UnitClass(unitId)
		if UnitHealthMax(unitId) == 100 then
			mobData.healthCur = floor(mobPPP * UnitHealth(unitId) + 0.5)
		else
			mobData.healthCur = UnitHealth(unitId)
		end
		mobData.manaCur = UnitMana( unitId )
		mobData.manaMax = UnitManaMax( unitId )
	end
	mobData.color = GetDifficultyColor( mobLevel )
end

function MI2_FetchMobData( mobIndex )
	local mobData = MI2_MobCache[mobIndex]
	if mobIndex and not mobData then
		local mobInfo = MobInfoDB[mobIndex]
		mobData = { mobType=1, resists={} }
		if mobInfo then
			MI2_GetMobDataFromMobInfo( mobInfo, mobData )
		end
		MI2_MobCache[mobIndex] = mobData

		local oldMob = MI2_MobCache[MI2_MobCacheIdx]
		if oldMob then
			MI2_MobCache[oldMob] = nil
		end
		MI2_MobCache[MI2_MobCacheIdx] = mobIndex
		MI2_MobCacheIdx = MI2_MobCacheIdx + 1
		if MI2_MobCacheIdx > MI2_CACHE_SIZE then
			MI2_MobCacheIdx = 1
		end
	end
	return mobData
end

function MI2_DecodeBasicMobData( mobInfo, mobData, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
		if not mobInfo then
			mobData.loots = 1
			return
		end
	end
	mobData.mobType = 1
	if mobInfo.bi then
		local a,b,lt,el,cp,iv,cc,xp,mt,sc = string.find( mobInfo.bi, "(%d*)/(%d*)/(%d*)/(%d*)/(%d*)/(%d*)/(%d*)/(%d*)")
		mobData.loots		= tonumber(lt)
		mobData.emptyLoots	= tonumber(el)
		mobData.xp			= tonumber(xp)
		mobData.clothCount	= tonumber(cc)
		mobData.copper		= tonumber(cp)
		mobData.itemValue	= tonumber(iv)
		mobData.mobType		= tonumber(mt) or 1
		mobData.skinCount	= tonumber(sc)
	end
	if mobData.mobType > 10 then
		mobData.lowHpAction = floor(mobData.mobType / 10)
		mobData.mobType = mobData.mobType - mobData.lowHpAction * 10
	end
end

function MI2_DecodeMobLocation( mobInfo, mobData, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
	end
	if mobInfo.ml then
		local a,b,x1,y1,x2,y2,c,z = string.find( mobInfo.ml, "(%d*)/(%d*)/(%d*)/(%d*)/(%d*)/(%d*)")
		mobData.location = {}
		mobData.location.x1	= tonumber(x1)
		mobData.location.y1	= tonumber(y1)
		mobData.location.x2	= tonumber(x2)
		mobData.location.y2	= tonumber(y2)
		mobData.location.c	= tonumber(c)
		mobData.location.z	= (tonumber(z) or 0)
		if not mobData.location.x1 or not mobData.location.x2 or 
				not mobData.location.y1 or not mobData.location.y2 or 
				mobData.location.z == 0 then
			mobData.location = nil
		end
	end
end

function MI2_DecodeQualityOverview( mobInfo, mobData, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
	end
	if mobInfo.qi then
		local a,b,r1,r2,r3,r4,r5 = string.find( mobInfo.qi, "(%d*)/(%d*)/(%d*)/(%d*)/(%d*)")
		mobData.r1 = tonumber(r1)
		mobData.r2 = tonumber(r2)
		mobData.r3 = tonumber(r3)
		mobData.r4 = tonumber(r4)
		mobData.r5 = tonumber(r5)
	end
end

function MI2_DecodePlayerSpecificData( mobInfo, mobData, playerName, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
	end
	if mobInfo[playerName] then
		local a,b,kl,mind,maxd,dps,xp = string.find( mobInfo[playerName], "(%d*)/(%d*)/(%d*)/(%d*)/*(%d*)")
		mobData.kills = tonumber(kl)
		mobData.minDamage = tonumber(mind)
		mobData.maxDamage = tonumber(maxd)
		mobData.dps = tonumber(dps)
		if xp then
			mobData.xp = tonumber(xp)
		end
	end
end

function MI2_DecodeResists( mobInfo, mobData, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
	end
	if mobInfo.re then
		local a,b,ar,arHits,fi,fiHits,fr,frHits,ho,hoHits,na,naHits,sh,shHits = string.find( mobInfo.re, "(%-?%d*),(%-?%d*)/(%-?%d*),(%-?%d*)/(%-?%d*),(%-?%d*)/(%-?%d*),(%-?%d*)/(%-?%d*),(%-?%d*)/(%-?%d*),(%-?%d*)")
		mobData.resists = {}
		mobData.resists.ar = tonumber(ar)
		mobData.resists.fi = tonumber(fi)
		mobData.resists.fr = tonumber(fr)
		mobData.resists.ho = tonumber(ho)
		mobData.resists.na = tonumber(na)
		mobData.resists.sh = tonumber(sh)
		mobData.resists.arHits = tonumber(arHits)
		mobData.resists.fiHits = tonumber(fiHits)
		mobData.resists.frHits = tonumber(frHits)
		mobData.resists.hoHits = tonumber(hoHits)
		mobData.resists.naHits = tonumber(naHits)
		mobData.resists.shHits = tonumber(shHits)
	end
end

function MI2_DecodeItemList( mobInfo, mobData, mobIndex )
	if mobIndex then
		mobInfo = MobInfoDB[mobIndex]
	end
	if mobInfo.il then
		local lootItems = mobInfo.il
		local s,e, item, amount = string.find( lootItems, "(%d+)[:]?(%d*)" )
		if e then mobData.itemList = {} end
		while e do
			mobData.itemList[tonumber(item)] = tonumber(amount) or 1
			s,e, item, amount = string.find( lootItems, "/(%d+)[:]?(%d*)", e+1 )
		end
	end
end

local function MI2_StoreBasicInfo( mobIndex, mobData )
	local mobInfo = MobInfoDB[mobIndex]
	if not mobInfo then
		mobInfo = {}
		MobInfoDB[mobIndex] = mobInfo
	end
	local mobType = mobData.mobType or 1
	if mobData.lowHpAction then
		mobType = mobType + mobData.lowHpAction * 10
	end
	local basicInfo = (mobData.loots or "").."/"..(mobData.emptyLoots or "").."/"..(mobData.copper or "").."/"..(mobData.itemValue or "").."/"..(mobData.clothCount or "").."//"..(mobType or "").."/"..(mobData.skinCount or "")
	if basicInfo ~= "///////" then
		mobInfo.bi = basicInfo
	end
	local qualityInfo = (mobData.r1 or "").."/"..(mobData.r2 or "").."/"..(mobData.r3 or "").."/"..(mobData.r4 or "").."/"..(mobData.r5 or "")
	if qualityInfo ~= "////" then
		mobInfo.qi = qualityInfo
	end
end

function MI2_StoreLocation( mobIndex, loc )
	local mobInfo = MobInfoDB[mobIndex]
	if not mobInfo then
		mobInfo = {}
		MobInfoDB[mobIndex] = mobInfo
	end
	local locationInfo = (loc.x1 or "").."/"..(loc.y1 or "").."/"..(loc.x2 or "").."/"..(loc.y2 or "").."//"..(loc.z or "")
	if locationInfo ~= "/////" then
		mobInfo.ml = locationInfo
	end
end

local function MI2_StoreCharData( mobIndex, mobData, playerName )
	local mobInfo = MobInfoDB[mobIndex]
	if not mobInfo then
		mobInfo = {}
		MobInfoDB[mobIndex] = mobInfo
	end
	local playerInfo = (mobData.kills or "").."/"..(mobData.minDamage or "").."/"..(mobData.maxDamage or "").."/"..(mobData.dps or "").."/"..(mobData.xp or "")
	if playerInfo ~= "////" then
		mobInfo[playerName] = playerInfo
	end
end

local function MI2_StoreLootItems( mobIndex, mobData )
	local mobInfo = MobInfoDB[mobIndex]
	if not mobInfo then
		mobInfo = {}
		MobInfoDB[mobIndex] = mobInfo
	end
	local itemList = ""
	if mobData.itemList then
		local prefix = ""
		for itemID, amount in pairs(mobData.itemList) do
			itemList = itemList..prefix..itemID
			if amount > 1 then
				itemList = itemList..":"..amount
			end
			prefix = "/"
		end
	end
	if itemList ~= "" then
		mobInfo.il = itemList
	end
end

function MI2_StoreResistData( mobIndex )
	local mobData = MI2_FetchMobData( mobIndex )
	resData = mobData.resists
	if resData.ar or resData.fi or resData.fr or resData.ho or resData.na or resData.sh then
		local mobInfo = MobInfoDB[mobIndex]
		if not mobInfo then
			mobInfo = {}
			MobInfoDB[mobIndex] = mobInfo
		end
		local resistString = 
				(resData.ar or "")..","..(resData.arHits or "").."/"..
				(resData.fi or "")..","..(resData.fiHits or "").."/"..
				(resData.fr or "")..","..(resData.frHits or "").."/"..
				(resData.ho or "")..","..(resData.hoHits or "").."/"..
				(resData.na or "")..","..(resData.naHits or "").."/"..
				(resData.sh or "")..","..(resData.shHits or "")
		mobInfo.re = resistString
	end
end

function MI2_StoreAllMobData( mobData, mobName, mobLevel, playerName, mobIndex )
	if not mobIndex then
		mobIndex = mobName..":"..mobLevel
	end
	if MobInfoConfig.SaveBasicInfo == 1 then
		MI2_StoreBasicInfo( mobIndex, mobData )
	end
	if MobInfoConfig.SaveLocation == 1 and mobData.location then
		MI2_StoreLocation( mobIndex, mobData.location )
	end
	if MobInfoConfig.SaveCharData == 1 then
		MI2_StoreCharData( mobIndex, mobData, MI2_PlayerName )
	end
	if MobInfoConfig.SaveItems == 1 then
		MI2_StoreLootItems( mobIndex, mobData )
	end
	if MobInfoConfig.SaveResist == 1 then
		MI2_StoreResistData( mobIndex )
	end
end

function MI2_RemoveCharData( mobInfo )
	for entryName, entryData in pairs(mobInfo) do
		if entryName ~= "bi" and entryName ~= "qi" and entryName ~= "il" and entryName ~= "ml" and entryName ~= "ver" then
			mobInfo[entryName] = nil
		end
	end
end

function MI2_DeleteMobData( mobIndex, deleteHealth )
	if mobIndex then
		MobInfoDB[mobIndex] = nil
		MI2_MobCache[mobIndex] = nil
		if deleteHealth then
			MobHealthDB[mobIndex] = nil
		end
		if mobIndex == MI2_Target.mobIndex then
			MI2_Target = {}
			MobHealth_Display()
		end
	end
end

function MI2_DeleteItemFromDB( itemID )
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		local mobData = {}
		MI2_DecodeItemList( mobInfo, mobData )
		if mobData.itemList then
			mobData.itemList[itemID] = nil
			MI2_StoreLootItems( mobIndex, mobData )
		end
	end
	MI2_ItemNameTable[itemID] = nil
end

function MI2_SetPlayerName()
	local charName = GetCVar( "realmName" )..':'..UnitName("player")
	if not MI2_CharTable[charName] then
		MI2_CharTable.charCount = MI2_CharTable.charCount + 1
		MI2_CharTable[charName] = "c"..MI2_CharTable.charCount
	end
	MI2_PlayerName = MI2_CharTable[charName]
end

function MI2_ClearMobCache()
	MI2_MobCache = {}
	MI2_MobCacheIdx = 1
end

function MI2_DeleteAllMobData()
	MobInfoDB = { ["DatabaseVersion:0"] = { ver = MI2_DB_VERSION, loc=GetLocale(), sv=MI2_DB_SV } }
	MI2_CharTable = { charCount = 0 }
	MI2_ItemNameTable = {}
	MI2_XRefItemTable = {}
	MI2_SetPlayerName()
	MI2_ClearMobCache()
	MI2_ZoneTable = { cnt = 1 }
end

function MI2_InitializeAllMobData()
	if not MobInfoDB then
		MobInfoDB = { ["DatabaseVersion:0"] = { ver = MI2_DB_VERSION, loc=GetLocale(), sv=MI2_DB_SV } }
	end
	MI2_CharTable = MI2_CharTable or { charCount = 0 }
	MI2_ItemNameTable = MI2_ItemNameTable or {}
	MI2_XRefItemTable = MI2_XRefItemTable or {}
	MI2_ZoneTable = MI2_ZoneTable or { cnt = 1 }
	MobHealthDB	= MobHealthDB or {}
	MobHealthPlayerDB =	MobHealthPlayerDB or {}
	MI2_SetPlayerName()
	MI2_ClearMobCache()
end

function chattext(txt)
	if( DEFAULT_CHAT_FRAME ) then
		DEFAULT_CHAT_FRAME:AddMessage( mifontLightBlue.."<MI2> "..txt)
	end
end

function midebug( txt, dbgLevel )
	if DEFAULT_CHAT_FRAME then
		if dbgLevel then
			if dbgLevel <= MI2_Debug then
				DEFAULT_CHAT_FRAME:AddMessage( mifontLightBlue.."[MI2DBG] "..txt)
			end
		else
			DEFAULT_CHAT_FRAME:AddMessage( mifontLightBlue.."<MI2DBG> "..txt)
		end
	end
end

 function MI2_InitOptions()
	if not MobInfoConfig or not MobInfoConfig.ShowLoots then
		MobInfoConfig = { }
		MI2_SlashAction_Default()
	end
	if  not MobInfoConfig.ShowBlankLines	then  MobInfoConfig.ShowBlankLines = 1	end
	if  not MobInfoConfig.DisableMobInfo	then  MobInfoConfig.DisableMobInfo = 0	end
	if  not MobInfoConfig.ShowDamage	then  MobInfoConfig.ShowDamage = 1		end
	if  not MobInfoConfig.ShowMana		then  MobInfoConfig.ShowMana = 1		end
	if  not MobInfoConfig.ShowEmpty		then  MobInfoConfig.ShowEmpty = 0		end
	if  not MobInfoConfig.CombinedMode	then  MobInfoConfig.CombinedMode = 0	end
	if  not MobInfoConfig.ShowCombined	then  MobInfoConfig.ShowCombined = 1	end
	if  not MobInfoConfig.KeypressMode	then  MobInfoConfig.KeypressMode = 0	end
	if  not MobInfoConfig.TargetHealth	then  MobInfoConfig.TargetHealth = 1	end
	if  not MobInfoConfig.TargetMana	then  MobInfoConfig.TargetMana = 1		end
	if  not MobInfoConfig.HealthPercent	then  MobInfoConfig.HealthPercent = 1	end
	if  not MobInfoConfig.ManaPercent	then  MobInfoConfig.ManaPercent = 1		end
	if  not MobInfoConfig.HealthPosX	then  MobInfoConfig.HealthPosX = -7		end
	if  not MobInfoConfig.HealthPosY	then  MobInfoConfig.HealthPosY = 11		end
	if  not MobInfoConfig.ManaPosX		then  MobInfoConfig.ManaPosX = -7		end
	if  not MobInfoConfig.ManaPosY		then  MobInfoConfig.ManaPosY = 11		end
	if  not MobInfoConfig.SavePlayerHp	then  MobInfoConfig.SavePlayerHp = 0	end
	if  not MobInfoConfig.CompactMode	then  MobInfoConfig.CompactMode = 1		end
	if  not MobInfoConfig.ShowItems		then  MobInfoConfig.ShowItems = 1		end
	if  not MobInfoConfig.SaveItems		then  MobInfoConfig.SaveItems = 1		end
	if  not MobInfoConfig.SaveCharData	then  MobInfoConfig.SaveCharData = 1	end
	if  not MobInfoConfig.ItemsQuality	then  MobInfoConfig.ItemsQuality = 2	end
	if  not MobInfoConfig.SaveBasicInfo	then  MobInfoConfig.SaveBasicInfo = 1	end
	if  not MobInfoConfig.ItemTooltip	then  MobInfoConfig.ItemTooltip = 1		end
	if  not MobInfoConfig.ItemFilter	then  MobInfoConfig.ItemFilter = ""		end
	if  not MobInfoConfig.ShowLocation	then  MobInfoConfig.ShowLocation = 1	end
	if  not MobInfoConfig.SaveLocation	then  MobInfoConfig.SaveLocation = 1	end
	if  not MobInfoConfig.ShowClothSkin	then  MobInfoConfig.ShowClothSkin = 1	end
	if  not MobInfoConfig.ImportOnlyNew	then  MobInfoConfig.ImportOnlyNew = 0	end
	if  not MobInfoConfig.SaveResist	then  MobInfoConfig.SaveResist = 1		end
	if  not MobInfoConfig.ShowResists	then  MobInfoConfig.ShowResists = 1		end
	if  not MobInfoConfig.ShowLowHpAction	then  MobInfoConfig.ShowLowHpAction = 1	end
	if  not MobInfoConfig.ShowItemPrice	then  MobInfoConfig.ShowItemPrice = 0	end
	if  not MobInfoConfig.DisableHealth  then  
		MobInfoConfig.DisableHealth = (MobInfoConfig.HealthOff or 0)
	end
	MobInfoConfig.HealthOff = nil
	MobInfoConfig.ManaDistance = nil
	MobInfoConfig.ShowPercent = nil
	MobInfoConfig.CustomTracks = nil
	MobInfoConfig.SaveAllValues = nil
	MobInfoConfig.MobDbVersion = nil
	MobInfoConfig.MobDbVersion = nil
	MobInfoConfig.ClearOnExit = nil
	MobInfoConfig.SaveGoodItems = nil
	MobInfoConfig.SaveQualityData = nil
	MobInfoConfig.OptStableMax = nil
end

function MI2_GetIndexComponents( mobIndex )
	local a, b, mobName, mobLevel = string.find(mobIndex, "(.+):(.+)$")
	mobLevel = tonumber(mobLevel)
	return mobName, mobLevel
end

local function MI2_UpdateDatabaseToV7()
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		if (mobInfo.lt or mobInfo.el or mobInfo.cp or mobInfo.iv or mobInfo.cc) and not mobInfo.bi then
			if mobInfo.lt and mobInfo.lt <= 0 then mobInfo.lt = nil end
			if mobInfo.cp and mobInfo.cp <= 0 then mobInfo.cp = nil end
			if mobInfo.iv and mobInfo.iv <= 0 then mobInfo.iv = nil end
			if mobInfo.el and mobInfo.el <= 0 then mobInfo.el = nil end
			if mobInfo.cc and mobInfo.cc <= 0 then mobInfo.cc = nil end
			mobInfo.bi = (mobInfo.lt or "").."/"..(mobInfo.el or "").."/"..(mobInfo.cp or "").."/"..(mobInfo.iv or "").."/"..(mobInfo.cc or "").."//"..(mobInfo.mt or "").."/"
		end
		local s, slashCount = string.gsub( (mobInfo.bi or ""), "/", "@" )
		if slashCount == 6 then mobInfo.bi = mobInfo.bi.."/"; slashCount = slashCount + 1 end
		if mobInfo.bi == "////////" then mobInfo.bi = nil end
		if mobInfo.bi and slashCount ~= 7 then mobInfo.bi = nil end
		if (mobInfo.r0 or mobInfo.r1 or mobInfo.r2 or mobInfo.r3 or mobInfo.r4) and not mobInfo.qi then
			if mobInfo.r0 and mobInfo.r0 <= 0 then mobInfo.r0 = nil end
			if mobInfo.r1 and mobInfo.r1 <= 0 then mobInfo.r1 = nil end
			if mobInfo.r2 and mobInfo.r2 <= 0 then mobInfo.r2 = nil end
			if mobInfo.r3 and mobInfo.r3 <= 0 then mobInfo.r3 = nil end
			if mobInfo.r4 and mobInfo.r4 <= 0 then mobInfo.r4 = nil end
			mobInfo.qi = (mobInfo.r0 or "").."/"..(mobInfo.r1 or "").."/"..(mobInfo.r2 or "").."/"..(mobInfo.r3 or "").."/"..(mobInfo.r4 or "")
		end
		if mobInfo.qi == "////" then  mobInfo.qi = nil  end
		for entryName, entryData in pairs(mobInfo) do
			if type(entryData) == "table" then
				local dl = entryData.dl
				local du = entryData.du
				local dd = entryData.dd
				if (dl or du) and not dd then
					dd = dl.."/"..du.."/"..0
				end
				mobInfo[entryName] = (entryData.kl or "").."/"..(dd or "").."/"..(mobInfo.xp or "")
			else
				local isCharEntry = (type(entryData) == "string") and (string.find(entryName,":") ~= nil or MI2_CharTable[entryName]) and string.find(entryData,"/") ~= nil
				isCharEntry = isCharEntry or type(entryData) == "string"
				if isCharEntry then
					if mobInfo[entryName] == "///" or mobInfo[entryName] == "///" then
						mobInfo[entryName] = nil
					end
				elseif entryName ~= "bi" and entryName ~= "qi" and entryName ~= "il" and entryName ~= "ml" and entryName ~= "re" then
					mobInfo[entryName] = nil
				end
			end
		end
	end
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		local entryCount = 0
		for entryName, entryData in pairs(mobInfo) do
			entryCount = entryCount + 1
			local isCharEntry = (type(entryData) == "string") and string.find(entryName,":") ~= nil and string.find(entryData,"/") ~= nil
			if isCharEntry then
				if not MI2_CharTable[entryName] then
					MI2_CharTable.charCount = MI2_CharTable.charCount + 1
					MI2_CharTable[entryName] = "c"..MI2_CharTable.charCount
				end
				mobInfo[MI2_CharTable[entryName]] = entryData
				mobInfo[entryName] = nil
			end
		end
		if entryCount == 0 then
			MobInfoDB[mobIndex] = nil
		end
	end
end

local function MI2_UpdateDatabaseV7ToV8()
	local zoneName, zoneId, mobIndex, mobInfo, newZoneTable
	newZoneTable = {}
	MI2_ZoneTable.cnt = nil
	for zoneName, zoneId in pairs(MI2_ZoneTable) do
		newZoneTable[zoneId] = zoneName
	end
	MI2_ZoneTable = newZoneTable
	MI2_ZoneTable.cnt = 0
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		local mobData = {}
		MI2_DecodeMobLocation( mobInfo, mobData )
		if mobData.location then
			local zone = mobData.location.z
			if zone < 100 then
				mobInfo.ml = nil
			end
		end
	end
end

local function MI2_UpdateDatabaseV8ToV9( cleanupMode )
	for idx, hpData in pairs(MobHealthDB) do
	    if type(hpData) == "string" then
			local _,_, pts, pct = string.find( hpData, "^(%d+)/(%d+)$")
			pts = tonumber(pts)
			pct = tonumber(pct)
			if not pct or not pts or pct <= 0 or pts <= 0 then
				MobHealthDB[idx] = nil
			else
			    local newPts = floor( (pts / pct) * 75.0 )
				MobHealthDB[idx] = newPts.."/"..75
			end
		else
		    MobHealthDB[idx] = nil
		end
	end
end

function MI2_CleanupDatabases()
	local mobIndex, mobInfo
	local dbVerInfo = MobInfoDB["DatabaseVersion:0"] or { ver=0 }
	local version = dbVerInfo.ver
	MI2_InitializeAllMobData()
	MobInfoDB["DatabaseVersion:0"] = nil
	MobInfoDB.DatabaseVersion = nil
	for mobIndex in pairs(MobInfoDB) do
		local mobName, mobLevel = MI2_GetIndexComponents( mobIndex )
		if not mobName or not mobLevel or mobName == "" then
			MobInfoDB[mobIndex] = nil
		end
	end
	if version < 7 then
		MI2_UpdateDatabaseToV7()
	end
	if version < 8 then
		MI2_UpdateDatabaseV7ToV8()
	end
	local subver = dbVerInfo.sv or 0
	if version < 9 or subver < 1 then
		MI2_UpdateDatabaseV8ToV9()
	end
	MobInfoDB["DatabaseVersion:0"] = { ver = MI2_DB_VERSION, loc=GetLocale(), sv=MI2_DB_SV }
end 

function MI2_PrepareForImport()
	local mobDbSize, healthDbSize, itemDbSize = 0, 0, 0
	if not MobInfoDB then return end
	local version = MobInfoDB["DatabaseVersion:0"].ver
	if version and (version < MI2_IMPORT_DB_VERSION or version > MI2_DB_VERSION) then
		MI2_Import_Status = "BADVER"
		return
	end
	local locale = MobInfoDB["DatabaseVersion:0"].loc
	if locale and locale ~= GetLocale() then
		MI2_Import_Status = "BADLOC"
		return
	end
	local levelSum, nameSum = 0, 0
	for index in pairs(MobInfoDB) do
		mobDbSize = mobDbSize + 1
		local mobName, mobLevel = MI2_GetIndexComponents( index )
		levelSum = levelSum + mobLevel
		nameSum = nameSum + string.len( mobName )
	end
	for index in pairs(MobHealthDB) do  healthDbSize = healthDbSize + 1  end
	for index in pairs(MI2_ItemNameTable) do  itemDbSize = itemDbSize + 1  end
	MI2_Import_Signature = mobDbSize.."_"..healthDbSize.."_"..itemDbSize.."_"..levelSum.."_"..nameSum
	if version  < 9 then
		MI2_UpdateDatabaseV8ToV9()
	end
	MobInfoDB["DatabaseVersion:0"] = nil
	MobInfoDB_Import = MobInfoDB
	MI2_ItemNameTable_Import = MI2_ItemNameTable
	MI2_ZoneTable_Import = MI2_ZoneTable
	MobHealthDB_Import = MobHealthDB
	if mobDbSize > 1 then
		MI2_Import_Status = "[V"..version.."] "..(mobDbSize-1).." Mobs"
	end
	if healthDbSize > 0 then
		if MI2_Import_Status then
			MI2_Import_Status = MI2_Import_Status.." & "
		end
		MI2_Import_Status = (MI2_Import_Status or "")..healthDbSize.." HP values"
	end
end

function MI2_SetNewZone( zoneName )
	if not zoneName or zoneName == "" then return end
	local name, id, zoneId
	for id, name in pairs(MI2_ZoneTable) do
		if name == zoneName then
			zoneId = id
			break
		end
	end
	if not zoneId then
		MI2_ZoneTable.cnt = MI2_ZoneTable.cnt + 1
		zoneId = 200 + MI2_ZoneTable.cnt
		MI2_ZoneTable[zoneId] = zoneName
	end
	MI2_CurZone = zoneId
end

local function MI2_AddItemToXRefTable( mobIndex, itemName, itemAmount )
	if not MI2_XRefItemTable[itemName] then
		MI2_XRefItemTable[itemName] = {}
	end
	local oldAmount = MI2_XRefItemTable[itemName][mobIndex]
	MI2_XRefItemTable[itemName][mobIndex] = (oldAmount or 0) + itemAmount
end

function MI2_BuildXRefItemTable()
	local mobIndex, mobInfo
	MI2_XRefItemTable = {}
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		local mobData = {}
		MI2_DecodeItemList( mobInfo, mobData )
		if mobData.itemList then 
			for itemID, amount in pairs(mobData.itemList) do
				local itemText = MI2_ItemNameTable[itemID]
				if itemText then
					itemText = string.sub( itemText, 1, -3 )
					MI2_AddItemToXRefTable( mobIndex, itemText, amount )
				end
			end
		end
	end
end

local function MI2_CombineLocations( mobData, loc2, correctWrongZone )
	local loc1 = mobData.location
	if loc1 or loc2 then
		if not loc1 or not loc1.z then
			mobData.location = loc2
		elseif loc2 then
			if loc1.z ~= loc2.z then
				if correctWrongZone then
					mobData.location = loc2
				end
			else
				if loc2.x1 < loc1.x1 then loc1.x1 = loc2.x1 end
				if loc2.x2 > loc1.x2 then loc1.x2 = loc2.x2 end
				if loc2.y1 < loc1.y1 then loc1.y1 = loc2.y1 end
				if loc2.y2 > loc1.y2 then loc1.y2 = loc2.y2 end
			end
		end
	end
end

function MI2_RecordLocationAndType( mobIndex )
	if MI2_MouseoverIndex == mobIndex then return end
	local mobData = MI2_FetchMobData( mobIndex )
	if MobInfoConfig.SaveLocation == 1 then
		local x, y = GetPlayerMapPosition("player")
		x = floor( x * 100.0 )
		y = floor( y * 100.0 )
		local newLocation = { x1=x, x2=x, y1=y, y2=y, z=MI2_CurZone }
		MI2_CombineLocations( mobData, newLocation, true )
		MI2_StoreLocation( mobIndex, mobData.location )
	end
	if MobInfoConfig.SaveBasicInfo == 1 then
		local mobType = UnitClassification("target")
		if mobType == "normal" then
		elseif mobType == "rare" or mobType == "elite" then
			mobData.mobType = 2
		elseif mobType == "rareelite" or mobType == "worldboss" then
			mobData.mobType = 3
		end
		if mobData.mobType > 1 then
			MI2_StoreBasicInfo( mobIndex, mobData )
		end
	end
end

function MI2_RecordLowHpAction( creature, action )
	if MobInfoConfig.SaveBasicInfo == 1 and MI2_Target.mobIndex and MI2_Target.name == creature then
		local mobData = MI2_FetchMobData( MI2_Target.mobIndex )
		mobData.lowHpAction = action
		MI2_StoreBasicInfo( MI2_Target.mobIndex, mobData )
	end
end

function MI2_RecordKill( creatureName, xp )
	local mobIndex
	if MI2_Target.name == creatureName then
		mobIndex = MI2_Target.mobIndex
	elseif MI2_LastTargetIdx and string.find(MI2_LastTargetIdx, creatureName) then
		mobIndex = MI2_LastTargetIdx
	else
		for i=1,MI2_CACHE_SIZE do
			local idx = MI2_MobCache[i]
			if idx and string.find(idx, creatureName) then
				mobIndex = idx
				break
			end
		end
	end
	if MobInfoConfig.SaveCharData == 1 and mobIndex then
		local mobData = MI2_FetchMobData( mobIndex )
		if xp then
			mobData.xp = xp
		end
		if (xp and not mobData.killed) or not xp then
			mobData.kills = (mobData.kills or 0) + 1
			mobData.killed = 1
		end
		MI2_StoreCharData( mobIndex, mobData, MI2_PlayerName )
	end
end

function MI2_RecordDamage( mobIndex, damage )
	if damage > 0 then
		local mobData = MI2_FetchMobData( mobIndex )
		if not mobData.minDamage or mobData.minDamage <= 0 then
			mobData.minDamage, mobData.maxDamage = damage, damage
		elseif damage < mobData.minDamage then
			mobData.minDamage = damage
		elseif damage > mobData.maxDamage then
			mobData.maxDamage = damage
		end
	end
end

function MI2_RecordDps( mobIndex, deltaTime, damage  )
	if MobInfoConfig.SaveCharData == 1 and deltaTime > 4 then
		local mobData = MI2_FetchMobData( mobIndex )
		local newDps = damage / deltaTime
		if not mobData.dps then mobData.dps = newDps end
		mobData.dps = floor( ((2.0 * mobData.dps) + newDps) / 3.0 )
		MI2_StoreCharData( mobIndex, mobData, MI2_PlayerName )
	end
end

function MI2_AddTwoMobs( mobData1, mobData2 )
	mobData1.loots = (mobData1.loots or 0) + (mobData2.loots or 0)
	mobData1.kills = (mobData1.kills or 0) + (mobData2.kills or 0)
	mobData1.emptyLoots = (mobData1.emptyLoots or 0) + (mobData2.emptyLoots or 0)
	mobData1.clothCount = (mobData1.clothCount or 0) + (mobData2.clothCount or 0)
	mobData1.copper = (mobData1.copper or 0) + (mobData2.copper or 0)
	mobData1.itemValue = (mobData1.itemValue or 0) + (mobData2.itemValue or 0)
	mobData1.skinCount = (mobData1.skinCount or 0) + (mobData2.skinCount or 0)
	mobData1.r1 = (mobData1.r1 or 0) + (mobData2.r1 or 0)
	mobData1.r2 = (mobData1.r2 or 0) + (mobData2.r2 or 0)
	mobData1.r3 = (mobData1.r3 or 0) + (mobData2.r3 or 0)
	mobData1.r4 = (mobData1.r4 or 0) + (mobData2.r4 or 0)
	mobData1.r5 = (mobData1.r5 or 0) + (mobData2.r5 or 0)
	if mobData2.mobType then mobData1.mobType = mobData2.mobType end
	if not mobData1.xp then mobData1.xp = mobData2.xp end
	if not mobData1.lowHpAction then mobData1.lowHpAction = mobData2.lowHpAction end
	MI2_CombineLocations( mobData1, mobData2.location )
	if not mobData1.dps then
		mobData1.dps = mobData2.dps
	else
		if mobData2.dps then
			mobData1.dps = floor( ((2.0 * mobData1.dps) + mobData2.dps) / 3.0 )
		end
	end
	local resdat1 = mobData1.resists or {}
	local resdat2 = mobData2.resists or {}
	resdat1.ar	= (resdat1.ar or 0) + (resdat2.ar or 0)
	resdat1.fi	= (resdat1.fi or 0) + (resdat2.fi or 0)
	resdat1.fr	= (resdat1.fr or 0) + (resdat2.fr or 0)
	resdat1.ho	= (resdat1.ho or 0) + (resdat2.ho or 0)
	resdat1.na	= (resdat1.na or 0) + (resdat2.na or 0)
	resdat1.sh	= (resdat1.sh or 0) + (resdat2.sh or 0)
	resdat1.arHits	= (resdat1.arHits or 0) + (resdat2.arHits or 0)
	resdat1.fiHits	= (resdat1.fiHits or 0) + (resdat2.fiHits or 0)
	resdat1.frHits	= (resdat1.frHits or 0) + (resdat2.frHits or 0)
	resdat1.hoHits	= (resdat1.hoHits or 0) + (resdat2.hoHits or 0)
	resdat1.naHits	= (resdat1.naHits or 0) + (resdat2.naHits or 0)
	resdat1.shHits	= (resdat1.shHits or 0) + (resdat2.shHits or 0)
	mobData1.resists = resdat1
	if (mobData2.minDamage or 99999) < (mobData1.minDamage or 99999) then
		mobData1.minDamage = mobData2.minDamage
	end
	if (mobData2.maxDamage or 0) > (mobData1.maxDamage or 0) then
		mobData1.maxDamage = mobData2.maxDamage
	end
	if mobData2.itemList then
		if not mobData1.itemList then mobData1.itemList = {} end
		for itemID, amount in pairs(mobData2.itemList) do
			mobData1.itemList[itemID] = (mobData1.itemList[itemID] or 0) + mobData2.itemList[itemID]
		end
	end
	if mobData1.loots == 0 then mobData1.loots = nil end
	if mobData1.kills == 0 then mobData1.kills = nil end
	if mobData1.emptyLoots == 0 then mobData1.emptyLoots = nil end
	if mobData1.clothCount == 0 then mobData1.clothCount = nil end
	if mobData1.copper == 0 then mobData1.copper = nil end
	if mobData1.itemValue == 0 then mobData1.itemValue = nil end
	if mobData1.skinCount == 0 then mobData1.skinCount = nil end
	if mobData1.dps == 0 then mobData1.dps = nil end
	if mobData1.r1 == 0 then mobData1.r1 = nil end
	if mobData1.r2 == 0 then mobData1.r2 = nil end
	if mobData1.r3 == 0 then mobData1.r3 = nil end
	if mobData1.r4 == 0 then mobData1.r4 = nil end
	if mobData1.r5 == 0 then mobData1.r5 = nil end
end

local function MI2_GetMobHealthStr( index, healthPercent )
	local ppp = MobHealth_PPP( index )
	if ppp > 0 and healthPercent then
		return string.format("%d / %d", (healthPercent * ppp) + 0.5, (100 * ppp) + 0.5)
	end
end

function copper2text(copper)
	local g,s,c
	g = floor(copper / COPPER_PER_GOLD)
	s = floor(copper / COPPER_PER_SILVER) - g * SILVER_PER_GOLD
	c = copper - g * COPPER_PER_GOLD - s * COPPER_PER_SILVER
	if g > 0 then
		return mifontWhite..g..mifontYellow..'g '..mifontWhite..s ..mifontSubWhite..'s '..mifontWhite..c..mifontGold..'c'
	end  
	if s > 0 then
		return mifontWhite..s ..mifontSubWhite..'s '..mifontWhite..c..mifontGold..'c'
	end
	return mifontWhite..c..mifontGold..'c'
end

function lootName2Copper(item)
	local i = 0
	local g,s,c = 0
	local money = 0
	i = string.find(item, MI_TXT_GOLD )
	if i then
		g = tonumber( string.sub(item,0,i-1) )
		item = string.sub(item,i+5,string.len(item))
		money = money + ((g or 0) * COPPER_PER_GOLD)
	end
	i = string.find(item, MI_TXT_SILVER )
	if i then
		s = tonumber( string.sub(item,0,i-1) )
		item = string.sub(item,i+7,string.len(item))
		money = money + ((s or 0) * COPPER_PER_SILVER)
	end
	i = string.find(item, MI_TXT_COPPER )
	if i then
		c = tonumber( string.sub(item,0,i-1) )
		money = money + (c or 0)
	end
	return money
end

function MI2_FindItemValue( itemID )
	local price = 0
	if KC_Common and KC_Common.GetItemPrices then
		price = KC_Common:GetItemPrices(itemID) or 0
	elseif ISync and ISync.FetchDB then
		price = tonumber( ISync:FetchDB(itemID, "price") or 0 )
	end
	if price == 0 and ItemDataCache then
		price = (ItemDataCache.Get.ByID_selltovendor(itemID) or 0)
 	end
	if price == 0 and Auctioneer_GetVendorSellPrice then
		price = Auctioneer_GetVendorSellPrice(itemID) or 0
	end
	if price == 0 then
		price = MI2_BasePrices[itemID] or 0
	end
	return price
end

local function GetLootId( slot )
	local itemId = 0
	local link = GetLootSlotLink( slot )
	if link then
		local _, _, idCode = string.find(link, "|Hitem:(%d+):(%d+):(%d+):")
		itemId = tonumber( idCode or 0 )
	end
	return itemId
end

local function MI2_RecordLootSlotData( mobIndex, mobData, slotID )
	local skinningLoot = false
	local texture, itemName, quantity, quality = GetLootSlotInfo( slotID )
	if string.find(itemName, MI_TXT_CLAM_MEAT) ~= nil then  return false,true  end
	local itemID = GetLootId( slotID )
	quality = quality + 1
	if LootSlotIsCoin(slotID) then
		local money = lootName2Copper(itemName)
		mobData.copper = (mobData.copper or 0) + money
		quality = -1
	end
	if MobInfoConfig.SaveItems == 1 and quality >= MobInfoConfig.ItemsQuality then
		if not mobData.itemList then mobData.itemList = {} end
		mobData.itemList[itemID] = (mobData.itemList[itemID] or 0) + quantity
		MI2_ItemNameTable[itemID] = itemName.."/"..quality
		MI2_AddItemToXRefTable( mobIndex, itemName, quantity )
	end
	if slotID == 1 and miSkinLoot[itemID] then  return true,false  end
	if LootSlotIsItem(slotID) then
		local itemValue = MI2_FindItemValue( itemID )
		mobData.itemValue = (mobData.itemValue or 0) + itemValue
		if itemValue < 1 and quality == 2 then quality = -1 end
	end
	if miClothLoot[itemID] then
		mobData.clothCount = (mobData.clothCount or 0) + miClothLoot[itemID]
	end
	if quality == 1 then 
		mobData.r1 = (mobData.r1 or 0) + 1
	elseif quality == 2 then
		mobData.r2 = (mobData.r2 or 0) + 1
	elseif quality == 3 then
		mobData.r3 = (mobData.r3 or 0) + 1
	elseif quality == 4 then
		mobData.r4 = (mobData.r4 or 0) + 1
	elseif quality == 5 then
		mobData.r5 = (mobData.r5 or 0) + 1
	end
	return false,false
end

function MI2_RecordAllLootItems( mobIndex, numItems )
	local skinningLoot = false
	local mobData = MI2_FetchMobData( mobIndex )
	for slotID = 1, numItems, 1 do
		local skin, clam = MI2_RecordLootSlotData( mobIndex, mobData, slotID )
		if clam then return end
		skinningLoot = skinningLoot or skin
	end
	if skinningLoot then
		mobData.skinCount = (mobData.skinCount or 0) + 1
	else
		mobData.loots = (mobData.loots or 0) + 1
		if numItems < 1 then
			mobData.emptyLoots = (mobData.emptyLoots or 0) + 1
		end
	end
	if MobInfoConfig.SaveBasicInfo == 1 then
		MI2_StoreBasicInfo( mobIndex, mobData )
	end
	if MobInfoConfig.SaveItems == 1 then
		MI2_StoreLootItems( mobIndex, mobData )
	end
end

function MI2_GetCorpseId( index )
	local corpseId
	local numItems = 0 
	local numSlots = GetNumLootItems()
	if index and numSlots > 0 then
		corpseId = index
		for slot = 1, numSlots do
			local texture, item = GetLootSlotInfo( slot )
			if item ~= "" then corpseId = corpseId..item end
		end
	end
	return corpseId
end

function MI2_StoreCorpseId( corpseId, isNewCorpse )
	if isNewCorpse then
		MI2_NewCorpseIdx = MI2_NewCorpseIdx + 1
		if MI2_NewCorpseIdx > 10 then
			MI2_NewCorpseIdx = 1
		end
		MI2_CurrentCorpseIndex = MI2_NewCorpseIdx
	end
	if MI2_CurrentCorpseIndex then
		MI2_RecentLoots[MI2_CurrentCorpseIndex] = corpseId
		if not corpseId then
			MI2_CurrentCorpseIndex = nil
		end
	end
end

function MI2_CheckForCorpseReopen( mobIndex )
	local isReopen = false
	local corpseId = MI2_GetCorpseId( mobIndex )
	for index, recentCorpseId in pairs(MI2_RecentLoots) do
		if recentCorpseId == corpseId then
			MI2_CurrentCorpseIndex = index
			isReopen = true
			break
		end
	end
	if corpseId and not isReopen then
		MI2_StoreCorpseId( corpseId, 1 )
	end
	return isReopen
end

function MI2_GetLootItemString( itemID )
	local itemString = MI2_ItemNameTable[itemID] or tostring(itemID)
	local color
	local s,e, quality = string.find( itemString, "/(%d+)" )
	quality = tonumber(quality)
	if s then itemString = string.sub( itemString, 1, s-1 ) end
	if quality then color = MI2_QualityColor[quality] end
	return itemString, (color or mifontLightRed), quality
end

local function MI2_AddOneItemToTooltip( mobData, itemID, amount, useFilter )
	local itemText, itemColor = MI2_GetLootItemString( itemID )
	if useFilter then
		if MobInfoConfig.ItemFilter ~= ""  then
			local itemNotOK = string.find( string.lower(itemText), string.lower(MobInfoConfig.ItemFilter) ) == nil
			if itemNotOK then return end
		end
	else
		itemColor = "* "..itemColor
	end
	local shortItemNames = true
	if shortItemNames and string.len(itemText) > 35 then
		itemText = string.sub(itemText,1,35).."..."
	end
	itemText = itemText..": "..amount
	local totalAmount = mobData.loots
	if miSkinLoot[itemID] then
		totalAmount = mobData.skinCount
	end
	if totalAmount and totalAmount > 0 then
		itemText = itemText.." ("..ceil(amount/totalAmount*100).."%)"  
	end
	GameTooltip:AddLine( itemColor..itemText )
end

local function MI2_AddItemsToTooltip( mobData )
	local normalList = {}
	local collapsedList = {}
	local skinList = {}
	local clothList = {}
	for itemID, amount in pairs(mobData.itemList) do
		if miSkinLoot[itemID] then
			skinList[itemID] = amount
		elseif miClothLoot[itemID] then
			clothList[itemID] = amount
		elseif MI2_ItemCollapseList[itemID] then
			if MI2_ItemCollapseList[itemID] == 0 then
				MI2_ItemCollapseList[itemID] = itemID
			end
			local collapsedID = MI2_ItemCollapseList[itemID]
			collapsedList[collapsedID] = (collapsedList[collapsedID] or 0) + amount
		else
			normalList[itemID] = amount
		end
	end
	if MobInfoConfig.ShowItems == 1 then
		for itemID, amount in pairs(normalList) do
			MI2_AddOneItemToTooltip( mobData, itemID, amount, true )
		end
		for itemID, amount in pairs(collapsedList) do
			MI2_AddOneItemToTooltip( mobData, itemID, amount, true )
		end
	end
	if MobInfoConfig.ShowClothSkin == 1 then
		for itemID, amount in pairs(skinList) do
			MI2_AddOneItemToTooltip( mobData, itemID, amount, false )
		end
		for itemID, amount in pairs(clothList) do
			MI2_AddOneItemToTooltip( mobData, itemID, amount, false )
		end
	end
end

local function MI2_AddLocationToTooltip( location, showFullLocation )
	local x = floor( (location.x1 + location.x2) / 2 )
	local y = floor( (location.y1 + location.y2) / 2 )
	local zone = MI2_ZoneTable[location.z]
	if zone then
		if showFullLocation then
			GameTooltip:AddLine( mifontGold..MI_TXT_LOCATION..mifontWhite..zone.." ("..x.."/"..y..")" )
		else
			GameTooltip:AddLine( mifontGold..MI_TXT_LOCATION..mifontWhite..zone )
		end
	end
end

local function MI2_AddResistToTooltip( resistData )
	local resiatances = ""
	local immunities = ""
	local shortcut, value
	for shortcut, value in pairs(resistData) do
		if string.len(shortcut) < 3 then
			local hits = tonumber(resistData[shortcut.."Hits"]) or 1
			if value < 0 then
				if hits < 1 then
					immunities = "  "..immunities..MI2_SpellSchools[shortcut]
				else
					immunities = "  "..immunities..MI2_SpellSchools[shortcut].."(partial)"
				end
			elseif value > 0 then
				resiatances = "  "..resiatances..MI2_SpellSchools[shortcut]..":"..ceil((value/hits)*100).."%"
			end
		end
	end
	if resiatances ~= "" then
		GameTooltip:AddLine( mifontGold..MI_TXT_RESIST..mifontWhite..resiatances )
	end
	if immunities ~= "" then
		GameTooltip:AddLine( mifontGold..MI_TXT_IMMUNE..mifontWhite..immunities )
	end
end

local function MI2_CreateNormalTooltip( mobData, mobIndex, showFullLocation )
	local copperAvg, itemValueAvg
	local addEmptyLine = 0
	if mobData.lowHpAction == 1 and MobInfoConfig.ShowLowHpAction == 1 then
		GameTooltip:AddLine( mifontLightRed..">>  "..MI2_CHATMSG_MONSTEREMOTE.."  <<" )
	end
	if mobData.class and MobInfoConfig.ShowClass == 1 then
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_CLASS, mifontWhite..mobData.class )
	end
	if mobData.healthCur and MobInfoConfig.ShowHealth == 1 then
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_HEALTH, mifontWhite..mobData.healthCur.." / "..mobData.healthMax )
		MI2_HealthLine = GameTooltip:NumLines()
	end
	if mobData.manaMax and mobData.manaMax > 0 and MobInfoConfig.ShowMana == 1 then
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_MANA, mifontWhite..mobData.manaCur.." / "..mobData.manaMax )
		MI2_ManaLine = GameTooltip:NumLines()
	end
	local mobGivesXp = not (mobData.color.r == 0.5  and  mobData.color.g == 0.5  and  mobData.color.b == 0.5)
	if mobGivesXp and mobData.xp then
		if MobInfoConfig.ShowXp == 1 then
			GameTooltip:AddDoubleLine( mifontGold..MI_TXT_XP, mifontWhite..mobData.xp )
		end 
		if MobInfoConfig.ShowNo2lev == 1 then
			GameTooltip:AddDoubleLine( mifontGold..MI_TXT_TO_LEVEL, mifontWhite..mobData.mob2Level )
		end 
	end
	if (mobData.minDamage or mobData.dps) and MobInfoConfig.ShowDamage == 1 then 
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_DAMAGE, mifontWhite..(mobData.minDamage or 0).."-"..(mobData.maxDamage or 0).."  ["..(mobData.dps or 0).."]" )
	end
	addEmptyLine = MobInfoConfig.ShowBlankLines
	if  MobInfoConfig.CombinedMode == 1  and  MobInfoConfig.ShowCombined == 1  then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddLine( mifontGray.."["..MI_TXT_COMBINED..mobData.combinedStr.."]" )
	end
	if mobData.kills and MobInfoConfig.ShowKills == 1 then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_KILLS, mifontWhite..mobData.kills )
	end
	if  mobData.loots  and  MobInfoConfig.ShowLoots == 1  then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_TIMES_LOOTED, mifontWhite..mobData.loots )
	end
	if  mobData.emptyLoots  and  MobInfoConfig.ShowEmpty == 1  then
		local emptyLootsStr = mifontWhite..mobData.emptyLoots
		if  mobData.loots  then
			emptyLootsStr = emptyLootsStr.." ("..ceil((mobData.emptyLoots/mobData.loots)*100).."%) "
		end
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_EMPTY_LOOTS, emptyLootsStr )
	end
	if mobData.clothCount and MobInfoConfig.ShowCloth == 1 then
		local clothStr = mifontWhite..mobData.clothCount
		if mobData.loots then
			clothStr = clothStr.." ("..ceil((mobData.clothCount/mobData.loots)*100).."%) "
		end
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_CLOTH_DROP, clothStr )
	end
	if mobData.copper and mobData.loots then
		copperAvg = ceil( mobData.copper / mobData.loots )
		if MobInfoConfig.ShowCoin == 1 then
			if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
			GameTooltip:AddDoubleLine(mifontGold..MI_TXT_COIN_DROP,mifontWhite..copper2text(copperAvg))
		end
	end
	if mobData.itemValue and mobData.loots then
		itemValueAvg = ceil( mobData.itemValue / mobData.loots )
		if MobInfoConfig.ShowIV == 1 then
			if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
			GameTooltip:AddDoubleLine(mifontGold..MI_TEXT_ITEM_VALUE,mifontWhite..copper2text(itemValueAvg))
		end
	end
	local totalValue = (copperAvg or 0) + (itemValueAvg or 0)
	if totalValue > 0 and MobInfoConfig.ShowTotal == 1 then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine(mifontGold..MI_TXT_MOB_VALUE,mifontWhite..copper2text(totalValue))
	end
	if mobData.qualityStr ~= "" and MobInfoConfig.ShowQuality == 1 then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		GameTooltip:AddDoubleLine(mifontGold..MI_TXT_QUALITY, mobData.qualityStr)
	end
	if mobData.resists and MobInfoConfig.ShowResists == 1 then
		MI2_AddResistToTooltip( mobData.resists )
	end
	if mobData.location and MobInfoConfig.ShowLocation == 1 then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		MI2_AddLocationToTooltip( mobData.location, showFullLocation )
	end
	addEmptyLine = MobInfoConfig.ShowBlankLines
	if mobData.itemList and (MobInfoConfig.ShowItems == 1 or MobInfoConfig.ShowClothSkin == 1) then
		if addEmptyLine == 1 then GameTooltip:AddLine("\n") addEmptyLine = 0 end
		MI2_AddItemsToTooltip( mobData )
	end
end

local function MI2_CreateDebugTooltip( mobIndex )
	GameTooltip:AddLine("--------------  D e b u g   I n f o  --------------")
	GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."mobIndex=",mobIndex)
	if MobInfoDB[mobIndex] then
		if MobInfoDB[mobIndex].bi then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."bi(basic info)",mifontWhite..MobInfoDB[mobIndex].bi) end
		if MobInfoDB[mobIndex].qi then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."qi(quality info)",mifontWhite..MobInfoDB[mobIndex].qi) end
		if MobInfoDB[mobIndex].ml then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."ml(mob location)",mifontWhite..MobInfoDB[mobIndex].ml) end
		if MobInfoDB[mobIndex].il then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."il(item list)",mifontWhite..MobInfoDB[mobIndex].il) end
		if MobInfoDB[mobIndex].re then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."re(resists)",mifontWhite..MobInfoDB[mobIndex].re) end
		if MI2_PlayerName and MobInfoDB[mobIndex][MI2_PlayerName] then GameTooltip:AddDoubleLine("[DBG] "..mifontGold..MI2_PlayerName.."(char data)",mifontWhite..MobInfoDB[mobIndex][MI2_PlayerName]) end
	end
	if MobHealthDB[mobIndex] then GameTooltip:AddDoubleLine("[DBG] "..mifontGold.."hp(health data)=",mifontWhite..MobHealthDB[mobIndex]) end
end

local function MI2_CreateCompactTooltip( mobData, mobIndex, showFullLocation )
	local firstLine = GameTooltip:NumLines() + 1
	if mobData.lowHpAction == 1 and MobInfoConfig.ShowLowHpAction == 1 then
		GameTooltip:AddLine( mifontLightRed..">>  "..MI2_CHATMSG_MONSTEREMOTE.."  <<" )
	end
	if mobData.class and MobInfoConfig.ShowClass == 1 then
		GameTooltip:AddDoubleLine( mifontGold..MI_TXT_CLASS, mifontWhite..mobData.class )
	end
	if (mobData.healthCur or mobData.manaMax and mobData.manaMax > 0)  
			and (MobInfoConfig.ShowHealth == 1 or MobInfoConfig.ShowMana == 1) then
		GameTooltip:AddDoubleLine( mifontGold.."HP    "..mifontWhite..(mobData.healthCur or 0).." / "..(mobData.healthMax or 0), mifontWhite..(mobData.manaCur or 0).." / "..(mobData.manaMax or 0)..mifontGold.." Mana" )
		MI2_HealthLine = GameTooltip:NumLines()
		if mobData.manaMax and mobData.manaMax > 0 then
			MI2_ManaLine = MI2_HealthLine
		end
	end
	local mobGivesXp = not (mobData.color.r == 0.5  and  mobData.color.g == 0.5  and  mobData.color.b == 0.5)
	if mobGivesXp and mobData.xp and (MobInfoConfig.ShowXp == 1 or MobInfoConfig.ShowNo2lev == 1) then
		GameTooltip:AddDoubleLine( mifontGold.."XP    "..mifontWhite..mobData.xp, mifontWhite..mobData.mob2Level..mifontGold.." KtL    " )
	end
	if (mobData.minDamage or mobData.dps) and MobInfoConfig.ShowDamage == 1 then
		GameTooltip:AddDoubleLine( mifontGold.."Dmg "..mifontWhite..(mobData.minDamage or 0).."-"..(mobData.maxDamage or 0), mifontWhite..(mobData.dps or 0)..mifontGold.." Dps   " )
	end
	if  MobInfoConfig.CombinedMode == 1  and  MobInfoConfig.ShowCombined == 1  then
		GameTooltip:AddLine( mifontGray.."["..MI_TXT_COMBINED..mobData.combinedStr.."]" )
	end
	if (mobData.kills or mobData.loots) and (MobInfoConfig.ShowKills == 1 or MobInfoConfig.ShowLoots == 1)  then
		GameTooltip:AddDoubleLine( mifontGold.."Kills  "..mifontWhite..(mobData.kills or 0), mifontWhite..(mobData.loots or 0)..mifontGold.." Loots" )
	end
	if  (mobData.emptyLoots or mobData.clothCount) and (MobInfoConfig.ShowCloth == 1 or MobInfoConfig.ShowEmpty == 1)  then
		local emptyLootsStr = mifontWhite..(mobData.emptyLoots or 0)
		if  mobData.loots  then
			emptyLootsStr = emptyLootsStr.." ("..ceil(((mobData.emptyLoots or 0)/mobData.loots)*100).."%) "
		end
		local clothStr = mifontWhite..(mobData.clothCount or 0)
		if mobData.loots then
			clothStr = clothStr.." ("..ceil(((mobData.clothCount or 0)/mobData.loots)*100).."%) "
		end
		GameTooltip:AddDoubleLine( mifontGold.."CL     "..mifontWhite..clothStr, mifontWhite..emptyLootsStr..mifontGold.." EL      " )
	end
	if (mobData.copper or mobData.itemValue) and mobData.loots and MobInfoConfig.ShowTotal == 1 then
		local copperAvg = ceil( (mobData.copper or 0) / mobData.loots )
		local itemValueAvg = ceil( (mobData.itemValue or 0) / mobData.loots )
		local totalValue = copperAvg + itemValueAvg
		if totalValue > 0 then
			GameTooltip:AddDoubleLine( mifontGold.."Val    "..mifontWhite..copper2text(totalValue), mifontWhite..copper2text(copperAvg)..mifontGold.." Coins" )
		end
	end
	if  mobData.qualityStr ~= ""  and  MobInfoConfig.ShowQuality == 1  then
		GameTooltip:AddLine( mifontGold.."Q      "..mifontWhite..mobData.qualityStr )
	end
	if mobData.resists and MobInfoConfig.ShowResists == 1 then
		MI2_AddResistToTooltip( mobData.resists )
	end
	if mobData.location and MobInfoConfig.ShowLocation == 1 then
		MI2_AddLocationToTooltip( mobData.location, showFullLocation )
	end
	if mobData.itemList and (MobInfoConfig.ShowItems == 1 or MobInfoConfig.ShowClothSkin == 1) then
		MI2_AddItemsToTooltip( mobData )
	end
end

local function MI2_BuildQualityString( mobData )
	local quality, chance
	local rt = mobData.loots or 1
	mobData.qualityStr = ""
	for idx = 1, 5 do
		quality = mobData["r"..idx]
		if quality then
			chance = ceil( quality / rt * 100.0 )
			if chance > 100 then chance = 100 end
			mobData.qualityStr = mobData.qualityStr..MI2_QualityColor[idx]..quality.."("..chance.."%) "
		end
	end
end

function MI2_BuildMobInfoTooltip( mobName, mobLevel, showFullLocation )
	if  UnitIsPlayer("mouseover")  then  return  end
	local mobIndex = mobName..":"..mobLevel
	if not showFullLocation then
		MI2_RecordLocationAndType( mobIndex )
	end
	MI2_MouseoverIndex = mobIndex
	local mobData = MI2_FetchMobData( MI2_MouseoverIndex )
	mobData.combinedStr = ""
	if  MobInfoConfig.CombinedMode == 1 and mobLevel > 0 then
		local combined = { combinedStr = "" }
		MI2_AddTwoMobs( combined, mobData )
		for levelToCombine = mobLevel-4, mobLevel+4, 1 do
			if levelToCombine ~= mobLevel  then
				local mobIndex = mobName..":"..levelToCombine
				if MobInfoDB[mobIndex] then
					local dataToCombine = MI2_FetchMobData( mobIndex )
					MI2_AddTwoMobs( combined, dataToCombine )
					combined.combinedStr = combined.combinedStr.." L"..levelToCombine
					combined.color = GetDifficultyColor( levelToCombine )
				end
			else
				combined.combinedStr = combined.combinedStr.." L"..levelToCombine
			end
		end
		mobData = combined
	end
	MI2_GetUnitBasedMobData( MI2_MouseoverIndex, mobData, "mouseover", mobLevel )
	if not mobData.color then mobData.color = {r=1.0;b=1.0;c=1.0} end
	if mobData.xp then
		local xpCurrent = UnitXP("player") + mobData.xp
		local xpToLevel = UnitXPMax("player") - xpCurrent
		mobData.mob2Level = ceil(abs(xpToLevel / mobData.xp))+1
	end
	MI2_BuildQualityString( mobData )
	if IsAltKeyDown() and IsControlKeyDown() then
		MI2_CreateDebugTooltip( MI2_MouseoverIndex )
	elseif MobInfoConfig.CompactMode == 1 then
		MI2_CreateCompactTooltip( mobData, MI2_MouseoverIndex, showFullLocation )
	else
		MI2_CreateNormalTooltip( mobData, MI2_MouseoverIndex, showFullLocation )
	end
end

local function MI2_AddItemPriceToTooltip()
	local frame = GetMouseFocus()
	if not frame then return end
	local frameName = frame:GetName()
	if not frameName then return end
	local parent = frame:GetParent()
	if not parent then return end
	local _,_,parenName, num = string.find( frameName, "(.+)Item(%d+)" )
	if not parenName or not num then return end
	local bagId
	local bagSlot = frame:GetID()
	if parent == BankFrame then
		bagId = BANK_CONTAINER
	else
		bagId = parent:GetID()
	end
	local price = 0
	local priceFound = false
	local link = GetContainerItemLink( bagId, bagSlot )
	local _, amount = GetContainerItemInfo( bagId, bagSlot )
	local _, _, itemID = string.find((link or ""), "|Hitem:(%d+):(%d+):(%d+):")
	if itemID and amount then
		price = MI2_FindItemValue( tonumber(itemID) ) * amount
		if price > 0 then
			GameTooltip:AddDoubleLine( mifontLightBlue..MI_TXT_PRICE..mifontWhite..amount, mifontWhite..copper2text(price) )
			priceFound = true
		end
	end
	if MI2_DebugItems > 0 then
		GameTooltip:AddLine( mifontSubWhite.."[frame="..frame:GetName()..",id="..frame:GetID().."]" )
		GameTooltip:AddLine( mifontSubWhite.."[parent="..parent:GetName()..",id="..parent:GetID().."]" )
		GameTooltip:AddLine( mifontSubWhite.."[bagId="..bagId..",bagSlot="..bagSlot.."]" )
		GameTooltip:AddLine( mifontSubWhite.."link="..link )
		GameTooltip:AddLine( mifontSubWhite.."[itemID="..itemID..",price="..price..",amount="..amount.."]" )
	end
	return priceFound
end

function MI2_BuildItemDataTooltip( itemName )
	local priceFound
	if MobInfoConfig.ShowItemPrice == 1 then
		priceFound = MI2_AddItemPriceToTooltip()
	end
	if MobInfoConfig.ItemTooltip ~= 1 then return end
	local itemFound = MI2_XRefItemTable[itemName]
	if not itemFound then return priceFound end
	local numMobs = 0
	local resultList = {}
	local sortList = {}
	local mobIndex, itemAmount
	for mobIndex, itemAmount in pairs(itemFound) do
		local mobData = {}
		MI2_DecodeBasicMobData( nil, mobData, mobIndex )
		local mobName, mobLevel = MI2_GetIndexComponents( mobIndex )
		local itemData = resultList[mobName]
		if not itemData then
			numMobs = numMobs + 1
			itemData = { name = mobName, loots = 0, count = 0 }
			resultList[mobName] = itemData
			sortList[numMobs] = itemData
		end
		itemData.loots = itemData.loots + (mobData.loots or 0)
		itemData.count = itemData.count + itemAmount
		if itemData.loots > 0 then
			itemData.chance = floor(100.0 * itemData.count / itemData.loots + 0.5)
			if itemData.chance > 100 then itemData.chance = 100 end
			if itemData.loots < 6 then
				itemData.rating = itemData.chance + itemData.loots * 1000
			else
				itemData.rating = itemData.chance + 6000
			end
		else
			itemData.chance = itemData.count
			itemData.rating = itemData.chance
		end
	end
	table.sort( sortList, function(a,b) return (a.rating > b.rating) end  )
	GameTooltip:AddLine( mifontLightBlue..MI_TXT_DROPPED_BY..numMobs.." Mobs:" )
	if numMobs > 8 then numMobs = 8 end
	for idx = 1, numMobs do
		local data = sortList[idx]
		if data.loots > 0 then
			GameTooltip:AddDoubleLine( mifontLightBlue.."  "..data.name, mifontWhite..data.chance.."% ("..data.count.."/"..data.loots..")" )
		else
			GameTooltip:AddDoubleLine( mifontLightBlue.."  "..data.name, mifontWhite..data.chance )
		end
	end
	return true
end

function MI2_ScanSpellbook()
	local spellBookPage = 2
	while spellBookPage > 0 do
		local pageName, texture, offset, numSpells = GetSpellTabInfo( spellBookPage )
		if pageName and offset and numSpells then
			for spellIndex = (offset+1), (offset + numSpells) do
				local spellName = GetSpellName( spellIndex, BOOKTYPE_SPELL )
				if spellName and (not string.find(spellName,":")) then
					for school in pairs(MI2_SpellSchools) do
						local schoolOK = string.find( pageName, school )
						if schoolOK and string.len(school) > 2 then
							MI2_SpellToSchool[spellName] = school
						end
					end
				end
			end
			spellBookPage = spellBookPage + 1
		else
			spellBookPage = 0
		end
	end
end

function MI2_RecordHit( damage, spell, school, isPeriodic )
	if not MI2_Target.FightStartTime then
		MI2_Target.FightStartTime = GetTime() - 1.0
		MI2_Target.FightEndTime = GetTime()
		MI2_Target.FightDamage = damage
	elseif MI2_Target.FightEndTime then
		MI2_Target.FightEndTime = GetTime()
		MI2_Target.FightDamage = MI2_Target.FightDamage + damage
	end
	if spell and school and MI2_SpellSchools[school] then
		MI2_SpellToSchool[spell] = school
	elseif spell then
		school = MI2_SpellToSchool[spell]
	end
	local acronym = MI2_SpellSchools[school]
	if school and acronym and not isPeriodic then
		local mobData = MI2_FetchMobData( MI2_Target.mobIndex )
		mobData.resists[acronym.."Hits"] = (mobData.resists[acronym.."Hits"] or 0)+ 1
	end
end

function MI2_RecordImmunResist( mobName, spell, isResist )
	if mobName == MI2_Target.name and MI2_Target.ResOk then
		local mobIndex = MI2_Target.mobIndex
		local mobData = MI2_FetchMobData( mobIndex )
		local school = MI2_SpellToSchool[spell]
		if school then
			local acronym = MI2_SpellSchools[school]
			if isResist then
				mobData.resists[acronym] = (mobData.resists[acronym] or 0) + 1
			else
				mobData.resists[acronym] = -1
			end
		end
	end
end

function MI2_GetChildren( list, frame )
	local children = { frame:GetChildren() }
	for idx, subFrame in pairs(children) do
		if subFrame:GetNumChildren() > 0 then
			MI2_GetChildren( list, subFrame )
		else
			tinsert( list, subFrame )
		end
	end
end

function MI2_UpdateMobInfoState()
	local children = { MI2_FrmTooltipOptions:GetChildren() }
	local controls = {}
	MI2_GetChildren( controls, MI2_FrmTooltipOptions )
	for idx, frame in pairs(controls) do
		if MobInfoConfig.DisableMobInfo == 0 then
			if frame.Enable then
				frame:Enable()
				getglobal(frame:GetName().."Text"):SetTextColor( 1.0, 0.8, 0.0 )
			else
				frame:Show()
			end
		else
			if frame.Disable then
				frame:Disable()
				getglobal(frame:GetName().."Text"):SetTextColor( 0.5, 0.5, 0.5 )
			else
				frame:Hide()
			end
		end
	end
	MI2_OptDisableMobInfo:Enable()
	MI2_OptDisableMobInfo:SetScale( 1.2 )
	MI2_OptDisableMobInfoText:SetTextColor( 1.0, 1.0, 1.0 )
end

function MI2_UpdateTooltipHealthMana( healthCur, healthMax )
	local tooltip = "GameTooltip"
	if TipBuddyTooltip then tooltip = "TipBuddyTooltip" end
	if MI2_HealthLine and healthCur then
		local healthText = healthCur.." / "..healthMax
		if MobInfoConfig.CompactMode == 1 then
			local healthLine = getglobal(tooltip.."TextLeft"..MI2_HealthLine)
			healthLine:SetText( mifontGold.."HP    "..mifontWhite..healthText )
		else
			local healthLine = getglobal(tooltip.."TextRight"..MI2_HealthLine)
			healthLine:SetText( mifontWhite..healthText )
		end
	end
	if MI2_ManaLine then
		local manaText = mifontWhite..UnitMana("mouseover").." / "..UnitManaMax("mouseover")
		local manaLine = getglobal(tooltip.."TextRight"..MI2_ManaLine)
		if MobInfoConfig.CompactMode == 1 then
			manaLine:SetText( manaText..mifontGold.." Mana" )
		else
			manaLine:SetText( manaText )
		end
	end
end