MI2_SearchOptions = {}
MI2_SearchOptions.MinLevel = 1
MI2_SearchOptions.MaxLevel = 85
MI2_SearchOptions.Normal = 1
MI2_SearchOptions.Elite = 0
MI2_SearchOptions.Boss = 0
MI2_SearchOptions.MinLoots = 0
MI2_SearchOptions.MobName = ""
MI2_SearchOptions.ItemName = ""
MI2_SearchOptions.CompactResult = 1
MI2_SearchOptions.ListMode = "Mobs"
MI2_SearchOptions.SortMode = "profit"

local MI2_SearchResultList = {}
local MI2_ItemsIdxList = ":"
MI2_NumMobsFound = 0

local function MI2_SearchForItems( itemName, enterItemsIntoList )
	MI2_ItemsIdxList = ":"
	MI2_NumMobsFound = 0
	if enterItemsIntoList then
		MI2_SearchResultList = {}
	end
	if itemName ~= "" or enterItemsIntoList then
		for idx in pairs(MI2_ItemNameTable) do
			local itemFound = true
			local itemText, itemColor = MI2_GetLootItemString( idx )
			if itemName ~= "*" then
				itemFound = string.find( string.lower(itemText), string.lower(itemName) ) ~= nil
			end
			if itemFound then
				MI2_ItemsIdxList = MI2_ItemsIdxList..idx..":"
				if enterItemsIntoList then
					MI2_NumMobsFound = MI2_NumMobsFound + 1
					MI2_SearchResultList[MI2_NumMobsFound] = { idx = itemText, val = "", col = itemColor }
				end
			end
		end
	end
	MI2_DisplaySearchResult( "Items" )
end

local function MI2_UpdateSearchResultList( updateItems )
	if updateItems then
		local enterItemsIntoList = MI2_SearchOptions.ListMode == "Items"
		MI2_SearchForItems( MI2_SearchOptions.ItemName, enterItemsIntoList )
	end
	if MI2_SearchOptions.ListMode == "Mobs" then
		MI2_SearchAndSort( "profit" )
	end
	MI2_DisplaySearchResult( MI2_SearchOptions.ListMode )
end

function MI2_SearchOptionsOnShow()
	MI2_OptSearchMinLevel:SetText( tostring(MI2_SearchOptions.MinLevel) )
	MI2_OptSearchMaxLevel:SetText( tostring(MI2_SearchOptions.MaxLevel) )
	MI2_OptSearchMinLoots:SetText( tostring(MI2_SearchOptions.MinLoots) )
	MI2_OptSearchMobName:SetText( MI2_SearchOptions.MobName )
	MI2_OptSearchItemName:SetText( MI2_SearchOptions.ItemName )
	MI2_OptSearchNormal:SetChecked( MI2_SearchOptions.Normal )
	MI2_OptSearchElite:SetChecked( MI2_SearchOptions.Elite )
	MI2_OptSearchBoss:SetChecked( MI2_SearchOptions.Boss )
	MI2_UpdateSearchResultList()
end

local function MI2_ValidateSearchOptions()
	if MI2_SearchOptions.MinLevel < 1 then
		MI2_SearchOptions.MinLevel = 1
		if this:GetText() == "0" then
			this:SetText( "1" )
		end
	end
	if MI2_SearchOptions.MaxLevel < 1 then
		MI2_SearchOptions.MaxLevel = 1
		if this:GetText() == "0" then
			this:SetText( "1" )
		end
	end
end

function MI2_SearchCheckboxClicked()
	local checkboxName = this:GetName()
	local optionName = string.sub( checkboxName, 14 )
	local optionValue = this:GetChecked() or 0
	MI2_SearchOptions[optionName] = optionValue
	MI2_UpdateSearchResultList()
end

function MI2_SearchValueChanged()
	local editboxName = this:GetName()
	local optionName = string.sub( editboxName, 14 )
	local optionValue = tonumber(this:GetText()) or 0
	if MI2_SearchOptions[optionName] ~= optionValue then
		MI2_SearchOptions[optionName] = optionValue
		MI2_ValidateSearchOptions()
		MI2_UpdateSearchResultList()
	end
end

function MI2_SearchTextChanged()
	local editboxName = this:GetName()
	local optionName = string.sub( editboxName, 14 )
	if MI2_SearchOptions[optionName] ~= this:GetText() then
		MI2_SearchOptions[optionName] = this:GetText()
		MI2_UpdateSearchResultList( true )
	end
end

local function MI2_CalculateRank( mobData, mobLevel, sortMode )
	local rank, value = 0, 0
	if sortMode == "profit" then
		local bonusFactor = mobLevel / 20
		if mobData.loots > 0 then
			value = (mobData.copper or 0) + (mobData.itemValue or 0)
			rank = value + ((mobData.r3 or 0) * 200 * bonusFactor) + ((mobData.r4 or 0) * 1000 * bonusFactor) + ((mobData.r5 or 0) * 2000 * bonusFactor)
			rank = ceil( rank / mobData.loots )
			value = copper2text( ceil(value / mobData.loots) )
		end
	elseif sortMode == "item" and mobData.itemList then
		for idx, val in pairs(mobData.itemList) do
			local itemFound = string.find( MI2_ItemsIdxList, idx ) ~= nil
			if itemFound then  rank = rank + val  end
		end
		value = rank.."  "
	end
	return rank, value
end

local function MI2_CheckMob( mobInfo, mobName, mobLevel )
	local levelOk, lootsOk, typeOk, itemsOK, mobData
	local nameOk = true
	if MI2_SearchOptions.MobName ~= "" then
		nameOk = string.find(string.lower(mobName),string.lower(MI2_SearchOptions.MobName),1,true) ~= nil
	end
	if nameOk and mobName ~= "" then
		levelOk = mobLevel >= MI2_SearchOptions.MinLevel and mobLevel <= MI2_SearchOptions.MaxLevel
		levelOk = levelOk or (mobLevel == -1)
	end
	if levelOk then
		mobData = {}
		MI2_DecodeBasicMobData( mobInfo, mobData )
		mobData.loots = mobData.loots or 0
		lootsOk = mobData.loots >= MI2_SearchOptions.MinLoots
		typeOk = (MI2_SearchOptions.Normal == 1 and mobData.mobType == 1) or (MI2_SearchOptions.Elite == 1 and mobData.mobType == 2) or (MI2_SearchOptions.Boss == 1 and mobData.mobType == 3)
		if lootsOk and typeOk then
			if MI2_ItemsIdxList ~= ":" then
				MI2_DecodeItemList( mobInfo, mobData )
				if mobData.itemList then
					for idx, val in pairs(mobData.itemList) do
						itemsOK = string.find( MI2_ItemsIdxList, ":"..idx..":" ) ~= nil
						if itemsOK then break end
					end
				end
				if not itemsOK then mobData = nil end
			end
		else
			mobData = nil
		end
	end
	return mobData
end

function MI2_SearchAndSort( )
	local mobName, mobLevel, insertPos, value, rank, mobIndex, mobInfo
	MI2_SearchResultList = {}
	MI2_NumMobsFound = 0
	for mobIndex, mobInfo in pairs(MobInfoDB) do
		mobName, mobLevel = MI2_GetIndexComponents( mobIndex )
		mobData = MI2_CheckMob( mobInfo, mobName, mobLevel )
		if mobData then
			rank, value = MI2_CalculateRank( mobData, mobLevel, MI2_SearchOptions.SortMode )
			MI2_NumMobsFound = MI2_NumMobsFound + 1
			MI2_SearchResultList[MI2_NumMobsFound] = { idx=mobIndex, val=value, rank=rank }
			if mobData.mobType and mobData.mobType > 1 then
				MI2_SearchResultList[MI2_NumMobsFound].type = mobData.mobType
			end
		end
	end
	if MI2_NumMobsFound > 1 then
		table.sort( MI2_SearchResultList, function(a,b) return (a.rank > b.rank) end  )
	end
end

function MI2_DisplaySearchResult( resultType )
	FauxScrollFrame_Update( MI2_SearchResultSlider, MI2_NumMobsFound, 15, 14 );
	local sliderPos = FauxScrollFrame_GetOffset(MI2_SearchResultSlider)
	if resultType then
		MI2_TxtSearchCount:SetText( mifontSubWhite.."("..MI2_NumMobsFound.." "..resultType..")" )
	end
	local resultLine
	for i = 1, 15 do
		if 	(i + sliderPos) <= MI2_NumMobsFound then
			resultLine = getglobal( "MI2_SearchResult"..i.."Index" )
			resultLine:SetText( i + sliderPos )
			resultLine = getglobal( "MI2_SearchResult"..i.."Value" )
			resultLine:SetText( MI2_SearchResultList[i + sliderPos].val )
			resultLine = getglobal( "MI2_SearchResult"..i.."Name" )
			local mobName = MI2_SearchResultList[i + sliderPos].idx
			if MI2_SearchResultList[i + sliderPos].type then
				mobName = mobName.."+"
			elseif MI2_SearchResultList[i + sliderPos].col then
				mobName = MI2_SearchResultList[i + sliderPos].col..mobName
			end
			resultLine:SetText( mobName )
		else
			resultLine = getglobal( "MI2_SearchResult"..i.."Index" )
			resultLine:SetText( "" )
			resultLine = getglobal( "MI2_SearchResult"..i.."Value" )
			resultLine:SetText( "" )
			resultLine = getglobal( "MI2_SearchResult"..i.."Name" )
			resultLine:SetText( "" )
		end
	end
end

function MI2_SlashAction_SortByValue()
	MI2_SearchOptions.SortMode = "profit"
	MI2_UpdateSearchResultList()
end

function MI2_SlashAction_SortByItem()
	MI2_SearchOptions.SortMode = "item"
	MI2_UpdateSearchResultList()
end

function MI2_SearchResult_Update()
	FauxScrollFrame_Update( MI2_SearchResultSlider, MI2_NumMobsFound, 15, 14 );
	MI2_DisplaySearchResult()
end

function MI2_ShowSearchResultTooltip()
	local sliderPos = FauxScrollFrame_GetOffset(MI2_SearchResultSlider)
	local selection = tonumber(string.sub(this:GetName(), 17)) + sliderPos
	if selection <= MI2_NumMobsFound then
		GameTooltip_SetDefaultAnchor( GameTooltip, UIParent )
		if MI2_SearchOptions.ListMode == "Mobs" then
			local index = MI2_SearchResultList[selection].idx
			local mobName, mobLevel = MI2_GetIndexComponents( index )
			local mobCaption = mobName.."  L"..mobLevel
			if MI2_SearchResultList[selection].type then
				mobCaption = mobCaption.."+"
			end
			GameTooltip:SetText( mobCaption )
			MI2_BuildMobInfoTooltip( mobName, mobLevel, 1 )
		elseif MI2_SearchOptions.ListMode == "Items" then
			local itemName = MI2_SearchResultList[selection].idx
			GameTooltip:SetText( MI2_SearchResultList[selection].col..itemName )
			MI2_BuildItemDataTooltip( itemName )
		end
		GameTooltip:Show()
	end
end

function MI2_SearchTab_OnClick()
	PanelTemplates_Tab_OnClick( MI2_SearchResultFrame )
	local selected = MI2_SearchResultFrame.selectedTab
	if selected == 1 then
		MI2_OptSortByValue:Enable()
		MI2_OptSortByItem:Enable()
		if MI2_NumMobsFound > 0 then
			MI2_OptDeleteSearch:Enable()
		else
			MI2_OptDeleteSearch:Disable()
		end
		MI2_SearchOptions.ListMode = "Mobs"
		MI2_UpdateSearchResultList( true )
	elseif selected == 2 then
		MI2_OptSortByValue:Disable()
		MI2_OptSortByItem:Disable()
		MI2_OptDeleteSearch:Disable()
		MI2_SearchOptions.ListMode = "Items"
		MI2_UpdateSearchResultList( true )
	end
end

function MI2_DeleteSearchResultMobs()
	for idx, val in pairs(MI2_SearchResultList) do
		local mobIndex = val.idx
		MI2_DeleteMobData( mobIndex, true )
	end
	chattext( "search result deleted : "..MI2_NumMobsFound.." Mobs" )
	MI2_UpdateSearchResultList()
end