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

WFInsomnia.lua

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

ADOBE CONFIDENTIAL
------------------
Copyright 2017 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.

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

	-- WF.rx
local Rx = require 'Rx'
local Observable = Rx.Observable

	-- WF.core.utils
local WFArguments = require 'WFArguments'
local KSDate = require 'KSDate'
local WFRxScheduler = require "WFRxScheduler"
local WFPlatformInfo = require 'WFPlatformInfo'

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

local check = assert( WFArguments.check )

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

local WFInsomnia = {}

local kPreventSystemSleepCallInterval = 20
local lastPreventSystemSleepCallIntervalTimeStamp = nil
local lastPreventDisplaySleepCallIntervalTimeStamp = nil

local isPreventingDisplaySleep = false
local isPreventingSleep = false

local resumeIdleTimerSubscription = nil

local canPreventSleep = WFPlatformInfo.isMac or WFPlatformInfo.isWindows

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

--[[!
	\brief MAC AND WIN ONLY: Prevent the system from going to sleep for ~20-40 seconds
		while the system is on AC Power. The system will still sleep if it's on 
		battery power.
	
	\param reason (string) The reason for sleeping.
	\param optKeepDisplayAwake (optional boolean) If true, we'll prevent the display from
		going to sleep.
	\param optPreventSleepDuration (optional number) Number of seconds to prevent sleep.
	
	\return (void)
--]]

function WFInsomnia.preventSystemSleep( reason, optKeepDisplayAwake, optPreventSleepDuration )

	check( 'string', '?boolean', '?number' )

	local timeStamp = KSDate.timeIntervalSinceAppLaunch()

	local pump = false
	local display = false
	
	if not WFPlatformInfo.hasACPower() and WFPlatformInfo.hasBatteryPower() then
		return
	end
	
	if not lastPreventSystemSleepCallIntervalTimeStamp or
	  ( timeStamp > lastPreventSystemSleepCallIntervalTimeStamp + kPreventSystemSleepCallInterval ) then
	
		lastPreventSystemSleepCallIntervalTimeStamp = timeStamp
		pump = true
		
	end

	if optKeepDisplayAwake then
	
		if not lastPreventDisplaySleepCallIntervalTimeStamp or
		  ( timeStamp > lastPreventDisplaySleepCallIntervalTimeStamp + kPreventSystemSleepCallInterval ) then
		
			lastPreventDisplaySleepCallIntervalTimeStamp = timeStamp
			pump = true
			display = true
			
		end
		
	end
	
	if pump then
	
		if resumeIdleTimerSubscription then
			resumeIdleTimerSubscription:dispose()
			resumeIdleTimerSubscription = nil
		end
		
		local preventSleepDuration = optPreventSleepDuration or kPreventSystemSleepCallInterval * 2
		
		resumeIdleTimerSubscription = Observable.timer( preventSleepDuration, WFRxScheduler.sharedScheduler() )

			:subscribe( function()
			
				if canPreventSleep then
					require 'WFInsomniaImp'.preventSystemSleep( -1, reason )
						-- allow the system to idle and sleep normally
				end
				
				isPreventingSleep = false
				isPreventingDisplaySleep = false
				
			end )

		if canPreventSleep then
			require 'WFInsomniaImp'.preventSystemSleep( display and 1 or 0, reason )
		end
		
		isPreventingSleep = true
		isPreventingDisplaySleep = not not display
		
	end
		
end

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

function WFInsomnia.isPreventingSleep()

	return isPreventingSleep, isPreventingDisplaySleep

end

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

return WFInsomnia
