--[[----------------------------------------------------------------------------

KSSystemNotifications.lua

--------------------------------------------------------------------------------

ADOBE CONFIDENTIAL
------------------
Copyright 2011 Adobe Systems Incorporated
All Rights Reserved.

NOTICE: All information contained herein is, and remain the property of
Adobe Systems Incorporated and its suppliers, if any. The intellectual and
technical concepts contained herein are proprietary to Adobe Systems
Incorporated and its suppliers and may be covered by U.S. and Foreign
Patents, patents in process, and are protected by trade secret or copyright
law.  Dissemination of this information or reproduction of this material is
strictly forbidden unless prior written permission is obtained from
Adobe Systems Incorporated.

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

local WFCurrentThread = require 'WFCurrentThread'

local KSReactive = require 'KSReactive'

--------------------------------------------------------------------------------

local DEBUG_NOTIFICATIONS = false

--------------------------------------------------------------------------------

-- @mark KSSystemNotifications namespace

--[[!
	\class KSSystemNotifications

	\brief This namespace provides a cross-platform interface to
		system notifications as event-stream objects.

]]--

local KSSystemNotifications = {}

local registeredNotificationsEventTable

-- GRUNGE [erwright 2011-06-01]: using a KSReactive weak event table or a fully-weak
-- regular table ends up being too weak for the notification system.  With those,
-- we keep losing the registered :onDataE() subscribers.  Something to look at later.

local USE_REACTIVE = false

if USE_REACTIVE then
	registeredNotificationsEventTable = KSReactive.makeWeakEventTable()
else
	registeredNotificationsEventTable = {}
end

--------------------------------------------------------------------------------

--[[!
	Retrieves an existing notification stream, or creates a new one if needed.

	\param notificationName (string) The desired notification.

	\return The event-stream object.
]]--

function KSSystemNotifications.notificationStreamE( --[[string]] notificationName )

	if USE_REACTIVE then
	
		local stream = registeredNotificationsEventTable:eventE( notificationName )
		return stream:relayE()
		
	else
	
		local stream = registeredNotificationsEventTable[ notificationName ]
		if not stream then
			stream = KSReactive.sourceE()
			registeredNotificationsEventTable[ notificationName ] = stream
		end
		
		return stream:relayE()
		
	end
end

--------------------------------------------------------------------------------

function KSSystemNotifications.onNotificationDo(
					--[[string]] notificationName,
					--[[function]] action )
					
	KSSystemNotifications.notificationStreamE( notificationName )
		:weakOnDataE( action )
		:runUntilDone()
					
end

--------------------------------------------------------------------------------

function KSSystemNotifications.ownedOnNotificationDo(
					--[[string]] notificationName,
					--[[object]] owner,
					--[[function]] action )
					
	KSSystemNotifications.notificationStreamE( notificationName )
			:ownedOnDataE( owner, action )
					
end

--------------------------------------------------------------------------------

WFCurrentThread.registerExternalMessageDispatchHandler(
	function( notificationName, ... )

		if DEBUG_NOTIFICATIONS then
			debug.print( "got broadcastNotification for: ", notificationName, select(1, ...), select( 2, ... ) )
		end
		
		if USE_REACTIVE then
		
			if registeredNotificationsEventTable:eventExists( notificationName ) then
				registeredNotificationsEventTable:postToEvent( notificationName, ... )
			else
				if DEBUG_NOTIFICATIONS then
					debug.print( "no one listening for: ", notificationName )
				end
			end
			
		else
		
			local stream = registeredNotificationsEventTable[ notificationName ]
			if stream then
				stream:post( ... )
			else
				if DEBUG_NOTIFICATIONS then
					debug.print( "no one listening for: ", notificationName )
				end
			end
			
		end
	
	end )

--------------------------------------------------------------------------------

return KSSystemNotifications
