--[[
--
--	Telepathy-Versions
--		Keeps track of what Telepathy addons/versions everyone is using.
--
--	By Karl Isenberg (AnduinLothar)
--
--
--
--	$Id: Telepathy-Versions.lua 3777 2006-07-11 11:11:44Z karlkfi $
--	$Rev: 3777 $
--	$LastChangedBy: karlkfi $
--	$Date: 2006-07-11 06:11:44 -0500 (Tue, 11 Jul 2006) $
--]]

local TELEPATHY_VERSIONS_NAME 			= "Telepathy-Versions"
local TELEPATHY_VERSIONS_VERSION 		= 1.2
local TELEPATHY_VERSIONS_LAST_UPDATED	= "August 13, 2006"
local TELEPATHY_VERSIONS_AUTHOR 		= "AnduinLothar"
local TELEPATHY_VERSIONS_EMAIL			= "karlkfi@cosmosui.org"
local TELEPATHY_VERSIONS_WEBSITE		= "http://www.wowwiki.com/Telepathy-Versions"

------------------------------------------------------------------------------
--[[ Embedded Sub-Library Load Algorithm ]]--
------------------------------------------------------------------------------

if (not Telepathy.Versions) then
	Telepathy.Versions = {};
end
local isBetterInstanceLoaded = (Telepathy.Versions.version and Telepathy.Versions.version >= TELEPATHY_VERSIONS_VERSION);

if (not isBetterInstanceLoaded) then
	
	Telepathy.Versions.version = TELEPATHY_VERSIONS_VERSION;

	------------------------------------------------------------------------------
	--[[ Table Initialization ]]--
	------------------------------------------------------------------------------
	
	local function VarInitTable(key)
		if (not Telepathy.Versions[key]) then
			Telepathy.Versions[key] = {};
		end
	end
	
	VarInitTable("RegisteredAddons");
	VarInitTable("RegisteredAddonUsers");
	VarInitTable("OutstandingAddonRequests");
	
	local name = UnitName('player');
	if (not Telepathy.Versions.RegisteredAddonUsers[name]) then
		Telepathy.Versions.RegisteredAddonUsers[name] = {};
	end
	
	Telepathy.Versions.RegisteredAddonUsers[name].Telepathy = Telepathy.version;
	
	------------------------------------------------------------------------------
	--[[ Global Keywords ]]--
	------------------------------------------------------------------------------
	
	Telepathy.Versions.ADDON_REQ_ID = "AddonReq";
	Telepathy.Versions.ADDON_LIST_ID = "AddonList";
	
	------------------------------------------------------------------------------
	--[[ Debug ]]--
	------------------------------------------------------------------------------
	
	Telepathy.Debug.VERSIONING = false;

	------------------------------------------------------------------------------
	--[[ User Functions: Addon Versioning ]]--
	------------------------------------------------------------------------------

	function Telepathy.Versions.GetUserAddons(playerName)
		return Telepathy.Versions.RegisteredAddonUsers[playerName];
	end
	
	function Telepathy.Versions.IsAddonUser(playerName, addon)
		local addonList = Telepathy.Versions.RegisteredAddonUsers[playerName];
		if (not addonList) then
			return nil;
		end
		return addonList[addon] or false;
	end
	
	------------------------------------------------------------------------------
	--[[ User Functions: Update Callback ]]--
	------------------------------------------------------------------------------
	
	function Telepathy.Versions.RegisterAddon(addonID, version, usesGlobal)
		Telepathy.Versions.RegisteredAddonUsers[UnitName('player')][addonID] = version;
		if (usesGlobal and not Telepathy.Versions.UseGlobalChannel) then
			Telepathy.Versions.UseGlobalChannel = true;
			
		end
	end
	
	function Telepathy.Versions.RegisterCallback(callbackID, func)
		Telepathy.Versions.RegisteredAddons[callbackID] = func;
	end
	
	------------------------------------------------------------------------------
	--[[ Addon List Maintinance ]]--
	------------------------------------------------------------------------------
	
	function Telepathy.Versions.InquireAboutAddons(unit)
		if ( not UnitExists(unit) or not UnitIsPlayer(unit) or UnitIsUnit(unit, "player") or UnitIsEnemy(unit, "player") ) then
			return;
		end
		
		local name = UnitName(unit);
		Sea.io.dprint(Telepathy.Debug.VERSIONING, "Inquiring InquireAboutAddons: ", unit, ": ", name);
		
		if ( not UnitIsConnected(unit) ) then
			Telepathy.Versions.OutstandingAddonRequests[name] = nil;
			if ( Telepathy.Versions.RegisteredAddonUsers[name] ) then
				Telepathy.Versions.RegisteredAddonUsers[name] = nil;
				Sea.io.dprint(Telepathy.Debug.VERSIONING, "Telepathy Addon List Found in Memory for Offline Player, Clearing Addon Info : ",unit, ": ", name);
			end
			return;
		end
		
		if ( not Telepathy.Versions.OutstandingAddonRequests[name] ) then
			if ( Telepathy.Versions.RegisteredAddonUsers[name] ) then
				Sea.io.dprint(Telepathy.Debug.VERSIONING, "Telepathy Addon List Found in Memory: ", unit, ": ", name);
			
			elseif ( UnitInParty(unit) or UnitInRaid(unit) ) then
				--ask unit for addon data
				Telepathy.Versions.OutstandingAddonRequests[name] = GetTime();
				Telepathy.sendMessage(Telepathy.Versions.ADDON_REQ_ID, name, "RAID", name, "ALERT");
				--set outstanding addon request timer
				Chronos.scheduleByName("TelepathyAddonReqAbandon"..name, 2, Telepathy.Versions.AbandonAddonReq, name);
				
			elseif ( Telepathy.isInGlobalChannel() ) then
				--ask unit for addon data
				Telepathy.Versions.OutstandingAddonRequests[name] = GetTime();
				Telepathy.sendMessage(Telepathy.Versions.ADDON_REQ_ID, name, "GLOBAL", name, "ALERT");
				Sea.io.dprint(Telepathy.Debug.VERSIONING, "Telepathy Addon Req Sent: Requesting Sky Addons from ", name);
				--set outstanding addon request timer
				Chronos.scheduleByName("TelepathyAddonReqAbandon"..name, 2, Telepathy.Versions.AbandonAddonReq, name);
			end
		end
	end
	
	function Telepathy.Versions.AbandonAddonReq(playerName)
		Telepathy.Versions.OutstandingAddonRequests[playerName] = nil;
		Telepathy.Versions.RegisteredAddonUsers[playerName] = {};
	end
	
	function Telepathy.Versions.ReadAddonListMessage(data, sender, method)
		Sea.io.dprint(Telepathy.Debug.VERSIONING, "Telepathy Addon List recieved from ", sender, ":" );
		if (Telepathy.Debug.VERSIONING) then
			Sea.io.printTable(data);
		end
		Telepathy.Versions.AbandonAddonReq(sender);
		for addon, version in pairs(data) do
			Telepathy.Versions.RegisteredAddonUsers[sender][addon] = version;
		end
		Chronos.unscheduleByName("TelepathyAddonReqAbandon"..sender);
		for callbackID, func in pairs(Telepathy.Versions.RegisteredAddons) do
			func(sender, Telepathy.Versions.RegisteredAddonUsers[sender]);
		end
	end
	
	function Telepathy.Versions.ReadAddonReqMessage(target, sender, method)
		Sea.io.dprint(Telepathy.Debug.VERSIONING, "Telepathy Addon List of ", target, " requested by ", sender, " via ", method, "." );
		if ( target == UnitName('player') ) then
			if ( method == "WHISPER" ) then
				Telepathy.Versions.SendAddonList(target, method);
			else
				Chronos.scheduleByName("TelepathySendAddonList"..method, .5, Telepathy.Versions.SendAddonList, nil, method);
			end
		elseif ( Telepathy.Versions.OutstandingAddonRequests[target] ) then
			Chronos.scheduleByName("TelepathyAddonReqAbandon"..target, 2, Telepathy.Versions.AbandonAddonReq, target);
		end
	end
	
	function Telepathy.Versions.SendAddonList(target, method)
		local info = Telepathy.Versions.RegisteredAddonUsers[UnitName('player')];
		Telepathy.sendTable(Telepathy.Versions.ADDON_LIST_ID, info, method, target, "ALERT");
	end
	
	function Telepathy.Versions.SendInitAddon()
		local info = Telepathy.Versions.RegisteredAddonUsers[UnitName('player')];
		if (GetChannelName(Telepathy.GLOBAL_CHANNEL) > 0) then
			Telepathy.sendTable(Telepathy.Versions.ADDON_LIST_ID, info, "GLOBAL", nil, "ALERT");
		end
		if (GetNumRaidMembers() > 1 or GetNumPartyMembers() > 1) then
			Telepathy.sendTable(Telepathy.Versions.ADDON_LIST_ID, info, "RAID", nil, "ALERT");
		end
		Chronos.unscheduleByName("TelepathyReqGroupList");
		Telepathy.Versions.RequestGroupVersions();
	end
	
	function Telepathy.Versions.RequestGroupVersions()
		if (Telepathy.Versions.NumRaidMembers > 0) then
			for i=1, Telepathy.Versions.NumRaidMembers do
				Telepathy.Versions.InquireAboutAddons("raid"..i);
			end
		else
			for i=1, Telepathy.Versions.NumPartyMembers do
				Telepathy.Versions.InquireAboutAddons("party"..i);
			end
		end
	end

	------------------------------------------------------------------------------
	--[[ Frame Scripts ]]--
	------------------------------------------------------------------------------

	function Telepathy.Versions.OnLoad()
		this:RegisterEvent("ADDON_LOADED");
		this:RegisterEvent("PARTY_MEMBERS_CHANGED");
		this:RegisterEvent("RAID_ROSTER_UPDATE");
		this:RegisterEvent("PLAYER_TARGET_CHANGED");
	end
	
	function Telepathy.Versions.LoadVariables()
		if (not Telepathy.Versions.VariablesLoaded or Telepathy.Versions.VariablesLoaded < TELEPATHY_VERSIONS_VERSION) then
			if (Telepathy.Versions.UseGlobalChannel) then
				Telepathy.registerListener(Telepathy.Versions.ADDON_REQ_ID, {"GLOBAL", "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"}, Telepathy.Versions.ReadAddonReqMessage);
				Telepathy.registerListener(Telepathy.Versions.ADDON_LIST_ID, {"GLOBAL", "PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"}, Telepathy.Versions.ReadAddonListMessage);
			else
				Telepathy.registerListener(Telepathy.Versions.ADDON_REQ_ID, {"PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"}, Telepathy.Versions.ReadAddonReqMessage);
				Telepathy.registerListener(Telepathy.Versions.ADDON_LIST_ID, {"PARTY", "RAID", "GUILD", "BATTLEGROUND", "WHISPER"}, Telepathy.Versions.ReadAddonListMessage);
			end
			
			Chronos.afterInit(Chronos.schedule, 2, Telepathy.Versions.SendInitAddon);
			Telepathy.Versions.NumPartyMembers = GetNumPartyMembers();
			Telepathy.Versions.NumRaidMembers = GetNumRaidMembers();
			Telepathy.Versions.VariablesLoaded = TELEPATHY_VERSIONS_VERSION;
		end
	end
	
	function Telepathy.Versions.OnEvent()
		if (not Telepathy.online) then
			return;
		end
		
		if ( event == "ADDON_LOADED" ) then
			Telepathy.Versions.RegisteredAddonUsers[name].Telepathy = Telepathy.version;
			Telepathy.Versions.LoadVariables();
			
		elseif ( event == "PARTY_MEMBERS_CHANGED" ) then
			local num = GetNumPartyMembers();
			if (Telepathy.Versions.NumPartyMembers == 0 and Telepathy.Versions.NumRaidMembers == 0 and num > 0) then
				Telepathy.Versions.SendAddonList(nil, "RAID")
			end
			Telepathy.Versions.NumPartyMembers = num;
			Chronos.scheduleByName("TelepathyReqGroupList", 1, Telepathy.Versions.RequestGroupVersions);
			
		elseif ( event == "RAID_ROSTER_UPDATE" ) then
			local num = GetNumRaidMembers();
			if (Telepathy.Versions.NumPartyMembers == 0 and Telepathy.Versions.NumRaidMembers == 0 and num > 0) then
				Telepathy.Versions.SendAddonList(nil, "RAID")
			end
			Telepathy.Versions.NumRaidMembers = num;
			Chronos.scheduleByName("TelepathyReqGroupList", 1, Telepathy.Versions.RequestGroupVersions);
			
		elseif (event == "PLAYER_TARGET_CHANGED") then
			Telepathy.Versions.InquireAboutAddons("target");
			
		end
	end
	
	------------------------------------------------------------------------------
	--[[ Frame Script Assignment ]]--
	------------------------------------------------------------------------------
	
	--Event Driver
	if (not TelepathyVersionsFrame) then
		CreateFrame("Frame", "TelepathyVersionsFrame");
	end
	TelepathyVersionsFrame:Hide();
	--Frame Scripts
	TelepathyVersionsFrame:SetScript("OnEvent", Telepathy.Versions.OnEvent);
	--OnLoad Call (this masked)
	local tempThis = this;
	this = TelepathyVersionsFrame;
	Telepathy.Versions.OnLoad();
	this = tempThis;
	
end

	
