-- LOAD LOCALISATION
if (GetLocale()=="deDE") then
	tradeDispenser_GetGerman()
elseif (GetLocale()=="zhCN") then
	tradeDispenser_GetChinese()
elseif (GetLocale()=="frFR") then
	tradeDispenser_GetFrench()
else tradeDispenser_GetEnglish()
end


function tradeDispenserVerbose(level, text)
	local temp=0;
	if (tD_GlobalDatas.Verbose) then	temp = tD_GlobalDatas.Verbose	end
    if (temp>=level) then
		DEFAULT_CHAT_FRAME:AddMessage(tradeDispenser_ProgName..": "..text)
	end
end


function tradeDispenserMessage(channel, message)
	channel = strupper(channel)
	if (channel=="WHISPER") then
		SendChatMessage(message, "WHISPER", tD_Loc[UnitFactionGroup("player")], tD_Temp.Target.Name)
	elseif (channel=="RAID" or channel=="PARTY" or channel=="GUILD" or channel=="YELL" or channel=="SAY") then
		SendChatMessage(message, channel);
	else
		tradeDispenserVerbose(0,"Error: cannot use channel '"..channel.."'") 
	end
end


function tradeDispenserPlaySound(frame)
	if (frame:GetFrameType()=="Button") then
		PlaySound("GAMEGENERICBUTTONPRESS")
	elseif (frame:GetFrameType()=="CheckButton") then
		if ( frame:GetChecked() ) then
			PlaySound("igMainMenuOptionCheckBoxOn");
		else
			PlaySound("igMainMenuOptionCheckBoxOff");
		end
	end
end



function tradeDispenserDrawTooltip(textfield)
	local i=0;
	GameTooltip:AddLine("|cFFFFFFFF"..textfield[i]);
	for i=1,table.getn(textfield) do
		GameTooltip:AddLine(textfield[i]);
	end						
	GameTooltip:Show();	
end

function tradeDispenserSetTooltipPosition(frame,mx,my)
	local lx,ly = frame:GetCenter();
	local px, py = UIParent:GetCenter();
	local pos, korrX, korrY = "ANCHOR_",1,1;
	if (ly>py) then pos=pos.."BOTTOM";             else  korrY=-1; 			end
	if (lx>px) then pos=pos.."LEFT";   korrX=-1;   else  pos=pos.."RIGHT";	end
	GameTooltip:SetOwner(frame,pos,mx*korrX,my*korrY);	
end


function tradeDispenser_Print(textfield)
	table.foreach(textfield, function(k,v) DEFAULT_CHAT_FRAME:AddMessage(v) end)
end

-- Hooked Function to check, if the PLAYER or the CLIENT has initiated the trade!
-- this is triggered BEFORE the event TradeShow gets fired
local OldInitiateTrade = InitiateTrade;
function InitiateTrade(UnitID)
	tradeDispenserVerbose(1,"Trade Started - triggered by hooked Function: InitiateTrade");
	tD_Temp.InitiateTrade=true;
	OldInitiateTrade(UnitID)
end

local OldBeginTrade = BeginTrade;
function BeginTrade()
	tradeDispenserVerbose(1,"Trade Started - triggered by hooked Function: BeginTrade");
	tD_Temp.InitiateTrade=true;
	OldBeginTrade()
end


function tradeDispenserUpdateMoney()
	tD_CharDatas.profile[tD_CharDatas.ActualRack][tD_CharDatas.ActualProfile].Charge = MoneyInputFrame_GetCopper(tradeDispenserMoneyFrame)
end


function tradeDispenserSplitMoney(money)
	local gold = floor(money / (COPPER_PER_GOLD))
	local silver = floor((money - (gold * COPPER_PER_GOLD)) / COPPER_PER_SILVER)
	local copper = mod(money, COPPER_PER_SILVER)
	return gold, silver, copper
end



function tradeDispenserCompile(slotID)
	if (tD_Temp.Slot[slotID].itemLink == nil) then
		return "deadlink",nil
	end
	
	local configItemLink = tD_Temp.Slot[slotID].itemLink
	local configItemCount = tD_Temp.Slot[slotID].itemCount
	
	if (configItemLink) then tradeDispenserVerbose(1,"tradeDispenserCompile: looking for: "..configItemLink) end
	tradeDispenserVerbose(2,"tradeDispenserCompile: first round")

	-- first we look for complete stacks
	for cID=4,0,-1 do
		tradeDispenserVerbose(3,"tradeDispenserCompile: "..GetContainerNumSlots(cID).." slots in bag "..cID)
		for sID=1,GetContainerNumSlots(cID) do
			local itemLink = GetContainerItemLink(cID, sID)
			local _, itemCount, itemLocked = GetContainerItemInfo(cID, sID)

			if (tradeDispenserLink(itemLink) == tradeDispenserLink(configItemLink) and not itemLocked) then
				if (itemCount) then tradeDispenserVerbose(2,"tradeDispenserCompile: found item: itemCount: "..itemCount) end
				if (itemCount == configItemCount) then
					tradeDispenserVerbose(3,"tradeDispenserCompile: found in first round in "..cID.."/"..sID)
					return cID, sID
				end
			end
		end
	end
	
	-- there is no complete stack, we have to compile one
	-- first we have to find a free bag slot
	local _cID, _sID = tradeDispenserFreeSlot()
	if (_cID == nil) then
		tradeDispenserVerbose(2,"tradeDispenserCompile: no free slots")
		return nil, nil
	end
	
	tradeDispenserVerbose(2,"tradeDispenserCompile: second round, tmp slot is :".._cID.."/".._sID)
	
	local stackCount = 0
	local stackFound = false
	for cID=4,0,-1 do
		for sID=1,GetContainerNumSlots(cID) do
			if (cID ~= _cID or sID ~= _sID) then
				local itemLink = GetContainerItemLink(cID, sID)
				local _, itemCount, itemLocked = GetContainerItemInfo(cID, sID)
			
				if (tradeDispenserLink(itemLink) == tradeDispenserLink(configItemLink) and not itemLocked) then
					stackFound = true
					local missingCount = configItemCount - stackCount
					local splitCount = math.min(missingCount, itemCount)
					tradeDispenserVerbose(3,"tradeDispenserCompile: second round found item: missingCount: "..missingCount..", itemCount: "..itemCount)
					SplitContainerItem(cID, sID, splitCount)
					PickupContainerItem(_cID, _sID)
					
					stackCount = stackCount + splitCount
					tradeDispenserVerbose(3,"tradeDispenserCompile: added "..splitCount.." items to temp stack, now we have "..stackCount)
				
					-- if we have compiled the stack... return
					if (stackCount == configItemCount) then
						tradeDispenserVerbose(2,"tradeDispenserCompile: finished second round")
						return _cID, _sID
					end
				end
			end	
		end
	end
	
	if (stackFound) then
		tradeDispenserVerbose(1,"tradeDispenserCompile: returning temp stack")
		return _cID, _sID
	else
		tradeDispenserVerbose(1,"tradeDispenserCompile: nothing found")
		return nil
	end
end




function tradeDispenserTradeControlChecker()
	local tradeDispenserClient = {};	-- used for saving the stats (guild, party, raid) of the Client;
	local targetClass, targetEnglishClass = UnitClass("NPC");
	tradeDispenserClient = {
		["Class"] 	= targetEnglishClass,
		["Level"] 	= UnitLevel("NPC"),
		["Name"] 	= UnitName("NPC")
	}
	if (UnitInRaid("player")) then
		if (UnitInRaid("NPC")) then			tradeDispenserClient.Raid = "IsMember";
		else								tradeDispenserClient.Raid = "NotMember";			end
	else 									
		if (UnitInParty("player")) then
			if (UnitInParty("NPC")) then	tradeDispenserClient.Raid = "IsMember";
			else							tradeDispenserClient.Raid = "NotMember";			end
		else 								tradeDispenserClient.Raid = "SinglePlayer"; 		end
	end
			
	local guildName,  guildRankName,  guildRankIndex = GetGuildInfo("player");
	local guildName2, guildRankName2, guildRankIndex2 = GetGuildInfo("NPC");
		
	if (guildName==guildName2) then
		 tradeDispenserClient.Guild = "IsMember";
	else tradeDispenserClient.Guild = "NotMember"; end
	
	if (tradeDispenserClient.Raid=="IsMember" or tradeDispenserClient.Guild=="IsMember") then tD_Temp.isInsider=true; end
	
	if (tD_CharDatas.ClientInfos) then
		local guildName3 = "";
		if (guildName2~=nil) then guildName3 = "<"..guildName2.."> ";	end
		if (not targetClass) then targetClass="Unknown" end
		DEFAULT_CHAT_FRAME:AddMessage(tD_Loc.Opposite.." "..tradeDispenserClient.Name.." "..guildName3.." -  "..targetClass.." Level "..tradeDispenserClient.Level,1,1,0);
	else
		tradeDispenserVerbose(1,"Clients Name = "..tradeDispenserClient.Name);
		tradeDispenserVerbose(1,"Clients Level = "..tradeDispenserClient.Level);
		tradeDispenserVerbose(1,"Clients Class = "..tradeDispenserClient.Class);
		tradeDispenserVerbose(1,"Group/Party = "..tradeDispenserClient.Raid);
		tradeDispenserVerbose(1,"your Guild = "..tradeDispenserClient.Guild);
	end
	
	if (tD_CharDatas.Raid and tradeDispenserClient.Raid=="NotMember") then 
		if (tD_CharDatas.Guild) then
			if (tradeDispenserClient.Guild=="NotMember") then
				tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[8])
				return false;
			end
		else
			tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[8])
			return false;
		end
	end
	
	if (tD_CharDatas.LevelCheck and tradeDispenserClient.Level<tD_CharDatas.LevelValue) then 
		tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[6])
		return false; 
	end
	

	local trades=tradeDispenserClientTrades(tradeDispenserClient.Name);
	if (trades>=1 and trades+1>tD_CharDatas.RegisterValue) then 
		tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[9])
		return false
	end
	
	if (tD_CharDatas.BanlistActive and tD_GlobalDatas.Bannlist and table.getn(tD_GlobalDatas.Bannlist)>0) then
		local found=false;
		table.foreach(tD_GlobalDatas.Bannlist, function(k,v) if (strlower(v)==strlower(tradeDispenserClient.Name)) then	found=true;	end; end)
		if (found) then
			tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[10])
			return false;
		end
	end
	
	return true;
end



function tradeDispenserClientTrades(name)
	if (not tD_CharDatas.RegisterCheck) then return 0  end
	local i=0
	local index=nil;
	while (tD_Temp.RegUser[i]~=nil) do
		if (tD_Temp.RegUser[i].name == name) then
			tradeDispenserVerbose(2,"Registred Player found at index "..i.." is: "..tD_Temp.RegUser[i].name);
			index=i;
		end
		i=i+1;
	end
	
	if (index==nil) then 
		tradeDispenserVerbose(1,name.." not registrated!");
		return 0
	else	
		tradeDispenserVerbose(1,name.." found with "..tD_Temp.RegUser[index].trades.." trades");	
		return tD_Temp.RegUser[index].trades
	end
end




function tradeDispenserAccept()
	tradeDispenserVerbose(1,"tradeDispenserAccept: Triggered")
	if (tD_Temp.tradeCharge and tD_Temp.tradeCharge > 0) then
		local recipientMoney = GetTargetTradeMoney()
		if (recipientMoney >= tD_Temp.tradeCharge) then
			tD_Temp.tradeState = nil
			AcceptTrade()
			
			if (tD_Temp.tradeData) then
				tD_Temp.tradeData = nil
				tD_Temp.isEnabled = false
				tradeDispenserUpdate()
				tradeDispenser_OSD_buttons()
			end
		else
			local gold, silver, copper = tradeDispenserSplitMoney(tD_Temp.tradeCharge)
			tradeDispenserMessage("WHISPER",tD_GlobalDatas.whisper[5].." "..gold.."g "..silver.."s "..copper.."c")
		end
	else
		tD_Temp.tradeState = nil
		AcceptTrade()
		
		if (tD_Temp.tradeData) then
			tD_Temp.tradeData = nil
			tD_Temp.isEnabled = false
			tradeDispenserUpdate()
			tradeDispenser_OSD_buttons()
		end
	end
end


function tradeDispenserFreeSlot()
	for cID=0,4 do
		for sID=1,GetContainerNumSlots(cID) do
			local itemLink = GetContainerItemLink(cID, sID)
			if (itemLink == nil) then
				return cID, sID
			end
		end
	end
	return nil
end

function tradeDispenserLink(itemLink)
	if (itemLink) then
		local _, _, itemID, itemEnchant, randomProperty, uniqueID, itemName = string.find(itemLink, "|Hitem:(%d+):(%d+):(%d+):(%d+)|h[[]([^]]+)[]]|h")
		return tonumber(itemID or 0), tonumber(randomProperty or 0), tonumber(itemEnchant or 0), tonumber(uniqueID or 0), itemName
	else
		return nil
	end
end



function tradeDispenserCompileProfile()
	if (not tD_Temp.Target.Name) then return false end
	local actualID=1;
	local i;
	tD_Temp.tradeCharge = 0;
	local getprofile = {
		["WARRIOR"] = {	[1]=2, [2]=10},
		["ROGUE"]	= { [1]=3, [2]=10},
		["HUNTER"]	= { [1]=4, [2]=11},
		["WARLOCK"]	= { [1]=5, [2]=11},
		["MAGE"]	= { [1]=6, [2]=11},
		["DRUID"]	= { [1]=7, [2]=12},
		["PRIEST"]	= { [1]=8, [2]=12},
		["PALADIN"] = { [1]=9, [2]=12},
		["SHAMAN"]  = { [1]=9, [2]=12}
	};
	tD_Temp.Slot={
		[1]={}, [2]={}, [3]={}, [4]={}, [5]={}, [6]={} 
	};

	tD_Temp.Target.EnglishClass = strupper(tD_Temp.Target.EnglishClass);
	tradeDispenserVerbose(1,"Compile the TradeProfiles: All Classes + "..tD_Temp.Target.EnglishClass.." + "..tD_Loc.profile[ getprofile[tD_Temp.Target.EnglishClass][2] ]);
	
	tD_Temp.tradeCharge = tD_CharDatas.profile[tD_CharDatas.ActualRack][1].Charge;	
	for slotID=1,6 do
		if (tD_CharDatas.profile[tD_CharDatas.ActualRack][1][slotID] and tD_CharDatas.profile[tD_CharDatas.ActualRack][1][slotID].itemName) then
			tD_Temp.Slot[actualID] = tD_CharDatas.profile[tD_CharDatas.ActualRack][1][slotID];
			actualID=actualID+1;
		end
	end
	
	local act=getprofile[tD_Temp.Target.EnglishClass][1];
	tradeDispenserVerbose(2, "looking in Profile "..act.." for items")
	tD_Temp.tradeCharge = tD_Temp.tradeCharge + tD_CharDatas.profile[tD_CharDatas.ActualRack][act].Charge;
	for slotID=1,6 do
		if (actualID<=6) then	
			local profile = tD_CharDatas.profile[tD_CharDatas.ActualRack][act][slotID]
			if ( profile and profile.itemName) then
				tD_Temp.Slot[actualID] = profile;
				actualID=actualID+1;
			end
		end
	end
	
	local act=getprofile[tD_Temp.Target.EnglishClass][2];
	tradeDispenserVerbose(2, "looking in Profile "..act.." for items")
	
	tD_Temp.tradeCharge = tD_Temp.tradeCharge + tD_CharDatas.profile[tD_CharDatas.ActualRack][act].Charge;
	for slotID=1,6 do
		if (actualID<=6) then
			local profile = tD_CharDatas.profile[tD_CharDatas.ActualRack][act][slotID];
			if (profile and profile.itemName) then
				tD_Temp.Slot[actualID] = profile;
				actualID=actualID+1;
			end
		end
	end	
	
	if (tD_CharDatas.Free4Guild and tD_Temp.isInsider) then tD_Temp.tradeCharge=0 end;
	actualID=actualID-1;
	tradeDispenserVerbose(1,"Found "..actualID.." items to trade");
	return actualID;
end
