

--===================================================
--									
--								GHI Communication
--									ghi_comm.lua
--
--	Handler of all communication between clients
--	
-- 						(c)2011 The Gryphonheart Team
--								All rights reservated
--===================================================	

local libComm = LibStub("AceComm-3.0");
local libSerial = LibStub("AceSerializer-3.0");
local libCompress = LibStub("LibCompress")
local libEncode = libCompress:GetAddonEncodeTable()
local addOnPrefix = "GHI2";

local class;
function GHI_Comm()
	
	if class then
		return class;
	end
	class = GHClass("GHI_Comm");
	
	local channel = "WHISPER";
	local recieveFuncs = {};
	local playersCommunicatedWith = {};
	local registeredFrames,OnEvent,ParseEventToFrames;
	
	-- Register special recieve func
	
	-- see http://www.wowace.com/addons/libcompress/#c1
	class.AddRecieveFunc = function(_prefix,_recieveFunc)
		recieveFuncs[_prefix] = _recieveFunc;
	end
	
	-- SendAddonMessage
	class.Send = function(prio,target,prefix,...)
		assert(not(target=="WHISPER"),"Non updated sending of info");
		GHCheck("GHI_Comm.Send",{"StringNil","String","String"},{prio,target,prefix})
		-- dont send to GMs
		if GMChatFrame_IsGM then return end;
				
		local finalMsg = libEncode:Encode(libCompress:CompressHuffman(libSerial:Serialize({prefix,...})));
		
		libComm:SendCommMessage(addOnPrefix,finalMsg,channel,target,prio)
		playersCommunicatedWith[target] = true;
	end
	
	class.GetQueueSize = function()
		local size = 0;
		for prioname, Prio in pairs(ChatThrottleLib.Prio) do
			if type(Prio.Ring)=="table" and type(Prio.Ring.pos)=="table" then
				for prioname, data in pairs(Prio.Ring.pos) do
					size = size + (data.nSize or 0);
				end
			end
		end
		return size;
	end
		
	local recieve = function(prefix,data,channel,sender) 
		
		local one = libEncode:Decode(data)
	
		--Decompress the decoded data
		local message = libCompress:Decompress(one)
		if(not message) then
			GHI_Message("GHI: error decompressing")
			return
		end
		
		-- Deserialize the decompressed data
		local success, data = libSerial:Deserialize(message)
		if (not success) then
			GHI_Message("GHI: error deserializing " .. data)
			return
		end
		
		local prefix = table.remove(data,1);
		if recieveFuncs[prefix] then
			recieveFuncs[prefix](sender,unpack(data));
		end
	end
	
	OnEvent = function(self,event,msg,...)
		if event == "CHAT_MSG_SYSTEM" then
			local pattern = gsub(ERR_CHAT_PLAYER_NOT_FOUND_S,"%%s","(%%a-)");
			local player = string.match(msg,pattern);
			if player and playersCommunicatedWith[player] then
				return;
			end
		end	
		ParseEventToFrames(event,msg,...)
	end
	
	ParseEventToFrames = function(event,...)
		for _,frame in pairs(registeredFrames) do
			if not(frame:IsEventRegistered(event)) then
				local s = frame:GetScript("OnEvent")
				s(frame,event,...);
			end
		end
	end
	
	local setUp = false;
	GHI_Timer(function()
		if setUp == false then
			registeredFrames = {GetFramesRegisteredForEvent("CHAT_MSG_SYSTEM")};
			for _,frame in pairs(registeredFrames) do
				frame:UnregisterEvent("CHAT_MSG_SYSTEM");
			end	
			class:RegisterEvent("CHAT_MSG_SYSTEM");
			setUp = true;
		end
	end,7);
		
	libComm:RegisterComm(addOnPrefix, recieve);
	class:SetScript("OnEvent",OnEvent);
	
	

	
	
	
	return class;
end

 