Quantcast

local	KarmaObj = KarmaAvEnK;
local	KOH = KarmaObj.Helpers;
local	KCfg = KarmaObj.Cfg;

KarmaObj.LFM = {};

local	LFMObj = KarmaObj.LFM;
local	SlashObj = KarmaObj.Slash;

local	KarmaModuleLocal =
		{
			-- LFM window: setup
			KarmaWindow2_ShowInital = 0;
			KarmaWindow2_CreatedButtons = 0;


			-- LFM window: populate menu choices
			LFM_Populate_Channel = nil,
			LFM_Populate_Class = nil,
		};

-- COMMON/REGIONNAMES LEVEL FIELDS: DB_L3_CR
local	KARMA_DB_L3_CR = {
			ZONEIDS = "ZONEIDS",
			ISPVPZONE = "PVPZONE",
			ZONETYPE = "ZONETYPE"
		};

local	KARMA_DB_L4_RRFF = {
			ALTGROUPS = "ALTGROUPS",
		};

local	KARMA_DB_L5_RRFFM_CONFLICT = "CONFLICT";

-- possible talents
local	KARMA_TALENT_CLASSMASK =
	{
		 [1] = 31,	-- druid: HPS/R, FERAL/M, DPS/R
		 [2] = 20,	-- hunter: DPS/R
		 [3] = 20,	-- mage: DPS/R
		 [4] = 31,	-- paladin: HPS/R, TANK/M, DPS/M
		 [5] = 21,	-- priest: HPS/R, DPS/R
		 [6] = 12,	-- rogue: DPS/M
		 [7] = 29,	-- shaman: HPS/R, DPS/M, DPS/R
		 [8] = 14,	-- warrior: TANK/M, DPS/M
		 [9] = 20,	-- warlock: DPS/R
		[10] = 14,	-- deathknight: TANK/M, DPS/M
		[11] = 31,	-- monk: HPS/R, TANK/M, DPS/M
	};

local	KARMA_RacesAlliance =
	{
		[1] = "KRA_DRAENEI",
		[2] = "KRA_DWARF",
		[3] = "KRA_GNOME",
		[4] = "KRA_HUMAN",
		[5] = "KRA_NIGHTELF",
		[6] = "KRA_WORGEN",
		[7] = "KRA_PANDAREN"
	}

local	KARMA_ClassToAllianceRace_Matrix;

local	KARMA_ClassToAllianceRace_Matrix_LichKing =
	{
		-- races: Draenei, Dwarf, Gnome, Human, Night Elf
		 [1] = "00001",		--	Druid
		 [2] = "11001",		--	Hunter
		 [3] = "10110",		--	Mage
		 [4] = "11010",		--	Paladin
		 [5] = "11011",		--	Priest
		 [6] = "01111",		--	Rogue
		 [7] = "10000",		--	Shaman
		 [8] = "11111",		--	Warrior
		 [9] = "00110",		--	Warlock
		[10] = "11111"		--	Deathknight
	}

local	KARMA_ClassToAllianceRace_Matrix_Cataclysm =
	{
		-- races: Draenei, Dwarf, Gnome, Human, Night Elf, Worgen
		 [1] = "000011",	--	Druid
		 [2] = "110111",	--	Hunter
		 [3] = "101111",	--	Mage
		 [4] = "110100",	--	Paladin
		 [5] = "111111",	--	Priest
		 [6] = "011111",	--	Rogue
		 [7] = "110000",	--	Shaman
		 [8] = "111111",	--	Warrior
		 [9] = "011101",	--	Warlock
		[10] = "111111"		--	Deathknight
	}

local	KARMA_ClassToAllianceRace_Matrix_Pandaria =
	{
		-- races: Draenei, Dwarf, Gnome, Human, Night Elf, Worgen, Pandaren
		 [1] = "0000110",	--	Druid
		 [2] = "1101111",	--	Hunter
		 [3] = "1111111",	--	Mage
		 [4] = "1101000",	--	Paladin
		 [5] = "1111111",	--	Priest
		 [6] = "0111111",	--	Rogue
		 [7] = "1100001",	--	Shaman
		 [8] = "1111111",	--	Warrior
		 [9] = "0111010",	--	Warlock
		[10] = "1111110",	--	Deathknight
		[11] = "1111101"	--	Monk
	}

local	KARMA_RacesHorde =
	{
		[1] = "KRH_BLOODELF",
		[2] = "KRH_ORC",
		[3] = "KRH_TAUREN",
		[4] = "KRH_TROLL",
		[5] = "KRH_UNDEAD",
		[7] = "KRH_PANDAREN"
	}

local	KARMA_ClassToHordeRace_Matrix;

local	KARMA_ClassToHordeRace_Matrix_LichKing =
	{
		-- races: Blood Elf, Orc, Tauren, Troll, Undead
		 [1] = "00100",		--	Druid
		 [2] = "11110",		--	Hunter
		 [3] = "10011",		--	Mage
		 [4] = "10000",		--	Paladin
		 [5] = "10011",		--	Priest
		 [6] = "11011",		--	Rogue
		 [7] = "01110",		--	Shaman
		 [8] = "01111",		--	Warrior
		 [9] = "11001",		--	Warlock
		[10] = "11111"		--	Deathknight
	}

local	KARMA_ClassToHordeRace_Matrix_Cataclysm =
	{
		-- races: Blood Elf, Orc, Tauren, Troll, Undead, Goblin
		 [1] = "001100",	--	Druid
		 [2] = "111111",	--	Hunter
		 [3] = "110111",	--	Mage
		 [4] = "101000",	--	Paladin
		 [5] = "101111",	--	Priest
		 [6] = "110111",	--	Rogue
		 [7] = "011101",	--	Shaman
		 [8] = "111111",	--	Warrior
		 [9] = "110111",	--	Warlock
		[10] = "111111"		--	Deathknight
	}

local	KARMA_ClassToHordeRace_Matrix_Pandaria =
	{
		-- races: Blood Elf, Orc, Tauren, Troll, Undead, Goblin, Pandaren
		 [1] = "0011000",	--	Druid
		 [2] = "1111111",	--	Hunter
		 [3] = "1101111",	--	Mage
		 [4] = "1010000",	--	Paladin
		 [5] = "1011111",	--	Priest
		 [6] = "1101111",	--	Rogue
		 [7] = "0111011",	--	Shaman
		 [8] = "1111111",	--	Warrior
		 [9] = "1101110",	--	Warlock
		[10] = "1111110",	--	Deathknight
		[11] = "1111101"	--	Monk
	}

local	KARMA_Online =
		{
			PlayersVersion = 0;
			PlayersAll = {};
			PlayersAllFilter = {
					minKarma = 50,
					KarmaReq = 0,
					minSkill = nil,
					ClassKnown = 0,
					LevelFrom = nil,
					LevelTo = nil,
					TalentHPS = 1,
					TalentTANK = 1,
					TalentDPS = 1,
					TalentMelee = 1,
					TalentRange = 1,
					ClassDruid = 1,
					ClassHunter = 1,
					ClassMage = 1,
					ClassPaladin = 1,
					ClassPriest = 1,
					ClassRogue = 1,
					ClassShaman = 1,
					ClassWarlock = 1,
					ClassWarrior = 1,
					ClassDeathknight = 1,
					ClassMonk = 1,
					Alts = false,
				},
			PlayersAllCache =
				{
					Version = 0,
					List1_Raw = {},
					List1_Srt = {},
					List1_Clean = nil
				},
			PlayersChosen = {};
		};

local	KARMA_LFGWND_LIST1_SIZE = 34;
local	KARMA_LFGWND_LIST2_SIZE = 25;

local	function	Karma_PlayerLevelRange()
	local	minlvl, islvl, maxlvl, delta;
	islvl = UnitLevel("player");

	-- lower levels => bigger range to include
	if (islvl < 41) then
		delta = 7;
	elseif (islvl < 51) then
		delta = 6;
	elseif (islvl < 61) then
		delta = 5;
	elseif (islvl < 71) then
		delta = 4;
	elseif (islvl < 80) then
		delta = 3;
	else
		delta = 2;
	end

	minlvl = math.max(islvl - delta, 1);
	maxlvl = math.min(islvl + delta, KarmaObj.Const.LevelMax);

	return minlvl, maxlvl;
end

-- ************************************************************************ --

-- ************************************************************************ --

function SlashObj.CheckClassOnline(args)
	if (args[2] == nil) or (args[2] == "") then
		KarmaChatDefault(KARMA_MSG_COMMAND_MISSINGARG .. KARMA_WINEL_FRAG_COLONSPACE .. KARMA_MSG_CHECKCLASS_CLASS);
		return
	end

	KarmaChatDefault(KARMA_MSG_CHECKCLASS_QUEUEING_ONE .. args[2] .. KARMA_WINEL_FRAG_TRIDOTS);

	-- queue all
	LFMObj.CheckClassOnline(args);
end

function LFMObj.CheckClassOnline(args)
	local	FactionRaceListComplete, FactionRaceListLocalized, ClassRaceMatrix;
	if (UnitFactionGroup("player") == "Alliance") then
		ClassRaceMatrix = KARMA_ClassToAllianceRace_Matrix;
		FactionRaceListComplete = KARMA_RacesAlliance;
		FactionRaceListLocalized = KARMA_RACES_ALLIANCE_LOCALIZED;
	elseif (UnitFactionGroup("player") == "Horde") then
		ClassRaceMatrix = KARMA_ClassToHordeRace_Matrix;
		FactionRaceListComplete = KARMA_RacesHorde;
		FactionRaceListLocalized = KARMA_RACES_HORDE_LOCALIZED;
	else
		KarmaChatDefault("You haven't chosen a faction to associate with yet.");
		return
	end

	local	iRaceCountMax, iRaceCount = 5;
	if (KarmaObj.Const.iTOC < 40000) then
		FactionRaceListComplete[6] = nil;
		FactionRaceListComplete[7] = nil;
	elseif (KarmaObj.Const.iTOC < 50000) then
		iRaceCountMax = 6;
		FactionRaceListComplete[7] = nil;
	else
		iRaceCountMax = 7;
	end
	iRaceCount = iRaceCountMax;

	-- need independent copy to delete the stuff we don't want
	local	FactionRaceListCheck = Karma_CopyTable(FactionRaceListComplete);

	local	ClassID = KOH.ClassToID(args[2]);
	if (ClassID ~= 0) then
		ClassID = math.abs(ClassID);
		local	iIndex;
		local	ClassToRace = ClassRaceMatrix[ClassID];
		if (not ClassToRace) then
			KarmaChatDebug("ClassID = " .. ClassID .. ": no race vector.");
		else
			KarmaChatDebug("ClassID = " .. ClassID .. " => Vector = " .. ClassToRace);
			local	sRemoved, sRemaining = "", "";
			local	RemKey, RemVal;
			for iIndex = 1, iRaceCountMax do
				if (strsub(ClassToRace, iIndex, iIndex) == "0") then
					sRemoved = sRemoved .. ", " .. Karma_NilToString(FactionRaceListComplete[iIndex]);
					for RemKey, RemVal in pairs(FactionRaceListCheck) do
						if (RemVal == FactionRaceListComplete[iIndex]) then
							tremove(FactionRaceListCheck, RemKey);
							iRaceCount = iRaceCount - 1;
							break
						end
					end
				else
					sRemaining = sRemaining .. ", " .. Karma_NilToString(FactionRaceListComplete[iIndex]);
				end
			end

			KarmaChatDebug("Removed {" .. strsub(sRemoved, 3) .. "}, remaining {" .. strsub(sRemaining, 3) .. "}");
		end
	else
		KarmaChatDefault(KARMA_MSG_CHECKCLASS_UNK1 .. " <" .. args[2] .. ">" .. KARMA_MSG_CHECKCLASS_UNK2);
		return
	end

	local	CCO_Args = {};
	CCO_Args[2] = args[2];	-- mandatory: class
	CCO_Args[4] = args[3];	-- maybe: level

	local	Races, sRace, key, value = {};
	for key, value in pairs(FactionRaceListCheck) do
		sRace = FactionRaceListLocalized[value];
		if (sRace == nil) then
			KarmaChatDebug("Missing localization to race " .. value .. " in the active locale.");
		end

		tinsert(Races, sRace);
	end

	local	iFrom, iTo = 1, KarmaObj.Const.LevelMax;
	if (args[3]) then
		iFrom, iTo = strsplit('-', args[3]);
		if (iFrom and iTo) then
			iFrom = tonumber(iFrom);
			iTo = tonumber(iTo);
			if (iFrom and iTo and iTo < iFrom) then
				args[3] = iTo .. "-" .. iFrom;
			end
		else
			local	iExact = tonumber(args[3]);
			if (iExact) then
				iFrom = iExact;
				iTo = iExact;
			end
		end
	end

	-- CCO_Args[3] is UNSET: first /who is actually without race to get a quick initial set
	if ((iFrom < iTo) and (iTo == KarmaObj.Const.LevelMax)) then
		if (iFrom < iTo - 5) then
			if (iFrom < 10) then
				-- bank alts level range
				CCO_Args[4] = iFrom .. "-10";
				Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
				CCO_Args = Karma_CopyTable(CCO_Args);
				-- regular levelling range
				CCO_Args[4] = "11-" .. (iTo - 6);
				Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
			else
				CCO_Args[4] = iFrom .. "-" .. (iTo - 6);
				Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
			end
			-- close to max. level
			CCO_Args = Karma_CopyTable(CCO_Args);
			CCO_Args[4] = (iTo - 5) .. "-" .. (iTo - 1);
			Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
		else
			-- e.g. 82-85
			CCO_Args = Karma_CopyTable(CCO_Args);
			CCO_Args[4] = iFrom .. "-" .. (iTo - 1);
			Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
		end

		-- max. level only
		CCO_Args = Karma_CopyTable(CCO_Args);
		CCO_Args[4] = iTo .. "-" .. iTo;
		Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
	else
		Karma_Command_CompareClassOnline_Insert(CCO_Args, Races);
	end
	KarmaChatDebug("Queued request(s) to check for class " .. args[2] .. KARMA_WINEL_FRAG_TRIDOTS);

	local	oCmd = { sName = "classcheck done", func = LFMObj.ClassCheckCompleted, args = Karma_CopyTable(args) };
	KarmaObj.Slash.CommandQAdd(oCmd);
end

function LFMObj.ClassCheckCompleted(args)
	local	bFound = false;
	local	fFind = function(oCmd)
			if (oCmd.method and (oCmd.method == Karma_Command_CompareClassOnline_Start) and oCmd.args and (oCmd.args.sClass == args[2])) then
				bFound = true;
				return false;
			end

			return true;
		end
	KarmaObj.Slash.CommandQIterate(fFind);

	if (bFound) then
		local	oCmd = { sName = "classcheck done", func = LFMObj.ClassCheckCompleted, args = args };
		KarmaObj.Slash.CommandQAdd(oCmd);
	else
		KarmaChatSecondaryFallbackDefault(KARMA_MSG_CHECKCLASS_DONE1 .. args[2] .. KARMA_MSG_CHECKCLASS_DONE2);
	end

	LFMObj.WindowUpdate();
end

-- ************************************************************************ --

function KarmaObj.Slash.CheckAllClassesOnline(args)
	-- if level range is given, the total # might be less than 50, so we wouldn't need to split by class
	if (args[2] and (args[2] ~= "") and (args[2] ~= tostring(KarmaObj.Const.LevelMax)) and not strfind(args[2], "-" .. tostring(KarmaObj.Const.LevelMax), 1, true)) then
		local	CCO_Args = {};
		CCO_Args[2] = "ANY";	-- class
		CCO_Args[3] = nil;	-- race
		CCO_Args[4] = args[2];	-- level

		Karma_Command_CompareClassOnline_Insert(CCO_Args);
		local	oCmd = { sName = "classcheck preview all", func = LFMObj.CheckAllClassesOnlineMaybe, args = args };
		KarmaObj.Slash.CommandQAdd(oCmd);
	else
		LFMObj.CheckAllClassesOnlineReally(args);
	end
end

function LFMObj.CheckAllClassesOnlineMaybe(args)
	local	_, iMax = GetNumWhoResults();
	if (iMax < 49) then
		local	oCmd = { sName = "classcheck done all", func = LFMObj.CheckAllClassesCompleted, args = { bFirst = false }};
		KarmaObj.Slash.CommandQAdd(oCmd);
	else
		LFMObj.CheckAllClassesOnlineReally(args);
	end
end

function LFMObj.CheckAllClassesOnlineReally(args)
	KarmaChatDefault(KARMA_MSG_CHECKCLASS_QUEUEING_ALL);

	-- queue *all*
	local	iFilter = 7;
	if (type(args[3]) == "number") then
		local	iRole = args[3];
		if (iRole == 1) then
			-- tank
			iFilter = 2;
			KarmaChatDebug("CACO: Setting filter to 2 for tanks.");
		elseif (iRole == 2) then
			-- hps
			iFilter = 1;
			KarmaChatDebug("CACO: Setting filter to 1 for healers.");
		elseif (iRole == 3) then
			-- dps
			iFilter = 4;
			KarmaChatDebug("CACO: Setting filter to 4 for dps.");
		else
			KarmaChatDebug("CACO: Invalid filter: " .. tostring(iRole));
		end
	end

	-- shift level, if argument was given
	args[3] = args[2];

	-- default to KarmaObj.Const.LevelMax if missing... (or player level +/-3 like /who?)
	if (args[3] == nil) or (args[3] == "") then
		args[3] = KarmaObj.Const.LevelMax;
	end

	local	iCounter;
	for iCounter = 1, #KARMA_TALENT_CLASSMASK do
		if (0 ~= bit.band(KARMA_TALENT_CLASSMASK[iCounter], iFilter)) then
			args[2] = KOH.IDToClass(iCounter);
			LFMObj.CheckClassOnline(args);
		end
	end

	-- "Job done" message
	local	oCmd = { sName = "classcheck done all", func = LFMObj.CheckAllClassesCompleted, args = { bFirst = true }};
	KarmaObj.Slash.CommandQAdd(oCmd);
end

function LFMObj.CheckAllClassesCompleted(args)
	local	bFound = false;
	local	fFind = function(oCmd)
			if (oCmd.method and (oCmd.method == Karma_Command_CompareClassOnline_Start)) then
				bFound = true;
				return false;
			end

			return true;
		end
	KarmaObj.Slash.CommandQIterate(fFind);

	if (bFound) then
		if (args.bFirst) then
			KarmaChatDefault(KARMA_MSG_CHECKCLASS_DONE_QUICK);
		end

		-- "Job done" message
		local	oCmd = { sName = "classcheck done all", func = LFMObj.CheckAllClassesCompleted, args = {}};
		KarmaObj.Slash.CommandQAdd(oCmd);
	else
		KarmaChatDefault(KARMA_MSG_CHECKCLASS_DONE_ALL);
	end
end

-- ************************************************************************ --

function	Karma_SlashCheckGuild(args)
	if (args[2] ~= nil) and (args[2] ~= "") then
		Karma_Command_CompareGuildOnline_Insert(args);
	else
		KarmaChatDefault(KARMA_MSG_COMMAND_MISSINGARG .. KARMA_WINEL_FRAG_COLONSPACE .. KARMA_MSG_CHECKGUILD_NOARG);
	end
end

-- ************************************************************************ --
-- ************************************************************************ --

function	LFMObj.PlayerUpdateFromChannel(sMemberName, iNow, bIsLFGChannel)
	if (KARMA_Online.PlayersAll[sMemberName] == nil) then
		KARMA_Online.PlayersAll[sMemberName] = {};
	end
	KARMA_Online.PlayersAll[sMemberName].time = iNow;
	if (bIsLFGChannel) then
		KARMA_Online.PlayersAll[sMemberName].lfg = iNow;
	else
		KARMA_Online.PlayersAll[sMemberName].lfg = nil;
	end
	KARMA_Online.PlayersVersion = KARMA_Online.PlayersVersion + 1;
end

function	LFMObj.PlayerUpdateFromWhoResult(sName, iNow, guild, level, race, class, zone)
	if (KARMA_Online.PlayersAll[sName] == nil) then
		KARMA_Online.PlayersAll[sName] = {};
	end

	KARMA_Online.PlayersAll[sName].time = iNow;
	KARMA_Online.PlayersAll[sName].zone = zone;
	-- non-members!
	KARMA_Online.PlayersAll[sName].guild = guild;
	KARMA_Online.PlayersAll[sName].level = level;
	KARMA_Online.PlayersAll[sName].class = class;

	-- not used
	KARMA_Online.PlayersAll[sName].race = race;

	KARMA_Online.PlayersVersion = KARMA_Online.PlayersVersion + 1;
end

-- ************************************************************************ --
-- ************************************************************************ --

function	LFMObj.WindowToggle()
	if (KarmaWindow2:IsVisible()) then
		KarmaWindow2:Hide();
	else
		KarmaWindow2:Show();
	end
end

function	LFMObj.WindowUpdate(bIfVisible)
	-- we don't want to appear ourselves
	KARMA_Online.PlayersAll[UnitName("player")] = nil;

	if (not bIfVisible or KarmaWindow2:IsVisible()) then
		KarmaWindow2_UpdateList1();
		KarmaWindow2_UpdateList2();
	end
end

function	LFMObj.WindowReset()
	KarmaWindow2:Hide();
	KarmaWindow2:ClearAllPoints();
	KarmaWindow2:SetPoint("CENTER");
	KarmaWindow2:Show();
end

-----------------------------------------
-- WndLFG
-----------------------------------------

function	KarmaWindow2_FilterList1_SkillMin_DropDown_Initialize()
	local	info = {};

	info.value = 1;
	info.text = "----- none -----";
--	info.notCheckable = true;				-- bugs SetSelectedID
	info.justifyH = "CENTER";

	info.func = KarmaWindow2_FilterList1_SkillMin_DropDown_OnClick;
	info.arg1 = info.text;
	info.arg2 = nil;

	UIDropDownMenu_AddButton(info);

	if (KarmaObj.Const.SkillLevels) then
		info = table.wipe(info);
		info.func = KarmaWindow2_FilterList1_SkillMin_DropDown_OnClick;
--		info.notCheckable = true;			-- bugs SetSelectedID

		local	i;
		for i = 0, 100 do
			if (KarmaObj.Const.SkillLevels[i]) then
				info.value = i + 100;
				info.text = KarmaObj.Const.SkillLevels[i];
				info.arg1 = KarmaObj.Const.SkillLevels[i];
				info.arg2 = i;

				UIDropDownMenu_AddButton(info);
			end
		end
	end
end

function	KarmaWindow2_FilterList1_SkillMin_DropDown_OnShow(self)
	UIDropDownMenu_Initialize(self, KarmaWindow2_FilterList1_SkillMin_DropDown_Initialize);
	UIDropDownMenu_SetWidth(self, 250);
	UIDropDownMenu_SetButtonWidth(self, 24);

	UIDropDownMenu_SetSelectedID(self, 1);
end

local	KarmaWindow2_FilterList1_SkillMin_DropDown_Selection = nil;

function	KarmaWindow2_FilterList1_SkillMin_DropDown_OnClick(self, arg1, arg2)
	UIDropDownMenu_SetSelectedID(KarmaWindow2_FilterList1_SkillMin_DropDown, self:GetID());
	UIDropDownMenu_SetText(KarmaWindow2_FilterList1_SkillMin_DropDown, arg1);
	KarmaWindow2_FilterList1_SkillMin_DropDown_Selection = arg2;
end
-- ************************************************************************ --
-- ************************************************************************ --

function	KarmaWindow2_FilterList1_Init()
	if (KARMA_Online.PlayersAllFilter.minKarma) then
		KarmaWindow2_FilterList1_KarmaMin_Editbox:SetText(tostring(KARMA_Online.PlayersAllFilter.minKarma));
	else
		KarmaWindow2_FilterList1_KarmaMin_Editbox:SetText("");
	end

	if (KARMA_Online.PlayersAllFilter.KarmaReq) then
		KarmaWindow2_FilterList1_KarmaReq_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.KarmaReq);
	else
		KarmaWindow2_FilterList1_KarmaReq_Checkbutton:SetChecked(0);
	end

	if (KARMA_Online.PlayersAllFilter.ClassKnown) then
		KarmaWindow2_FilterList1_ClassReq_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassKnown);
	else
		KarmaWindow2_FilterList1_ClassReq_Checkbutton:SetChecked(0);
	end

	-- Level range
	if (KARMA_Online.PlayersAllFilter.LevelFrom) and (KARMA_Online.PlayersAllFilter.LevelTo) then
		KarmaWindow2_FilterList1_LevelRange_Editbox:SetText(tostring(KARMA_Online.PlayersAllFilter.LevelFrom)
									.. "-" .. tostring(KARMA_Online.PlayersAllFilter.LevelTo));
	else
		-- local	minlvl, maxlvl = Karma_PlayerLevelRange();
		local	minlvl, maxlvl = 1, KarmaObj.Const.LevelMax;
		KarmaWindow2_FilterList1_LevelRange_Editbox:SetText(tostring(minlvl) .. "-" .. tostring(maxlvl));
		KARMA_Online.PlayersAllFilter.LevelFrom = minlvl;
		KARMA_Online.PlayersAllFilter.LevelTo = maxlvl;
	end

	-- Talents: HPS/TANK/DPS Melee/Ranged
	if (KARMA_Online.PlayersAllFilter.TalentHPS) then
		KarmaWindow2_FilterList1_HPS_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.TalentHPS);
	else
		KarmaWindow2_FilterList1_HPS_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.TalentTANK) then
		KarmaWindow2_FilterList1_TANK_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.TalentTANK);
	else
		KarmaWindow2_FilterList1_TANK_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.TalentDPS) then
		KarmaWindow2_FilterList1_DPS_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.TalentDPS);
	else
		KarmaWindow2_FilterList1_DPS_Checkbutton:SetChecked(1);
	end

	if (KARMA_Online.PlayersAllFilter.TalentMelee) then
		KarmaWindow2_FilterList1_Melee_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.TalentMelee);
	else
		KarmaWindow2_FilterList1_Melee_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.TalentRange) then
		KarmaWindow2_FilterList1_Range_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.TalentRange);
	else
		KarmaWindow2_FilterList1_Range_Checkbutton:SetChecked(1);
	end

	-- Classes
	if (KARMA_Online.PlayersAllFilter.ClassDruid) then
		KarmaWindow2_FilterList1_Druid_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassDruid);
	else
		KarmaWindow2_FilterList1_Druid_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassHunter) then
		KarmaWindow2_FilterList1_Hunter_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassHunter);
	else
		KarmaWindow2_FilterList1_Hunter_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassMage) then
		KarmaWindow2_FilterList1_Mage_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassMage);
	else
		KarmaWindow2_FilterList1_Mage_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassPaladin) then
		KarmaWindow2_FilterList1_Paladin_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassPaladin);
	else
		KarmaWindow2_FilterList1_Paladin_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassPriest) then
		KarmaWindow2_FilterList1_Priest_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassPriest);
	else
		KarmaWindow2_FilterList1_Priest_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassRogue) then
		KarmaWindow2_FilterList1_Rogue_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassRogue);
	else
		KarmaWindow2_FilterList1_Rogue_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassShaman) then
		KarmaWindow2_FilterList1_Shaman_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassShaman);
	else
		KarmaWindow2_FilterList1_Shaman_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassWarlock) then
		KarmaWindow2_FilterList1_Warlock_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassWarlock);
	else
		KarmaWindow2_FilterList1_Warlock_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassWarrior) then
		KarmaWindow2_FilterList1_Warrior_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassWarrior);
	else
		KarmaWindow2_FilterList1_Warrior_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassDeathknight) then
		KarmaWindow2_FilterList1_Deathknight_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassDeathknight);
	else
		KarmaWindow2_FilterList1_Deathknight_Checkbutton:SetChecked(1);
	end
	if (KARMA_Online.PlayersAllFilter.ClassMonk) then
		KarmaWindow2_FilterList1_Monk_Checkbutton:SetChecked(KARMA_Online.PlayersAllFilter.ClassMonk);
	else
		KarmaWindow2_FilterList1_Monk_Checkbutton:SetChecked(1);
	end
end

function	KarmaWindow2_FilterList1_Ok()
	local	sValue, iValue;

	KARMA_Online.PlayersAllFilter.minKarma = nil;
	sValue = KarmaWindow2_FilterList1_KarmaMin_Editbox:GetText();
	if (sValue) and (sValue ~= "") then
		iValue = tonumber(sValue);
		if (iValue) then
			KARMA_Online.PlayersAllFilter.minKarma = iValue;
		end
	end

	if (KarmaWindow2_FilterList1_KarmaReq_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.KarmaReq = 1;
	else
		KARMA_Online.PlayersAllFilter.KarmaReq = 0;
	end

	KARMA_Online.PlayersAllFilter.minSkill = KarmaWindow2_FilterList1_SkillMin_DropDown_Selection;
	if (KARMA_Online.PlayersAllFilter.minSkill and KarmaObj.Const.SkillLevels) then
		if (KarmaObj.Const.SkillLevels[KARMA_Online.PlayersAllFilter.minSkill] == nil) then
			KARMA_Online.PlayersAllFilter.minSkill = nil;
		end
	end

	if (KarmaWindow2_FilterList1_ClassReq_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassKnown = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassKnown = 0;
	end

	KARMA_Online.PlayersAllFilter.LevelFrom = nil;
	KARMA_Online.PlayersAllFilter.LevelTo = nil;
	local	LevelRange = KarmaWindow2_FilterList1_LevelRange_Editbox:GetText();
	if (tonumber(LevelRange) ~= nil) then
		KARMA_Online.PlayersAllFilter.LevelFrom = tonumber(LevelRange);
		KARMA_Online.PlayersAllFilter.LevelTo = tonumber(LevelRange);
	else
		local	iPosHyphen = strfind(tostring(LevelRange), "-", 1, true);
		if (iPosHyphen) then
			local	LevelFrom = strsub(tostring(LevelRange), 1, iPosHyphen - 1);
			local	LevelTo = strsub(tostring(LevelRange), iPosHyphen + 1);
			if (tonumber(LevelFrom) and tonumber(LevelTo)) then
				KARMA_Online.PlayersAllFilter.LevelFrom = tonumber(LevelFrom);
				KARMA_Online.PlayersAllFilter.LevelTo = tonumber(LevelTo);
			end
		end
	end

	if (KarmaWindow2_FilterList1_HPS_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.TalentHPS = 1;
	else
		KARMA_Online.PlayersAllFilter.TalentHPS = 0;
	end
	if (KarmaWindow2_FilterList1_TANK_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.TalentTANK = 1;
	else
		KARMA_Online.PlayersAllFilter.TalentTANK = 0;
	end
	if (KarmaWindow2_FilterList1_DPS_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.TalentDPS = 1;
	else
		KARMA_Online.PlayersAllFilter.TalentDPS = 0;
	end

	if (KarmaWindow2_FilterList1_Melee_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.TalentMelee = 1;
	else
		KARMA_Online.PlayersAllFilter.TalentMelee = 0;
	end
	if (KarmaWindow2_FilterList1_Range_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.TalentRange = 1;
	else
		KARMA_Online.PlayersAllFilter.TalentRange = 0;
	end

	if (KarmaWindow2_FilterList1_Druid_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassDruid = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassDruid = 0;
	end
	if (KarmaWindow2_FilterList1_Hunter_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassHunter = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassHunter = 0;
	end
	if (KarmaWindow2_FilterList1_Mage_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassMage = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassMage = 0;
	end
	if (KarmaWindow2_FilterList1_Paladin_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassPaladin = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassPaladin = 0;
	end
	if (KarmaWindow2_FilterList1_Priest_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassPriest = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassPriest = 0;
	end
	if (KarmaWindow2_FilterList1_Rogue_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassRogue = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassRogue = 0;
	end
	if (KarmaWindow2_FilterList1_Shaman_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassShaman = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassShaman = 0;
	end
	if (KarmaWindow2_FilterList1_Warlock_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassWarlock = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassWarlock = 0;
	end
	if (KarmaWindow2_FilterList1_Warrior_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassWarrior = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassWarrior = 0;
	end
	if (KarmaWindow2_FilterList1_Deathknight_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassDeathknight = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassDeathknight = 0;
	end
	if (KarmaWindow2_FilterList1_Monk_Checkbutton:GetChecked()) then
		KARMA_Online.PlayersAllFilter.ClassMonk = 1;
	else
		KARMA_Online.PlayersAllFilter.ClassMonk = 0;
	end

	KARMA_Online.PlayersVersion = KARMA_Online.PlayersVersion + 1;
	KarmaWindow2_UpdateList1();
end

function	KarmaWindow2_Alts_Toggle()
	KARMA_Online.PlayersAllFilter.Alts = not KARMA_Online.PlayersAllFilter.Alts;
	local	sTitle = KarmaWindow2_Alts_Button:GetText();
	if (KARMA_Online.PlayersAllFilter.Alts) then
		sTitle = "-" .. strsub(sTitle, 2);
	else
		sTitle = "+" .. strsub(sTitle, 2);
	end
	KarmaWindow2_Alts_Button:SetText(sTitle);

	KARMA_Online.PlayersVersion = KARMA_Online.PlayersVersion + 1;
	KarmaWindow2_UpdateList1();
end

-- ************************************************************************ --
-- ************************************************************************ --
function	KarmaWindow2_PopulateWindow_Channel_DropDown_Initialize()
	local	info;
	local	i, id, name;
	for i = 1, 10 do
		id, name = GetChannelName(i);
		if (id == i) then
			info = {};
			info.value = i;
			info.text = id .. KARMA_WINEL_FRAG_COLONSPACE .. name;
			info.arg1 = name;
			info.arg2 = i;
			info.func = KarmaWindow2_PopulateWindow_Channel_DropDown_OnClick;
			UIDropDownMenu_AddButton(info);
		end
	end
end

function	KarmaWindow2_PopulateWindow_Channel_DropDown_OnShow(self)
	UIDropDownMenu_Initialize(self, KarmaWindow2_PopulateWindow_Channel_DropDown_Initialize);
	UIDropDownMenu_SetWidth(self, 150);
	UIDropDownMenu_SetButtonWidth(self, 24);

	-- hopefully overriden...
	UIDropDownMenu_SetSelectedID(self, 1);
	KarmaModuleLocal.LFM_Populate_Channel = 1;
end

function	KarmaWindow2_PopulateWindow_Channel_DropDown_OnClick(self, arg1, arg2)
	UIDropDownMenu_SetSelectedID(KarmaWindow2_PopulateWindow_Channel_DropDown, self:GetID());
	UIDropDownMenu_SetText(KarmaWindow2_PopulateWindow_Channel_DropDown, arg1);
	KarmaModuleLocal.LFM_Populate_Channel = arg2;

	local	oCheckBox = KarmaWindow2_PopulateWindow_Channel_Checkbox;
	if (oCheckBox:GetChecked() ~= 1) then
		oCheckBox:SetChecked(1)
		KarmaWindow2_PopulateWindow_ClickedSearch(oCheckBox);
	end
end
-- ************************************************************************ --
-- ************************************************************************ --

-- ************************************************************************ --
-- ************************************************************************ --
function	KarmaWindow2_PopulateWindow_Class_DropDown_Initialize()
	local	info, i = {};

	local	oTableLocale = KARMAAVENK_LOCUI_MODLFM[KARMAAVENK_LOCUI_MODLFM["DEFAULT"]];
	local	oRole = { oTableLocale.TANK, oTableLocale.HPS, oTableLocale.DPS };
	for i = 1, 3 do
		info = table.wipe(info);

		info.value = 100 + i;
		info.text = oRole[i];

		info.func = KarmaWindow2_PopulateWindow_Class_DropDown_OnClick;
		info.arg1 = info.text;
		info.arg2 = 100 + i;

		UIDropDownMenu_AddButton(info);
	end

	info = table.wipe(info);
	info.value = 50;
	info.text = "----------------------";
	info.notClickable = true;
	info.notCheckable = true;
	info.justifyH = "CENTER";

	UIDropDownMenu_AddButton(info);

	local	ClassRaceMatrix;
	if (UnitFactionGroup("player") == "Alliance") then
		ClassRaceMatrix = KARMA_ClassToAllianceRace_Matrix;
	elseif (UnitFactionGroup("player") == "Horde") then
		ClassRaceMatrix = KARMA_ClassToHordeRace_Matrix;
	else
		ClassRaceMatrix = {};
	end

	local	i;
	for i = 1, #KARMA_TALENT_CLASSMASK do
		-- skip classes not valid in the current expansion (added with MoP beta for monk)
		if (ClassRaceMatrix[i]) then
			info = table.wipe(info);
			info.value = i;
			info.text = KOH.IDToClass(i);

			info.func = KarmaWindow2_PopulateWindow_Class_DropDown_OnClick;
			info.arg1 = info.text;
			info.arg2 = i;

			UIDropDownMenu_AddButton(info);
		end
	end
end

function	KarmaWindow2_PopulateWindow_Class_DropDown_OnShow(self)
	UIDropDownMenu_Initialize(self, KarmaWindow2_PopulateWindow_Class_DropDown_Initialize);
	UIDropDownMenu_SetWidth(self, 150);
	UIDropDownMenu_SetButtonWidth(self, 24);

	UIDropDownMenu_SetSelectedID(self, 1);			-- UIDropDownMenu_SetSelectedID chooses the line #1, not the line with the value 1!
	KarmaModuleLocal.LFM_Populate_Class = 101;
end

function	KarmaWindow2_PopulateWindow_Class_DropDown_OnClick(self, arg1, arg2)
	UIDropDownMenu_SetSelectedID(KarmaWindow2_PopulateWindow_Class_DropDown, self:GetID());
	UIDropDownMenu_SetText(KarmaWindow2_PopulateWindow_Class_DropDown, arg1);
	KarmaModuleLocal.LFM_Populate_Class = arg2;

	local	oCheckBox = KarmaWindow2_PopulateWindow_Class_Checkbox;
	if (oCheckBox:GetChecked() ~= 1) then
		oCheckBox:SetChecked(1)
		KarmaWindow2_PopulateWindow_ClickedSearch(oCheckBox);
	end
end
-- ************************************************************************ --
-- ************************************************************************ --

function	KarmaWindow2_PopulateWindow_Level_Editbox_OnShow(self)
	local	text = KarmaWindow2_PopulateWindow_Level_Editbox:GetText();
	if (text == nil) or (text == "") then
		local	minlvl, maxlvl = Karma_PlayerLevelRange();
		KarmaWindow2_PopulateWindow_Level_Editbox:SetText(tostring(minlvl) .. "-" .. tostring(maxlvl));
	end
end

function	KarmaWindow2_PopulateWindow_ClickedSearch(which)
	local	CheckBoxes = {
				KarmaWindow2_PopulateWindow_Channel_Checkbox,
				KarmaWindow2_PopulateWindow_Channels_Checkbox,
				KarmaWindow2_PopulateWindow_Class_Checkbox,
				KarmaWindow2_PopulateWindow_Classes_Checkbox,
				KarmaWindow2_PopulateWindow_Guild_Checkbox
			};
	local key, value;
	for key, value in pairs(CheckBoxes) do
		if (value ~= which) then
			value:SetChecked(0);
		end
	end
end

function	KarmaWindow2_PopulateWindow_Execute()
KarmaChatDebug(">> KarmaWindow2_PopulateWindow_Execute");
	if (KarmaWindow2_PopulateWindow_Channel_Checkbox:GetChecked() == 1) then
		if (KarmaModuleLocal.LFM_Populate_Channel) and (KarmaModuleLocal.LFM_Populate_Channel > 0) then
			Karma_QueueCommandChannelCheck(KarmaModuleLocal.LFM_Populate_Channel);
			KarmaWindow2_PopulateWindow_Channel_Checkbox:SetChecked(0);
			-- UIDropDownMenu_SetSelectedID(KarmaWindow2_PopulateWindow_Channel_DropDown, 0);
			-- UIDropDownMenu_SetText(KarmaWindow2_PopulateWindow_Channel_DropDown, "");
		end
	elseif (KarmaWindow2_PopulateWindow_Channels_Checkbox:GetChecked() == 1) then
		KarmaChatDefault(KARMA_MSG_CHECKCHANNEL_ALL .. KARMA_WINEL_FRAG_TRIDOTS);
		local	i, id, name;
		for i = 1, 10 do
			id, name = GetChannelName(i);
			if (id == i) then
				Karma_QueueCommandChannelCheck(id);
			end
		end

		KarmaWindow2_PopulateWindow_Channels_Checkbox:SetChecked(0);
	end

	local	levelrange = KarmaWindow2_PopulateWindow_Level_Editbox:GetText();
	if (KarmaWindow2_PopulateWindow_Class_Checkbox:GetChecked() == 1) then
		if (KarmaModuleLocal.LFM_Populate_Class) then
			if (Karma_Executing_Command) then
				KarmaChatDefault(KARMA_MSG_COMMANDQUEUE_FULL1 .. KARMA_WINEL_FRAG_COLONSPACE .. #Karma_CommandQueue .. KARMA_MSG_COMMANDQUEUE_FULL2);
			else
				if (KarmaModuleLocal.LFM_Populate_Class < 100) then
					local	args = {};
					args[2] = KOH.IDToClass(KarmaModuleLocal.LFM_Populate_Class);
					args[3] = levelrange;
					KarmaObj.Slash.CheckClassOnline(args);
				else
					local	args = {};
					args[2] = levelrange;
					args[3] = KarmaModuleLocal.LFM_Populate_Class - 100;
					KarmaObj.Slash.CheckAllClassesOnline(args);
				end

				KarmaWindow2_PopulateWindow_Class_Checkbox:SetChecked(0);
				-- UIDropDownMenu_SetSelectedID(KarmaWindow2_PopulateWindow_Class_DropDown, 0);
				-- UIDropDownMenu_SetText(KarmaWindow2_PopulateWindow_Class_DropDown, "");
			end
		end
	elseif (KarmaWindow2_PopulateWindow_Classes_Checkbox:GetChecked() == 1) then
		-- checkallclasses: if yes, then last if no command is running
		if (Karma_Executing_Command) then
			KarmaChatDefault(KARMA_MSG_COMMANDQUEUE_FULL1 .. KARMA_WINEL_FRAG_COLONSPACE .. #Karma_CommandQueue .. KARMA_MSG_COMMANDQUEUE_FULL2);
		else
			local	args = {};
			args[2] = levelrange;
			KarmaObj.Slash.CheckAllClassesOnline(args);
			KarmaWindow2_PopulateWindow_Classes_Checkbox:SetChecked(0);
		end
	elseif (KarmaWindow2_PopulateWindow_Guild_Checkbox:GetChecked()) then
		local	guildname = KarmaWindow2_PopulateWindow_Guild_Editbox:GetText();
		if (guildname) and (guildname ~= "") then
			if (Karma_Executing_Command) then
				KarmaChatDefault(KARMA_MSG_COMMANDQUEUE_FULL1 .. KARMA_WINEL_FRAG_COLONSPACE .. #Karma_CommandQueue .. KARMA_MSG_COMMANDQUEUE_FULL2);
			else
				local	args = {};
				args[1] = "checkguild";
				args[2] = guildname;
				Karma_SlashCheckGuild(args);

				KarmaWindow2_PopulateWindow_Guild_Checkbox:SetChecked(0);
			end
		end
	end
KarmaChatDebug("<< KarmaWindow2_PopulateWindow_Execute");
end

function	KarmaWindow2_Message_EditBox_Tooltip(self, motion)
	if Karma_ShowTooltipHelp() then
		GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT");
		GameTooltip:AddLine(KARMAAVENK_LOCUI_MODLFM[KARMAAVENK_LOCUI_MODLFM["DEFAULT"]].MESSAGE_TO_SEND_TOOLTIP, 1, 1, 1);
		GameTooltip:Show();
	end
end

function	KarmaWindow2_SendMessage_OnEnter(self, motion)
	if Karma_ShowTooltipHelp() then
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
		GameTooltip:AddLine(KARMAAVENK_LOCUI_MODLFM[KARMAAVENK_LOCUI_MODLFM["DEFAULT"]].SENDMESS_TOOLTIP, 1, 1, 1);
		GameTooltip:Show();
	end
end

function	KarmaWindow2_SentMessage_OnEnter(self, motion)
	if Karma_ShowTooltipHelp() then
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
		GameTooltip:AddLine(KARMAAVENK_LOCUI_MODLFM[KARMAAVENK_LOCUI_MODLFM["DEFAULT"]].SENTMESS_TOOLTIP, 1, 1, 1);
		GameTooltip:Show();
	end
end

function	KarmaWindow2_PositiveReply_OnEnter(self, motion)
	if Karma_ShowTooltipHelp() then
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
		GameTooltip:AddLine(KARMAAVENK_LOCUI_MODLFM[KARMAAVENK_LOCUI_MODLFM["DEFAULT"]].POSREPLY_TOOLTIP, 1, 1, 1);
		GameTooltip:Show();
	end
end

function	KarmaWindow2_SentMessage(entry)
	if (KARMA_Online.PlayersAll[entry.target].sendmess == 1) then
		KARMA_Online.PlayersAll[entry.target].sendmess = nil;
		KARMA_Online.PlayersAll[entry.target].sentmess = 1;

		KarmaWindow2_UpdateList2();
	end
end

function	KarmaWindow2_Invite()
	local	sMembername, Dummy;
	for sMembername, Dummy in pairs(KARMA_Online.PlayersChosen) do
		if (KARMA_Online.PlayersAll[sMembername].posreply == 1) then
			InviteUnit(sMembername);
		end
	end
end

function	KarmaWindow2_QueryNotesPub()
	local	sPlayername, Dummy, sQueued, iCount;
	sQueued = "";
	iCount = 0;
	for sPlayername, Dummy in pairs(KARMA_Online.PlayersChosen) do
		if (KARMA_Online.PlayersAll[sPlayername].queried ~= 1) then
			Karma_QueueCommandShareQuery(sPlayername);
			KARMA_Online.PlayersAll[sPlayername].queried = 1;
			sQueued = sQueued .. " " .. sPlayername;
			iCount = iCount + 1;
		end
	end

	KarmaChatSecondaryFallbackDefault("Queued sharedquery-requests for:" .. sQueued .. " (" .. iCount .. " total).");
end

function	KarmaWindow2_SendMessage()
	local	iCnt = KarmaObj.MessageQueueLen();
	if (iCnt > 0) then
		KarmaChatDefault("There are still messages queued to be sent. Please wait until the current batch is out...");
		return
	end

	local	sMembername, Dummy, Text, iPos;
	Text = KarmaWindow2_Message_EditBox:GetText();
	iPos = strfind(Text, "%%");
	if (Text) and (Text ~= "") then
		for sMembername, Dummy in pairs(KARMA_Online.PlayersChosen) do
			local	oOnline = KARMA_Online.PlayersAll[sMembername];
			if (oOnline.sendmess == 1) then
				local	entry = {};
				entry.func = KarmaWindow2_SentMessage;
				entry.chattype = "WHISPER";
				if (oOnline.alt == true) then
					entry.target = oOnline.main;
				else
					entry.target = sMembername;
				end
				if (iPos) then
					-- replace %t with telltarget, %a with alt name
					entry.text = string.gsub(Text, "%%t", entry.target);
					if (oOnline.alt) then
						entry.text = string.gsub(Text, "%%a", sMembername);
					end
				else
					entry.text = Text;
				end

				KarmaObj.MessageQueueAdd(entry);
			end
		end
	end
end

function	KarmaWindow2_SendMessage_OnClick(button, buttonobject)
	local	id = buttonobject:GetID();
	local	button = getglobal("KarmaWindow2_List2_Name" .. id .. "_Text");
	local	sMembername = button:GetText();
	if (sMembername ~= nil) and (sMembername ~= "") then
		if (KARMA_Online.PlayersAll[sMembername]) then
			local	CheckBoxObj = getglobal("KarmaWindow2_List2_SendMessage" .. id);
			if (CheckBoxObj:GetChecked()) then
				KARMA_Online.PlayersAll[sMembername].sendmess = 1;
			else
				KARMA_Online.PlayersAll[sMembername].sendmess = nil;
			end
		end
	end
end

function	KarmaWindow2_PositiveReply_OnClick(button, buttonobject)
	local	id = buttonobject:GetID();
	local	button = getglobal("KarmaWindow2_List2_Name"..id.."_Text");
	local	sMembername = button:GetText();
	if (sMembername ~= nil) and (sMembername ~= "") then
		if (KARMA_Online.PlayersAll[sMembername]) then
			local	CheckBoxObj = getglobal("KarmaWindow2_List2_PositiveReply" .. id);
			if (CheckBoxObj:GetChecked()) then
				KARMA_Online.PlayersAll[sMembername].posreply = 1;
			else
				KARMA_Online.PlayersAll[sMembername].posreply = nil;
			end
		end
	end
end

function	KarmaWindow_List1_OnClick(buttonobject, mousebutton)
	local	id = buttonobject:GetID();
	local	button = getglobal("KarmaWindow2_List1_Name"..id.."_Text");
	local	sMembername = button.Membername;
	if (sMembername ~= nil) and (sMembername ~= "") then
		if (mousebutton == "LeftButton") then
			if (KARMA_Online.PlayersChosen[sMembername] == nil) then
				KARMA_Online.PlayersChosen[sMembername] = 1;

				KarmaWindow2_UpdateList2();
			end
		elseif (mousebutton == "MiddleButton") then
			Karma_UpdateMember(sMembername, true);
		elseif (mousebutton == "RightButton") then
			local	oMember = Karma_MemberList_GetObject(sMembername);
			if (oMember) then
				Karma_MemberConflict_Menu.Caller = buttonobject:GetName();
				Karma_MemberConflict_Menu.Member = sMembername;
				ToggleDropDownMenu(1, nil, Karma_MemberConflict_Menu, buttonobject, 0, 0);
			end
		end
	end
end

function	KarmaWindow_List2_OnClick(buttonobject, mousebutton)
	local	id = buttonobject:GetID();
	local	button = getglobal("KarmaWindow2_List2_Name"..id.."_Text");
	local	sMembername = button.Membername;
	if (sMembername ~= nil) and (sMembername ~= "") then
		if (mousebutton == "LeftButton") then
			KARMA_Online.PlayersChosen[sMembername] = nil;
			KarmaWindow2_UpdateList2();
		elseif (mousebutton == "RightButton") then
			local	oMember = Karma_MemberList_GetObject(sMembername);
			if (oMember) then
				Karma_MemberConflict_Menu.Caller = buttonobject:GetName();
				Karma_MemberConflict_Menu.Member = sMembername;
				ToggleDropDownMenu(1, nil, Karma_MemberConflict_Menu, buttonobject, 0, 0);
			end
		end
	end
end

function	KarmaWindow_List1_OnEnter(self, motion)
	local	id = self:GetID();
	local	button = getglobal("KarmaWindow2_List1_Name"..id.."_Text");
	local	sName = button.Membername;
	if (sName ~= nil and sName ~= "" and sName ~= KARMA_UNKNOWN and sName ~= KARMA_UNKNOWN_ENT) then
		if (KARMA_Online.PlayersAll[sName]) then
			GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
			if (KARMA_Online.PlayersAll[sName].zone) then
				GameTooltip:AddLine(KARMA_Online.PlayersAll[sName].zone, 1, 1, 1);
			end

			local	bGotGuild;
			if (KARMA_Online.PlayersAll[sName].guild) and (KARMA_Online.PlayersAll[sName].guild ~= "") then
				bGotGuild = true;
			end

			if (KARMA_Online.PlayersAll[sName].lfg and
			    (time() - KARMA_Online.PlayersAll[sName].lfg < 300)) then
				local	sec = time() - KARMA_Online.PlayersAll[sName].lfg;
				local	min = math.floor(sec / 60);
				sec = sec % 60;
				if (sec < 10) then
					sec = "0" .. sec;
				end
				GameTooltip:AddLine("|cFF40FF40" .. KARMA_CHANNELNAME_LFG .. "|r less than " .. min .. ":" .. sec .. " ago", 1, 1, 1);
			end

			local	oMember = Karma_MemberList_GetObject(sName);
			if (oMember) then
				if	(oMember[KARMA_DB_L5_RRFFM_CONFLICT] ~= nil) and
					(oMember[KARMA_DB_L5_RRFFM_CONFLICT].Resolved == 0) then
					GameTooltip:AddLine("CONFLICT: " .. oMember[KARMA_DB_L5_RRFFM_CONFLICT].Conflict, 1, 0, 0);
				end

				local	iKarma, bModified = Karma_MemberObject_GetKarmaModified(oMember);
				if (bModified) then
					local	red, green, blue = Karma_Karma2Color(iKarma);
					GameTooltip:AddLine(KARMA_ITSELF .. KARMA_WINEL_FRAG_COLONSPACE .. Karma_MemberObject_GetKarmaWithModifiers(oMember), red, green, blue);
				end

				if (bGotGuild) then
					GameTooltip:AddLine("<" .. KARMA_Online.PlayersAll[sName].guild .. ">", 1, 1, 1);
				else
					local	Guild = Karma_MemberObject_GetGuild(oMember);
					if (Guild) and (Guild ~= "") then
						GameTooltip:AddLine("<" .. Guild .. ">", 1, 1, 1);
					end
				end

				local	altid = Karma_MemberObject_GetAltID(oMember);
				if (altid ~= -1) then
					local	sAlts = Karma_AltID2Names(altid, 5, KARMA_MSG_LFM_LIST1TIP_ALTS .. KARMA_WINEL_FRAG_COLONSPACE);
					if (sAlts) and (sAlts ~= "") then
						GameTooltip:AddLine(sAlts, 0.8, 1, 1);
					end
				end

				if (KCfg.Get("TOOLTIP_TALENTS") == 1) then
					local	oLines, sSummarySub, iTimeOfTalents = KarmaObj.Talents.MemberObjToStringsObj(oMember, bShiftPressed);

					local	i;
					for i = 1, #oLines do
						if (iTimeOfTalents) then
							GameTooltip:AddLine("Talents as of " .. date(KARMA_DATEFORMAT, iTimeOfTalents) .. ":", 1, 1, 1);
							iTimeOfTalents = nil;
						end
						GameTooltip:AddLine(oLines[i], 1, 1, 1);
					end
				end

				local	sNote = Karma_MemberObject_GetNotes(oMember);
				if (sNote) and (sNote ~= "") then
					GameTooltip:AddLine("-------------------------", 1, 1, 0);
					local	sExtract = KOH.ExtractHeader(sNote);
					GameTooltip:AddLine(sExtract, 0.7, 0.9, 0.7, 1);
				end
			elseif (bGotGuild) then
				GameTooltip:AddLine("<" .. KARMA_Online.PlayersAll[sName].guild .. ">", 1, 1, 1);
			end

			GameTooltip:Show();
		end
	end
end

function	KarmaWindow_List2_OnEnter(self, motion)
	local	id = self:GetID();
	local	button = getglobal("KarmaWindow2_List2_Name"..id.."_Text");
	local	sName = button.Membername;
	if (sName ~= nil and sName ~= "" and sName ~= KARMA_UNKNOWN and sName ~= KARMA_UNKNOWN_ENT) then
		local	oNotes = KarmaObj.UI.NotesPublic.Get(sName);
		if (KARMA_Online.PlayersAll[sName]) and
			(KARMA_Online.PlayersAll[sName].zone or KARMA_Online.PlayersAll[sName].guild or oNotes) then
			GameTooltip:SetOwner(self, "ANCHOR_RIGHT");

			if (KARMA_Online.PlayersAll[sName].zone) then
				GameTooltip:AddLine(KARMA_Online.PlayersAll[sName].zone, 1, 1, 1);
			end
			if (KARMA_Online.PlayersAll[sName].guild) and (KARMA_Online.PlayersAll[sName].guild ~= "") then
				GameTooltip:AddLine("<" .. KARMA_Online.PlayersAll[sName].guild .. ">", 1, 1, 1);
			end

			if (oNotes ~= nil) then
				local	sFrom, aStance;
				for sFrom, aStance in pairs(oNotes) do
					local	sFromOut = sFrom;
					local	red, green, blue = Karma_GetColors_Karma(sFrom);
					if (red + green + blue < 2.95) then
						sFromOut = format("|cFF%02x%02x%02x%s|r", blue, green, red, sFrom);
					end

					local	sLine = sFromOut .. " says:";
					if (aStance.sKarma) then
						sLine = sLine .. " [" .. aStance.sKarma .. "]";
					end
					if (aStance.sNotePub) then
						sLine = sLine .. " => <<" .. aStance.sNotePub .. ">>";
					end
					GameTooltip:AddLine(sLine, 1, 1, 1);
				end
			else
				GameTooltip:AddLine("No information available.");
			end

			GameTooltip:Show();
		end
	end
end

local	Karma_ClassToBucket =
	{
		-- reordered: healer, healer/tank, tank, dps
		[  5 ] =  1;	-- priest
		[  7 ] =  2;	-- shaman
		[  1 ] =  3;	-- druid
		[ 11 ] =  4;	-- monk
		[  4 ] =  5;	-- paladin
		[  8 ] =  6;	-- warrior
		[ 10 ] =  7;	-- deathknight
		[  6 ] =  8;	-- rogue
		[  3 ] =  9;	-- mage
		[  9 ] = 10;	-- warlock
		[  2 ] = 11;	-- hunter
	};

function	KARMA_OnlinePlayersAll_Sort(lMemberNames)
	-- two big buckets:
		-- with Karma
		-- without Karma
	local	PlayersWKarma = {};
	local	PlayersWOKarma = {};

	-- interspersed special buckets
	local	iBucketUnknownWOClass = #Karma_ClassToBucket + 1;
	local	iBucketKnownWORole = #Karma_ClassToBucket + 4;
	local	iBucketKnownDPS = #Karma_ClassToBucket - 2;

	-- Karma bucket:
		-- bucket 1: HPS
		-- bucket 2: TANK, FERAL
		-- bucket 9: DPS
		-- bucket 3-8, 10-13: Karma_ClassToBucket
		-- bucket 14: w/o class
		-- Pandaria: monk added at #9, => 10: DPS, 11-14 C2B DPS, 15 w/o class
	local	iCount;
	for iCount = 1, #Karma_ClassToBucket + 4 do
		PlayersWKarma[iCount] = {};
	end

	-- non-Karma bucket:
		-- bucket 1-10: Karma_ClassToBucket
		-- bucket 11: w/o class
		-- Pandaria: monk added at #6, 12 w/o class
	local	iCount;
	for iCount = 1, iBucketUnknownWOClass do
		PlayersWOKarma[iCount] = {};
	end

	local	iBucketUnknownWOClass = #Karma_ClassToBucket + 1;
	local	iBucketKnownWORole = #Karma_ClassToBucket + 4;
	local	iBucketKnownDPS = #Karma_ClassToBucket - 2;

	Karma_WhoAmIInit();

	local	key, value, classbucket, bucket, iSpec, iClass, sClass, iShift, iDelta, iLevel;
	local	aTalents = {};
	for key, value in pairs(lMemberNames) do
		if (value == WhoAmI) then
			lMemberNames[key] = nil;
		else
			local	oMember = Karma_MemberList_GetObject(value);
			if (oMember) then
				iShift = 1;
				iDelta = 2;
				local	bPattern;
				for iSpec = 1, KarmaObj.Talents.SpecCount do
					aTalents["S_" .. iSpec], bPattern = Karma_MemberObject_GetTalentID(oMember, iSpec);
					if (bPattern) then
						local	iDerived = KarmaObj.Talents.MemberObjSpecNumToTalent(oMember, iSpec);
						if (iDerived) then
							aTalents["S_" .. iSpec] = iDerived;
						end
					end
				end
				for iSpec = KarmaObj.Talents.SpecCount, 2, -1 do
					if (aTalents["S_" .. iSpec] == aTalents["S_1"]) then
						aTalents["S_" .. iSpec] = nil;
					end
				end
				iLevel = Karma_MemberObject_GetLevel(oMember);
				-- forceupdate'd member? -> don't lose because of level -> 0...
				if (iLevel == 0) then
					iLevel = nil;
				end
				sClass = Karma_MemberObject_GetClass(oMember);
				iClass = KOH.ClassToID(sClass);
			else
				iShift = 0;
				iDelta = 0;
				iTalent = nil;
				iTalentRaw = nil;
				iLevel = KARMA_Online.PlayersAll[value].level;
				sClass = KARMA_Online.PlayersAll[value].class;
				iClass = KOH.ClassToID(sClass);
			end

			bucket = iBucketUnknownWOClass;
			if (oMember) then
				for iSpec = 1, KarmaObj.Talents.SpecCount do
					local	iTalent = aTalents["S_" .. iSpec];
					if (iTalent) and (iTalent ~= 0) then
						iTalent = bit.band(iTalent, 7);
						if (iTalent ~= 0) then
							if (bit.band(iTalent, 1) == 1) then
								-- HPS: -1 (1)
								if (bucket) then
									bucket = math.min(bucket, -1);
								else
									bucket = -1;
								end
							elseif (bit.band(iTalent, 2) == 2) then
								-- TANK/FERAL: 0 (2)
								if (bucket) then
									bucket = math.min(bucket, 0);
								else
									bucket = 0;
								end
							elseif (bit.band(iTalent, 4) == 4) then
								-- DPS: 7 (9) -- Pandaria: 8 (10)
								if (bucket) then
									bucket = math.min(bucket, iBucketKnownDPS);
								else
									bucket = iBucketKnownDPS;
								end
							end
						end
-- KarmaChatDebug(Karma_MemberObject_GetName(oMember) .. ".Talent[" .. iSpec .. "] = " .. iTalent);	-- ###
					end
				end
			end

			classbucket = nil;
			if (iClass) and (iClass ~= 0) then
				if (iClass < 0) then
					iClass = - iClass;
				end

				if (Karma_ClassToBucket[iClass]) then
					classbucket = Karma_ClassToBucket[iClass];

					if ((bucket == iBucketUnknownWOClass) or
					    (bucket == iBucketKnownDPS) and (classbucket > iBucketKnownDPS)) then
						bucket = classbucket;
						if (bucket >= iBucketKnownDPS) then
							bucket = bucket + iShift;
						end
					end
				end
			end

			local	bAdd = true;
			if (iLevel) and (KARMA_Online.PlayersAllFilter.LevelFrom) and (KARMA_Online.PlayersAllFilter.LevelTo) then
				if (iLevel < KARMA_Online.PlayersAllFilter.LevelFrom) or (iLevel > KARMA_Online.PlayersAllFilter.LevelTo) then
					bAdd = false;
				end
			end

			if (bAdd) and (oMember) then
				if (KARMA_Online.PlayersAllFilter.minKarma) then
					local	iKarma = KarmaObj.DB.M.KarmaGet(oMember);
					if (iKarma) and (iKarma > 0) then
						if (iKarma < KARMA_Online.PlayersAllFilter.minKarma) then
							bAdd = false;
						end
					end
				end

				if (bAdd) and (KARMA_Online.PlayersAllFilter.minSkill) then
					local	iSkill = Karma_MemberObject_GetSkill(oMember);
					if (iSkill) and (iSkill >= 0) then
						if (iSkill < KARMA_Online.PlayersAllFilter.minSkill) then
							bAdd = false;
						end
					end
				end
			end

			if (bAdd) and (oMember) then
				if (bucket == -1) and (KARMA_Online.PlayersAllFilter.TalentHPS ~= 1) then
					bAdd = false;
				elseif (bucket == 0) and (KARMA_Online.PlayersAllFilter.TalentTANK ~= 1) then
					bAdd = false;
				elseif (bucket == 7) and (KARMA_Online.PlayersAllFilter.TalentDPS ~= 1) then
					bAdd = false;
				end
			end

			if (bAdd) and (iClass) and (classbucket) then
				-- some classes cannot be HPS, DPS, TANK...
				-- KARMA_TALENT_CLASSMASK sums the total of each class
				local	classmask = KARMA_TALENT_CLASSMASK[iClass];
				local	role, distance = 0, 0;
				for iSpec = 1, KarmaObj.Talents.SpecCount do
					local	iTalent = aTalents["S_" .. iSpec];
					if (iTalent) and (iTalent ~= 0) then
						role     = bit.bor(role,     bit.band(iTalent,  7));
						distance = bit.bor(distance, bit.band(iTalent, 24));
					end
				end
				if (role == 0) then
					role = bit.band(classmask, 7);
				end
				if (distance == 0) then
					distance = bit.band(classmask, 24);
				end

				local	choicemask = 0;
				if (KARMA_Online.PlayersAllFilter.TalentHPS == 1) then
					choicemask = choicemask + 1;
				end
				if (KARMA_Online.PlayersAllFilter.TalentTANK == 1) then
					choicemask = choicemask + 2;
				end
				if (KARMA_Online.PlayersAllFilter.TalentDPS == 1) then
					choicemask = choicemask + 4;
				end
				if (bit.band(role, choicemask) == 0) then
					bAdd = false;
				end

				choicemask = 0;
				if (KARMA_Online.PlayersAllFilter.TalentMelee == 1) then
					choicemask = choicemask + 8;
				end
				if (KARMA_Online.PlayersAllFilter.TalentRange == 1) then
					choicemask = choicemask + 16;
				end
				if (bit.band(distance, choicemask) == 0) then
					bAdd = false;
				end
			end

			if (bAdd) and (iClass) and (classbucket) then
				if (iClass == 1) and (KARMA_Online.PlayersAllFilter.ClassDruid ~= 1) then
					bAdd = false;
				elseif (iClass == 2) and (KARMA_Online.PlayersAllFilter.ClassHunter ~= 1) then
					bAdd = false;
				elseif (iClass == 3) and (KARMA_Online.PlayersAllFilter.ClassMage ~= 1) then
					bAdd = false;
				elseif (iClass == 4) and (KARMA_Online.PlayersAllFilter.ClassPaladin ~= 1) then
					bAdd = false;
				elseif (iClass == 5) and (KARMA_Online.PlayersAllFilter.ClassPriest ~= 1) then
					bAdd = false;
				elseif (iClass == 6) and (KARMA_Online.PlayersAllFilter.ClassRogue ~= 1) then
					bAdd = false;
				elseif (iClass == 7) and (KARMA_Online.PlayersAllFilter.ClassShaman ~= 1) then
					bAdd = false;
				elseif (iClass == 8) and (KARMA_Online.PlayersAllFilter.ClassWarrior ~= 1) then
					bAdd = false;
				elseif (iClass == 9) and (KARMA_Online.PlayersAllFilter.ClassWarlock ~= 1) then
					bAdd = false;
				elseif (iClass == 10) and (KARMA_Online.PlayersAllFilter.ClassDeathknight ~= 1) then
					bAdd = false;
				elseif (iClass == 11) and (KARMA_Online.PlayersAllFilter.ClassMonk ~= 1) then
					bAdd = false;
				end
			end

			if (bAdd) then
				if (oMember) then
					if (PlayersWKarma[bucket + 2]) then
						tinsert(PlayersWKarma[bucket + 2], value);
-- KarmaChatDebug("player " .. value .. " => bucket " .. bucket);
					else
						KarmaChatDebug("Failed to add " .. value .. ", selected bucket " .. bucket .. " is invalid.");
					end
				else
					if (PlayersWOKarma[bucket]) then
						tinsert(PlayersWOKarma[bucket], value);
					else
						KarmaChatDebug("Failed to add " .. value .. ", selected bucket " .. bucket .. " is invalid.");
					end
				end
			end
		end
	end

	local	SkipClassLess;
	if (KARMA_Online.PlayersAllFilter.ClassKnown == 1) then
		SkipClassLess = 1;
	else
		SkipClassLess = 0;
	end

	local	timecurrent = time();

	local	iOnline = 0;
	local	Result = {};
	local	Result2 = {};

	for iCount = 1, (14 - SkipClassLess) do
		for key, value in pairs(PlayersWKarma[iCount]) do
			local	bLFG   = ((KARMA_Online.PlayersAll[value].lfg ~= nil) and
					  (timecurrent - KARMA_Online.PlayersAll[value].lfg < 300));
			if (bLFG) then
				iOnline = iOnline + 1;
				tinsert(Result, value);
			else
				tinsert(Result2, value);
			end
		end
	end

	local	iOfflineCount = #Result2;
	for iCount = 1, iOfflineCount do
		tinsert(Result, Result2[iCount]);
	end
	table.wipe(Result2);

	if (KARMA_Online.PlayersAllFilter.KarmaReq ~= 1) then
		for iCount = 1, (11 - SkipClassLess) do
			for key, value in pairs(PlayersWOKarma[iCount]) do
				local	bLFG   = ((KARMA_Online.PlayersAll[value].lfg ~= nil) and
						  (timecurrent - KARMA_Online.PlayersAll[value].lfg < 300));
				if (bLFG) then
					iOnline = iOnline + 1;
					tinsert(Result, value);
				else
					tinsert(Result2, value);
				end
			end
		end
	end

	local	iOfflineCount = #Result2;
	for iCount = 1, iOfflineCount do
		tinsert(Result, Result2[iCount]);
	end
	Result2 = nil;

	return Result, iOnline;
end

local	RegionnamesToRegionIDs = {};

local	function	UpdateRegions()
	-- KARMA_Online.PlayersAll[sMembername].zone: add RegionID field
	local	RegionList = KarmaObj.DB.CG.RegionListGet();
	local	key, value, subkey, subvalue;
	for key, value in pairs(KARMA_Online.PlayersAll) do
		if (value.zone ~= nil) and (value.RegionID == nil) then
			if (RegionnamesToRegionIDs[value.zone] ~= nil) then
				value.RegionID = RegionnamesToRegionIDs[value.zone];
			else
				for subkey, subvalue in pairs(RegionList) do
					if (subvalue.Name == value.zone) then
						value.RegionID = subkey;
					end
				end

				RegionnamesToRegionIDs[value.zone] = value.RegionID;
			end
		end
	end
end

function	KarmaWindow2_UpdateList(which)
	KarmaObj.ProfileStart("KarmaWindow2_UpdateList");

	local	timecurrent = time();

	local	MemberNames;
	local	key, value;

	local	ListSize, ScrollFrame;
	if (which == "KarmaWindow2_List1_") then
		ListSize = KARMA_LFGWND_LIST1_SIZE;
		ScrollFrame = KarmaWindow2_List1_ScrollFrame;
	else
		ListSize = KARMA_LFGWND_LIST2_SIZE;
		ScrollFrame = KarmaWindow2_List2_ScrollFrame;
	end

	if (which == "KarmaWindow2_List1_") then
		-- delete entries over 60m (once per minute)
		if (KARMA_Online.PlayersAllCache.List1_Clean == nil) then
			KARMA_Online.PlayersAllCache.List1_Clean = timecurrent;
		elseif (timecurrent - KARMA_Online.PlayersAllCache.List1_Clean > 60) then
			local	bUpdate;
			for key, value in pairs(KARMA_Online.PlayersAll) do
				-- only if not selected...
				if (KARMA_Online.PlayersChosen[key] == nil) then
					-- ... and age > 60m
					if (timecurrent - value.time > 3600) then
						KARMA_Online.PlayersAll[key] = nil;
						bUpdate = true;
					end
				end

				if ((value.lfg ~= nil) and (timecurrent - value.lfg > 300)) then
					value.lfg = nil;
					bUpdate = true;
				end
			end
			-- request cache update
			if (bUpdate) then
				KARMA_Online.PlayersVersion = KARMA_Online.PlayersVersion + 1;
			end
		end

		if (KARMA_Online.PlayersVersion ~= KARMA_Online.PlayersAllCache.Version) then
			UpdateRegions();

			KARMA_Online.PlayersAllCache.Version = Version;
			KARMA_Online.PlayersAllCache.List1_Raw = {};
			KARMA_Online.PlayersAllCache.List1_Srt = {};

			local	AltsObj;
			if (KARMA_Online.PlayersAllFilter.Alts) then
				AltsObj = KarmaObj.DB.FactionCacheGet()[KARMA_DB_L4_RRFF.ALTGROUPS];
			end
			local	oRemove, oAdd = {}, {};
			for key, value in pairs(KARMA_Online.PlayersAll) do
				if (value.alt) then
					if (AltsObj == nil) then
						tinsert(oRemove, key);
					end
				else
					-- KarmaChatDebug("MemberNames += " .. key);
					tinsert(KARMA_Online.PlayersAllCache.List1_Raw, key);
					if (AltsObj) then
						local	oMember = Karma_MemberList_GetObject(key);
						if (oMember) then
							local	altid = Karma_MemberObject_GetAltID(oMember);
							if (altid ~= -1) then
								local	key1, value1;
								for key1, value1 in pairs(AltsObj) do
									if (value1.ID == altid) then
										local	key2, value2;
										for key2, value2 in pairs(value1.AL) do
											if (value2 ~= key) then
												tinsert(KARMA_Online.PlayersAllCache.List1_Raw, value2);
												oAdd[value2] = { main = key, alt = true, time = value.time, zone = value.zone };
											end
										end

										break;
									end
								end
							end
						end
					end
				end
			end
			for key, value in pairs(oRemove) do
				KARMA_Online.PlayersAll[key] = nil;
			end
			for key, value in pairs(oAdd) do
				if (KARMA_Online.PlayersAll[key] == nil) then
					KARMA_Online.PlayersAll[key] = value;
				end
			end

			MemberNames = Karma_CopyTable(KARMA_Online.PlayersAllCache.List1_Raw);

			-- pre-sort alphabetically, then into special sort into buckets
			MemberNames = KOH.AlphaBucketSort(MemberNames);
			MemberNames, KARMA_Online.PlayersOnlineCount = KARMA_OnlinePlayersAll_Sort(MemberNames);

			KARMA_Online.PlayersAllCache.List1_Srt = Karma_CopyTable(MemberNames);
		else
			MemberNames = KARMA_Online.PlayersAllCache.List1_Srt;
		end
	else
		MemberNames = {};
		for key, value in pairs(KARMA_Online.PlayersChosen) do
			-- KarmaChatDebug("MemberNames += " .. key);
			tinsert(MemberNames, key);
		end

		-- pre-sort alphabetically, then into special sort into buckets
		MemberNames = KOH.AlphaBucketSort(MemberNames);
		MemberNames = KARMA_OnlinePlayersAll_Sort(MemberNames);
	end

	local	i = 0;
	for key, value in pairs(MemberNames) do
		i = i + 1;
	end
	local	iNumEntries = i;

	if (which == "KarmaWindow2_List1_") then
		KARMA_Online.PlayersTotalCount = iNumEntries;
	else
		KARMA_Online.PlayersSelectedCount = iNumEntries;
	end

	do
		local	oTitleList2 = KarmaWindow2_List2_Title;
		local	sPrefix = oTitleList2.LocalizationValue or oTitleList2:GetText() or "";
		local	sText = (KARMA_Online.PlayersSelectedCount or 0)
				.. " / " .. (KARMA_Online.PlayersTotalCount or "?")
				.. " |cFF00FF00(" .. (KARMA_Online.PlayersOnlineCount or 0) .. " in a city recently)|r";
		oTitleList2:SetText(sPrefix .. KARMA_WINEL_FRAG_COLONSPACE.. sText);
	end

-- KarmaChatDebug("KarmaWindow2_UpdateList(" .. which .. "): " .. tostring(iNumEntries) .. " entries.");

	-- clear all buttons from current values:
	local	oTalentBtn = { [1] = "L", [2] = "R" };
	local	buttontext, k;
	for i = 1, ListSize do
		buttontext = getglobal(which .. "Online"..i.."_Text");
		buttontext:SetText("");
		buttontext = getglobal(which .. "KarmaValue"..i.."_Text");
		buttontext:SetText("");
		buttontext = getglobal(which .. "Name"..i.."_Text");
		buttontext:SetText("");
		buttontext.Membername = nil;
		buttontext = getglobal(which .. "ClassLvl"..i.."_Text");
		buttontext:SetText("");
		for k = 1, 2 do
			buttontext = getglobal(which .. "Talent" .. i .. "_Text" .. oTalentBtn[k]);
			buttontext:SetText("");
			buttontext = getglobal(which .. "Talent" .. i .. "_Icon" .. oTalentBtn[k]);
			buttontext:SetTexture("");
		end
		buttontext = getglobal(which .. "Talent" .. i .. "_TextWide");
		buttontext:SetText("");
		buttontext = getglobal(which .. "Location"..i.."_Text");
		buttontext:SetText("");

		if (which == "KarmaWindow2_List2_") then
			buttontext = getglobal(which .. "SendMessage"..i);
			buttontext:SetChecked(0);
			buttontext = getglobal(which .. "SentMessage"..i);
			buttontext:SetChecked(0);
			buttontext = getglobal(which .. "PositiveReply"..i);
			buttontext:SetChecked(0);
		end
	end

	local	RegionList = KarmaObj.DB.CG.RegionListGet();

	local	iCounter = 1;
	local	nindex = 1;
	local	oMember, sClass, iClass, iSpec, iTalents, sTalents;
	local	timediff, minutes, seconds;
	local	red, green, blue;
	local	iSpecCount = math.min(KarmaObj.Talents.SpecCount, 2);
	for key, sMembername in pairs(MemberNames) do
		--search the index of the array for the current users name
		if (nindex - FauxScrollFrame_GetOffset(ScrollFrame)  >= 0) then
			if (iCounter <= ListSize) then
				timediff = timecurrent - KARMA_Online.PlayersAll[sMembername].time;
				minutes = floor(timediff / 60);
				seconds = timediff - (minutes * 60);
				if (seconds < 10) then
					seconds = "0".. tostring(seconds);
				end
				local checktime;
				if (timediff >= 600) then
					checktime = tostring(minutes) .. "m";
				else
					checktime = tostring(minutes) .. ":" .. tostring(seconds);
				end
				if (KARMA_Online.PlayersAll[sMembername].lfg and
				    (timecurrent - KARMA_Online.PlayersAll[sMembername].lfg < 300)) then
					checktime = "|cFF40FF40" .. checktime .. "|r";
				end

				buttontext = getglobal(which .. "Online" .. iCounter .. "_Text");
				buttontext:SetText(checktime);

				local	zonetext = getglobal(which .. "Location"..iCounter.."_Text");
				if (KARMA_Online.PlayersAll[sMembername].zone) then
					local	Color = "|cFFA0A0A0";
					local	RegionID = KARMA_Online.PlayersAll[sMembername].RegionID;
					if (RegionID ~= nil) and (RegionList[RegionID] ~= nil) then
						local	bPvp = RegionList[RegionID][KARMA_DB_L3_CR.ISPVPZONE];
						local	iInstance = RegionList[RegionID][KARMA_DB_L3_CR.ZONETYPE];
						if (bPvp) or (iInstance == 1) then
							Color = "|cFFFF4040";				-- red
						elseif (iInstance) then
							if (iInstance == 0) then
								Color = "|cFFFFFF00";			-- yellow
							elseif (iInstance == 5) then
								Color = "|cFF00FFFF";			-- turquoise
							elseif (iInstance == 10) then
								Color = "|cFF6060FF";			-- blue
							elseif (iInstance == 25) then
								Color = "|cFFFF00FF";			-- purple
							end
						end
					end

					if (which == "KarmaWindow2_List1_") then
						zonetext:SetText(Color .. KARMA_Online.PlayersAll[sMembername].zone .. "|r");
					else
						-- cut down, don't want it to creep under the checkboxes
						zonetext:SetText(Color .. strsub(KARMA_Online.PlayersAll[sMembername].zone, 1, 12) .. "|r");
					end
				end

				local	nametext = getglobal(which .. "Name" .. iCounter .. "_Text");
				nametext:SetText(sMembername);
				nametext.Membername = sMembername;
				if (KARMA_Online.PlayersAllFilter.Alts) then
					if (KARMA_Online.PlayersAll[sMembername].alt) then
						nametext:SetText("(" .. sMembername .. ")");
						local	zone = zonetext:GetText() or "<place unknown>";
						zonetext:SetText("Main: " .. KARMA_Online.PlayersAll[sMembername].main .. " >> " .. zone);
					end
				end

				local	bTalent = false;

				oMember = Karma_MemberList_GetObject(sMembername);
				if (oMember == nil) then
					sClass = KARMA_Online.PlayersAll[sMembername].class;
					if (KARMA_Online.PlayersAll[sMembername].class) then
						iClass = KOH.ClassToID(sClass);
						if (iClass < 0) then
							iClass = - iClass;
						end
						sClass = KOH.IDToClass(iClass);
					end
					red, green, blue = Karma_ClassMToColor(sClass);
					nametext:SetTextColor(red, green, blue);

					if (KARMA_Online.PlayersAll[sMembername].level and KARMA_Online.PlayersAll[sMembername].class) then
						local	sClassSub = KARMA_Online.PlayersAll[sMembername].class;
						local	iSpace = strfind(sClassSub, " ", 1, true);
						if (iSpace) then
							sClassSub = strsub(sClassSub, 1, iSpace - 1);
						end
						local	classlvltext = getglobal(which .. "ClassLvl"..iCounter.."_Text");
						classlvltext:SetText(KARMA_Online.PlayersAll[sMembername].level .. sClassSub);

						local	sClass = KARMA_Online.PlayersAll[sMembername].class;
						local	iClass = KOH.ClassToID(sClass);
						if (sClass and iClass) then
							iTalents = KARMA_TALENT_CLASSMASK[math.abs(iClass)];
							if (iTalents and (bit.band(iTalents, 7) == 4)) then
								local	sDistance, sTexture, xmin, xmax = KarmaObj.Talents.TalentID2TextureDistance(iTalents, iClass);
								if (sTexture) then
									bTalent = true;
									local	texture    = getglobal(which .. "Talent" .. iCounter .. "_IconL");
									texture:SetTexture(sTexture);
									texture:SetTexCoord(xmin, xmax, 0, 1);
									local	talenttext = getglobal(which .. "Talent" .. iCounter .. "_TextL");
									talenttext:SetText(sDistance);
								end
							end
						end
					end
				else
					red, green, blue = Karma_GetColors_Class(sMembername);
					nametext:SetTextColor(red, green, blue);

					red, green, blue = Karma_GetColors_Karma(sMembername);
					local	iKarma, bModified = Karma_MemberObject_GetKarmaModified(oMember);
					local	sKarma;
					if (iKarma >= 100) then
						sKarma = "++";
					else
						sKarma = iKarma;
					end
					if (bModified) then
						sKarma = "*" .. sKarma;
					end
					local	karmavaluetext = getglobal(which .. "KarmaValue"..iCounter.."_Text");
					karmavaluetext:SetText(sKarma);
					karmavaluetext:SetTextColor(red, green, blue);

					local	sClass, iClass = Karma_MemberObject_GetClass(oMember);
					local	classlvltext = getglobal(which .. "ClassLvl"..iCounter.."_Text");
					if	(oMember[KARMA_DB_L5_RRFFM_CONFLICT] ~= nil) and
						(oMember[KARMA_DB_L5_RRFFM_CONFLICT].Resolved == 0) then
						classlvltext:SetText("|cFFFF0000CONFLICT!|r");
					else
						local	sClassSub = sClass;
						-- cutting the deathknight
						local	iSpace = strfind(sClassSub, " ", 1, true);
						if (iSpace) then
							sClassSub = strsub(sClassSub, 1, iSpace - 1);
						end
						classlvltext:SetText(Karma_MemberObject_GetLevel(oMember) .. sClassSub);
					end

					bTalent = true;
					local	oTalents, bOnlyText, bOnlyTextures, j, i = {}, true, true;
					for i = 1, iSpecCount do
						sTalents, iTalents = Karma_MemberObject_GetTalentColorizedText(oMember, i);
						local	talenttext = getglobal(which .. "Talent" .. iCounter .. "_Text" .. oTalentBtn[i]);
						local	texture    = getglobal(which .. "Talent" .. iCounter .. "_Icon" .. oTalentBtn[i]);
						local	sDistance, sTexture, xmin, xmax = KarmaObj.Talents.TalentID2TextureDistance(iTalents, iClass);
						if (sTexture) then
							texture:SetTexture(sTexture);
							texture:SetTexCoord(xmin, xmax, 0, 1);
							talenttext:SetText(sDistance);

							oTalents[i] = { Texture = sTexture .. "_" .. xmin .. "_" .. xmax, Distance = sDistance };
							bOnlyText = false;
						else
							texture:SetTexture("");
							for j = 1, i - 1 do
								if (oTalents[j] and (sTalents == oTalents[j].AsText)) then
									sTalents = "";
									break;
								end
							end

							talenttext:SetText(sTalents);
							if (sTalents ~= "") then
								oTalents[i] = { AsText = sTalents };
								bOnlyTextures = false;
							end
						end
					end

					if (iSpecCount > 1) then
						-- caveat: speccount == 2
						if (bOnlyText and (oTalents[iSpecCount] == nil)) then
							local	talenttextL = getglobal(which .. "Talent" .. iCounter .. "_Text" .. oTalentBtn[1]);
							local	talenttextW = getglobal(which .. "Talent" .. iCounter .. "_TextWide");
							talenttextW:SetText(talenttextL:GetText());
							talenttextL:SetText("");
						end
						-- caveat: speccount == 2
						if (bOnlyTextures) then
							local	bEqual = (oTalents[1] ~= nil) and (oTalents[iSpecCount] ~= nil);
							if (bEqual) then
								bEqual = (oTalents[1].Texture  == oTalents[iSpecCount].Texture) and
									 (oTalents[1].Distance == oTalents[iSpecCount].Distance);
							end
							if (bEqual) then
								local	talenttext = getglobal(which .. "Talent" .. iCounter .. "_Text" .. oTalentBtn[iSpecCount]);
								local	texture    = getglobal(which .. "Talent" .. iCounter .. "_Icon" .. oTalentBtn[iSpecCount]);
								texture:SetTexture(nil);
								talenttext:SetText("");
							end
						end
					end
				end

				if (not bTalent) then
					local	sText = KARMA_MISSING_INFO;
					local	sClass = KARMA_Online.PlayersAll[sMembername].class;
					local	iClass = KOH.ClassToID(sClass);
					if (sClass and iClass) then
						iTalents = KARMA_TALENT_CLASSMASK[math.abs(iClass)];
						if (iTalents and (iTalents ~= 0)) then
							-- above we tested for DPS/?, now only ???/M and ???/R remains
							if (bit.band(iTalents, 3) ~= 0) then
								local	iDistance = bit.band(iTalents, 24);
								if (iDistance ~= 24) then
									sText = sText .. "/" .. KarmaObj.Talents.TalentID2Distance(iDistance);
								end
							end
						end
					end

					local	talenttext = getglobal(which .. "Talent" .. iCounter .. "_TextWide");
					talenttext:SetText(sText);
				end

				if (which == "KarmaWindow2_List2_") then
					if (KARMA_Online.PlayersAll[sMembername].sendmess == 1) then
						buttontext = getglobal(which .. "SendMessage" .. iCounter);
						buttontext:SetChecked(1);
					end

					if (KARMA_Online.PlayersAll[sMembername].sentmess == 1) then
						buttontext = getglobal(which .. "SentMessage" .. iCounter);
						buttontext:SetChecked(1);
					end

					if (KARMA_Online.PlayersAll[sMembername].posreply == 1) then
						buttontext = getglobal(which .. "PositiveReply" .. iCounter);
						buttontext:SetChecked(1);
					end
				end

				iCounter = iCounter+1;
			end
		end
		nindex = nindex+1;
	end

	local	ExtraLines = ListSize - (ListSize % 2);
	ExtraLines = ExtraLines / 2;
	FauxScrollFrame_Update(ScrollFrame, iNumEntries + ExtraLines, ListSize, 13, nil, 0, 0);

	KarmaObj.ProfileStop("KarmaWindow2_UpdateList");
end

function	KarmaWindow2_UpdateList1()
	KarmaWindow2_UpdateList("KarmaWindow2_List1_");
end

function	KarmaWindow2_UpdateList2()
	KarmaWindow2_UpdateList("KarmaWindow2_List2_");
end

function	KarmaWindow2_OnShow(self)
	if (time() - KarmaModuleLocal.KarmaWindow2_ShowInital > 120) then
		KarmaModuleLocal.KarmaWindow2_ShowInital = time();
		if (GetChannelName(KARMA_CHANNELNAME_LFG) > 0) then
			Karma_QueueCommandChannelCheck(KARMA_CHANNELNAME_LFG);
		end
	end

	if (GetGuildInfo("player") ~= nil) then
		GuildRoster();
		Karma_WhoAmIInit();
		local	iNow = time();
		if (GetNumGuildMembers() > 1) then
			local	iCnt, i = GetNumGuildMembers();
			for i = 1, iCnt do
				local	sName, _, _, iLvl, sClass, sZone, _, _, bOnline = GetGuildRosterInfo(i);
				if (bOnline and sName and (sName ~= WhoAmI)) then
					local	oPlayer = KARMA_Online.PlayersAll[sName];
					if (oPlayer == nil) then
						oPlayer = {};
						KARMA_Online.PlayersAll[sName] = oPlayer;
					end

					oPlayer.time = iNow;
					oPlayer.level = iLvl;
					oPlayer.class = sClass;
					oPlayer.zone = sZone;
				end
			end
		end
	end

	KarmaWindow2_UpdateList1();
	KarmaWindow2_UpdateList2();
end

function	LFMObj.ModuleInit()
	KARMA_ClassToAllianceRace_Matrix = KARMA_ClassToAllianceRace_Matrix_LichKing;
	KARMA_ClassToHordeRace_Matrix = KARMA_ClassToHordeRace_Matrix_LichKing;
	if (KarmaObj.Const.iTOC >= 40000) then
		KarmaChatDebug("[KarmaLFM] Using cataclysm Class/Race matrices.");
		KARMA_ClassToAllianceRace_Matrix = KARMA_ClassToAllianceRace_Matrix_Cataclysm;
		KARMA_ClassToHordeRace_Matrix = KARMA_ClassToHordeRace_Matrix_Cataclysm;
		if (KarmaObj.Const.iTOC >= 50000 and KarmaObj.Const.bMoPActive) then
			KarmaChatDebug("[KarmaLFM] Using Pandaria Class/Race matrices.");
			KARMA_ClassToAllianceRace_Matrix = KARMA_ClassToAllianceRace_Matrix_Pandaria;
			KARMA_ClassToHordeRace_Matrix = KARMA_ClassToHordeRace_Matrix_Pandaria;
		end
	end

	if (KarmaModuleLocal.KarmaWindow2_CreatedButtons == 0) then
		KarmaModuleLocal.KarmaWindow2_CreatedButtons = 1;

		local	ButtonList = { "Online", "KarmaValue", "Name", "ClassLvl", "Talent", "Location" };
		local	CheckButtonList = { "SendMessage", "SentMessage", "PositiveReply" };
		local	p, parentobj, prefix, ListSize, y, i, btnobj, template;
		for p = 1, 2 do
			if (p == 1) then
				parentobj = getglobal("KarmaWindow2_List1_Frame");
				prefix = "KarmaWindow2_List1_";
				ListSize = KARMA_LFGWND_LIST1_SIZE;
				y = 0;
			else
				parentobj = getglobal("KarmaWindow2_List2_Frame");
				prefix = "KarmaWindow2_List2_";
				ListSize = KARMA_LFGWND_LIST2_SIZE;
				y = -4;
			end
			for i = 2, ListSize do
				for key, value in pairs(ButtonList) do
					-- FrameType, Name, parentFrame, inheritFrame
					template = "KarmaWindow2_List_" .. value .. "Template";
					if (value == "Name") then
						template = prefix .. value .. "Template";
					end
					btnobj = CreateFrame("Button", prefix .. value .. tostring(i), parentobj, template);
					btnobj:SetID(i);
					btnobj:SetPoint("TOPLEFT", prefix .. value .. tostring(i - 1), "BOTTOMLEFT", 0, y);
				end

				if (p == 2) then
					for key, value in pairs(CheckButtonList) do
						-- FrameType, Name, parentFrame, inheritFrame
						template = "KarmaWindow2_List_" .. value .. "Template";
						btnobj = CreateFrame("CheckButton", prefix .. value .. tostring(i), parentobj, template);
						btnobj:SetID(i);
						btnobj:SetPoint("LEFT", prefix .. value .. tostring(i - 1), "LEFT");
						btnobj:SetPoint("TOP", prefix .. "Name" .. tostring(i), "TOP", 0, 4);
						if (value == "SentMessage") then
							-- btnobj:Disable();
							btnobj:RegisterForClicks();
						end
					end
				end
			end
		end

		btnobj = getglobal("KarmaWindow2_List2_SentMessage1");
		if (btnobj) then
			-- btnobj:Disable();
			btnobj:RegisterForClicks();
		end

		local	sLocale = KARMAAVENK_LOCUI_MODLFM["DEFAULT"];
		local	oTableLOC = KARMAAVENK_LOCUI_MODLFM[sLocale];
		local	oTableEN = KARMAAVENK_LOCUI_MODLFM["enUS"];

		local	oFunctions = { "GetChildren", "GetRegions" };
		local	function	LocalizeIt(oFrame)
				local	iIndex, sFunction;
				for iIndex, sFunction in pairs(oFunctions) do
					if (type(oFrame[sFunction]) == "function") then
						local	oChildren, iIndex, oButton = { oFrame[sFunction](oFrame) };
						for iIndex, oButton in pairs(oChildren) do
							if (type(oButton) == "table") then
								if (type(oButton.GetText) == "function") then
									local	sText = oButton:GetText();
									if (sText) then
										-- KarmaChatDebug("Checking LFM localization... Buttontext = " .. sText);
										if (strsub(sText, 1, 24) == "KARMAAVENK_LOCUI_MODLFM_") then
											local	sKey, sValue = strsub(sText, 25);
											sValue = oTableLOC[sKey];
											if (sValue) then
												oButton:SetText(sValue);
											else
												sValue = oTableEN[sKey];
												if (sValue) then
													oButton:SetText(sValue);
													KarmaChatDebug("Missing current localization to key: " .. sKey);
												else
													oButton:SetText("<" .. sKey .. "?>");
													KarmaChatDebug("Missing any localization to key: " .. sKey);
												end
											end

											oButton.LocalizationKey = sKey;
											oButton.LocalizationValue = sValue;
										end
									end
								end

								local	iIndexSub, sFunctionSub;
								for iIndexSub, sFunctionSub in pairs(oFunctions) do
									if (type(oButton[sFunctionSub]) == "function") then
										LocalizeIt(oButton);
										break
									end
								end
							end
						end
					end
				end
			end

		LocalizeIt(KarmaWindow2);
		LocalizeIt(KarmaWindow2_PopulateWindow);
		LocalizeIt(KarmaWindow2_FilterList1);

		KarmaObj.Slash.CommandAdd("checkclass", SlashObj.CheckClassOnline);
		KarmaObj.Slash.CommandAdd("checkchannel", Karma_SlashCheckOnlineInChannel);
		KarmaObj.Slash.CommandAdd("checkallclasses", KarmaObj.Slash.CheckAllClassesOnline);
		KarmaObj.Slash.CommandAdd("checkguild", Karma_SlashCheckGuild);
	end
end