--[[ ---------------------------------------------------------------------------
Created:		7/30/2010 6:17:41 PM
Last Modified:	2011-04-29T08:44:39Z
Author:			orgevo
Version:		v1.3a

SlotSearchModule:	Search module for matching based on the equipment slot an item is used in.

AtlasLootAdvancedSearch is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

AtlasLootAdvancedSearch is distributed WITHOUT ANY WARRANTY; without even the 
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with AtlasLootAdvancedSearch.	If not, see <http://www.gnu.org/licenses/>.

----------------------------------------------------------------------------- ]]



local ADDON_TAG					= "AtlasLootAdvancedSearch"
local AtlasLootAdvancedSearch	= LibStub("AceAddon-3.0"):GetAddon(ADDON_TAG);
local alas_addon				= AtlasLootAdvancedSearch;
local al_addon					= AtlasLoot;
local SLOTSEARCH_DEBUG			= false;
local ENABLE_LOGGING			= alas_addon.ENABLE_LOGGING and SLOTSEARCH_DEBUG

-- localization
local L						= LibStub("AceLocale-3.0"):GetLocale(ADDON_TAG, true)
local AL					= LibStub("AceLocale-3.0"):GetLocale("AtlasLoot");
local BabbleInventory		= AtlasLoot_GetLocaleLibBabble("LibBabble-Inventory-3.0")
local ADDON_NAME			= L["ADDON_NAME"]

local GREY = al_addon.GREY;
local RED = al_addon.RED;
local WHITE = al_addon.WHITE;
local GREEN = al_addon.GREEN;
local PURPLE = al_addon.PURPLE;
local BLUE = al_addon.BLUE;
local ORANGE = al_addon.ORANGE;

local tinsert, tconcat = table.insert, table.concat
local strlen, strmatch, strfind, strsub, strformat, strlower, strupper = string.len, string.match, string.find, string.sub, string.format, string.lower, string.upper
local pairs, next, type = pairs, next, type
local tostring = tostring
local AtlasLootAdvancedSearch_GetLootItemMetadata = AtlasLootAdvancedSearch_GetLootItemMetadata

-- print wrappers
-- t_print (testing): what I use while developing....most of these will be commented out in the repository versions
-- dev_print (development): outputs only when AtlasLootAdvancedSearch.dev_mode is true
local function r_print(str) alas_addon:Print(str); end
local function r_printf(str,...) alas_addon:Print(strformat(str,...)); end

local dbgProxy = alas_addon.DebugProxy;
local function isDevMode()			return dbgProxy and dbgProxy:isDevMode() end
local function isInternal()			return dbgProxy and dbgProxy:isInternal() end
local function t_print(str)			if dbgProxy and ENABLE_LOGGING then dbgProxy:t_print(str) end end
local function t_printf(str,...)	if dbgProxy and ENABLE_LOGGING then dbgProxy:t_printf(str, ...) end end
local function dev_print(str)		if dbgProxy and ENABLE_LOGGING then dbgProxy:dev_print(str) end end
local function dev_printf(str, ...)	if dbgProxy and ENABLE_LOGGING then dbgProxy:dev_printf(str,...) end end
local function d_print(str)			if dbgProxy and ENABLE_LOGGING then dbgProxy:d_print(str) end end
local function d_printf(str,...)	if dbgProxy and ENABLE_LOGGING then dbgProxy:d_printf(str,...) end end
local function funcEnter(obj, funcName, formatStr, ...)
	if alas_addon.DebugProxy.isEnabled and ENABLE_LOGGING then
		if formatStr then alas_addon.DebugProxy:TraceEnter(obj,funcName,strformat(formatStr,...));
		else alas_addon.DebugProxy:TraceEnter(obj,funcName); end
	end
end
local function funcExit(obj, funcName, formatStr, ...)
	if alas_addon.DebugProxy.isEnabled and ENABLE_LOGGING then
		if formatStr then alas_addon.DebugProxy:TraceExit(obj,funcName,strformat(formatStr,...));
		else alas_addon.DebugProxy:TraceExit(obj,funcName); end
	end
end

local function t_printSlow(str)			if alas_addon.ALLOW_SLOW_LOGS then t_print(str)		end end
local function t_printfSlow(str,...)	if alas_addon.ALLOW_SLOW_LOGS then t_printf(str,...)	end end




function AtlasLootAdvancedSearch:Search_ItemSlotNames(lootTableID, item_data, completingCombinationSearch)
	local isMatch, itemID, displayText, description = false, item_data[2];
	local isPartialMatch, remainingMatch = false, nil;
	
--	{ 2,"EMBLEMOFFROSTMENU", "inv_misc_frostemblem_01", "=ds="..AL["Emblem of Frost Rewards"], "=q5="..AL["Wrath of the Lich King"]};
--	  1                   2                          3                                      4                                    5         6
--[===[@debug@	
--funcEnter(alas_addon,"["..tostring(lootTableID).."] Search_ItemSlotNames","[2]:%s,  [4]:%s,  [5]:%s",tostring(item_data[2]),tostring(item_data[4]),tostring(item_data[5]));
--@end-debug@]===]
	local encoded_metadata, extraData = AtlasLootAdvancedSearch_GetLootItemMetadata(item_data);
	if encoded_metadata == nil then
		return false;
	end
	local itemSlotCode = strmatch(encoded_metadata, "#s%d+#");
	if not itemSlotCode then
		itemSlotCode = strmatch(encoded_metadata, "#h[1-4]#");
	end
	if itemSlotCode then
		local slotName = al_addon:FixText(itemSlotCode);
		if slotName then
			local parser = searchParms.SearchParser;
			if parser then
			--t_printf("Searching for itemslot %s....", slotName);
				isMatch, isPartialMatch, remainingMatch = parser:IsMatch(slotName,completingCombinationSearch ~= true,searchParms.pendingMatches);
				if isMatch or isPartialMatch then
					local itemName, formattedItemName;
					itemName, formattedItemName, description = AtlasLootAdvancedSearch_GetFormattedName(item_data);
					displayText = formattedItemName;
				end
			end
		end
	end
		
--[===[@debug@	
--funcExit(alas_addon,"["..tostring(lootTableID).."] Search_ItemSlotNames","itemID:%s  displayText:%s   description:%s   isMatch:%s   isPartialMatchOnly:%s",
--	tostring(item_data[2]), tostring(displayText), tostring(description), tostring(isMatch), tostring(remainingMatch ~= nil and #remainingMatch > 0));
--@end-debug@]===]
	return isMatch, item_data[2], displayText, description, remainingMatch;
end



do
	if not _G["AL_SEARCHMODULES"] then _G["AL_SEARCHMODULES"] = {} end
	if not _G["AL_SEARCHMODULES"]["ALSEARCH_ITEMSLOT"] then
		_G["AL_SEARCHMODULES"]["ALSEARCH_ITEMSLOT"] = {
			ModuleName="ItemSlotNames",
			Priority = 1,
			Func=alas_addon.Search_ItemSlotNames,
			LocKey=L["OPT_ITEMSLOTS_NAME"],
			LocValue=L["OPT_ITEMSLOTS_DESC"],
			foundMatch=nil,
			ValidValues = {
				BabbleInventory["Head"],
				BabbleInventory["Neck"],
				BabbleInventory["Shoulder"],
				BabbleInventory["Back"],
				BabbleInventory["Chest"],
				BabbleInventory["Shirt"],
				BabbleInventory["Tabard"],
				BabbleInventory["Wrist"],
				BabbleInventory["Hands"],
				BabbleInventory["Waist"],
				BabbleInventory["Legs"],
				BabbleInventory["Feet"],
				BabbleInventory["Ring"],
				BabbleInventory["Trinket"],
				BabbleInventory["Main Hand"],
				BabbleInventory["Off Hand"],
				BabbleInventory["One-Hand"],
				BabbleInventory["Two-Hand"],
				BabbleInventory["Held in Off-Hand"],
				BabbleInventory["Relic"],
			},
--			PreSearchFunc = alas_addon.PrepareZoneNameSearch,
--			PostSortFunc = alas_addon.CleanupZoneNameSearch,
			LocChoices=L["OPT_ITEMSLOTS_LIST"],
		}
	end
end


--[[
function AtlasLootAdvancedSearch:PerformSearchModuleItemIteration(searchIdx, searchers, tempResultsTable)
	local searchModule = searchers[searchIdx];
	
	-- let the search module know that we're about to start sending it item data to check
	local searchModulePerformedIteration = false;
	if searchModule.PreSearchFunc then
		searchModulePerformedIteration = searchModule:PreSearchFunc();
	end
	if not searchModulePerformedIteration then

		for lootSourceID, lootSourceContents in pairs(AtlasLoot_Data) do
			local zoneTableID = lootSourceID;
			for lootSourceCategoryIndex, lootSourceCategoryName in ipairs(lootTableTypes) do
				if	lootSourceContents.info and
					(lootSourceContents.info.instance == nil or lootSourceCategoryName == "Normal" or lootSourceCategoryName == "Heroic") and
					(not AtlasLoot.IgnoreList[lootSourceID]) then
					local function IterateLootTableItems( dataID )
						local lootTableItems = AtlasLoot:GetLootPageFromDataID(dataID);
						for tableIdx, item_data in ipairs(lootTableItems) do
							if not ALAS_HasModuleSeenItem(searchModule, item_data) then
								local foundMatch, itemID, displayText, extraInfo;
								local function MatchSearchPhraseRemainder( searchPhrase )
									local tempParameters = {
										SearchText = "",
										SearchParser = searchPhrase,
										pendingMatches = searchParms.pendingMatches,
										OriginalValue = searchParms,
									}
									searchParms = tempParameters;
									for connectedSearchIdx = 1, #searchers do
										if connectedSearchIdx ~= searchIdx then
											local connectedSearchModule = searchers[connectedSearchIdx];
											if not ALAS_HasModuleSeenItem(connectedSearchModule, item_data) then
												local prevMatch = ALAS_IsSearchResultFlagSet(connectedSearchModule, item_data);
												
												local foundConnectionMatch, connectionItemID, connectionDisplayText, connectionExtraInfo, additionalOrphenPhrases = connectedSearchModule:Func(zoneTableID, item_data, true);
												ALAS_MarkModuleSawItem(connectedSearchModule, item_data);
												
												local additionalTermCount = 0;
												if additionalOrphenPhrases then
													additionalTermCount = additionalOrphenPhrases:CountTokens();
													if additionalTermCount > 0 then
														MatchSearchPhraseRemainder(additionalOrphenPhrases);
													end
												end;
												if foundConnectionMatch and additionalTermCount == 0 then
													foundMatch = true;
													itemID = connectionItemID;
													displayText = connectionDisplayText;
													extraInfo = connectionExtraInfo;
												end
											end		-- ALAS_HasModuleSeenItem
										end
									end
									
									searchParms = tempParameters.OriginalValue;
								end
								local searchFunc = searchModule.Func;
								-- if the searcher returns a valid value for searchPhraseRemainder, it means that only part of the search string could be
								-- matched by this search module, and a predicate was specified.  i.e. if a user specifies the search term 'feet and "trial of the crusader"',
								-- only those search results which match both conditions can be shown, but each of the conditions in the search are recognized by
								-- different search modules.
								local searchPhraseRemainder;
								searchParms.pendingMatches = {};
								foundMatch, itemID, displayText, extraInfo, searchPhraseRemainder = searchFunc(searchModule, zoneTableID, item_data);
								if searchPhraseRemainder and searchPhraseRemainder:CountTokens() > 0 then
									MatchSearchPhraseRemainder(searchPhraseRemainder);
								end
								searchParms.pendingMatches = nil;

								-- the intent is to allow searchers to override other searchers' searches, if necessary
								if foundMatch ~= nil and type(foundMatch) == "boolean" then
									if not ALAS_IsItemInResultSet(item_data, foundMatch) then
										if foundMatch and displayText then
											ALAS_SetItemSearchResultFlag(searchModule, item_data);
											tinsert(tempResultsTable,
												{0, itemID, item_data[3], displayText, item_data[5], dataID}
											);
										end
									end
								end	-- foundMatch ~= nil and....
								ALAS_MarkModuleSawItem(searchModule, item_data);
							end		-- if not ALAS_HasModuleSeenItem
						end	-- ipairs(lootTableList)
					end -- local function IterateLootTableItems


					-- i.e. HellscreamsReach#Normal
					local dataID = lootSourceID .. "#" .. lootSourceCategoryName;
					local dataIDStrLength = strlen(dataID);
					IterateLootTableItems(dataID);
					
					-- each page is contained within its own subtable
					local nextPage = AtlasLoot:GetNextPrevPage(dataID);
					while ( nextPage ) do
						if strsub(nextPage, 1, dataIDStrLength) ~= dataID then
							break;
						end
						IterateLootTableItems(nextPage);
						nextPage = AtlasLoot:GetNextPrevPage(nextPage);
					end
				end
			end
		end
    
		-- let the search module know that the list is complete
		if searchModule.PostSearchFunc then
			searchModule:PostSearchFunc();
		end
	end
end
--]]
