components_data_SceneManager.bs

import "pkg:/source/roku_modules/log/LogMixin.brs"
import "pkg:/source/utils/dialogs.bs"
import "pkg:/source/utils/misc.bs"

sub init()
  m.log = new log.Logger("SceneManager")
  m.scene = m.top.getScene()
  m.overhang = m.scene.findNode("overhang")
end sub

' SceneManager is purely a shared SERVICE node — backdrop, theme, the overhang user/clock
' passthroughs below, and the one dialog QUERY (isDialogOpen) that needs to answer for both
' presentation channels at once. It no longer SHOWS dialogs: every dialog in the app goes
' through source/utils/dialogs.bs and answers on its own node. The router host (JRScene) owns
' navigation and its own overhang controller; there is no scene stack (pushScene / popScene /
' getActiveScene etc.).

' Signal that home screen should be reloaded (used after theme color changes)
' Main.bs observes reloadHomeRequested field and handles the actual reload
sub reloadHome()
  m.top.reloadHomeRequested = true
end sub

' Update username in overhang
sub updateUser()
  ' Passthrough to overhang
  if isValid(m.overhang) then m.overhang.currentUser = m.top.currentUser
end sub

' Reset time
sub resetTime()
  ' Passthrough to overhang
  m.overhang.callFunc("resetTime")
end sub

' Set the background image
' @param {string} uri - The image URI to display
' @param {boolean} isAnimated - Whether to animate the transition
' @param {boolean} forceBackdrop - Force show backdrop regardless of user setting (used for login splashscreen)
sub setBackgroundImage(uri as string, isAnimated = true as boolean, forceBackdrop = false as boolean)
  m.log.info("SceneManager.setBackgroundImage called", uri, isAnimated, forceBackdrop)
  ' Passthrough to scene via callFunc
  if isValid(m.scene)
    m.scene.callFunc("setBackgroundImage", uri, isAnimated, forceBackdrop)
  else
    m.log.error("SceneManager.setBackgroundImage: m.scene is invalid!")
  end if
end sub

' Is ANY dialog currently on screen? Callers use this to hold off on something
' that would interfere — the OSD's inactivity auto-hide, the player's
' end-of-playback teardown.
'
' There are TWO channels and this must answer for both. It used to check only
' Roku's modal channel, so it began silently returning false for every dialog in
' the app when the JRDialog family moved to scene-appended overlays. The OSD read
' that false and hid itself out from under an open dialog, taking focus with it
' — the dialog stayed on screen but deaf, and Back fell through to the player.
function isDialogOpen() as boolean
  if isValid(m.scene.dialog) then return true
  return isOverlayDialogOpen()
end function

' Refresh theme colors on JRScene and overhang.
' Called after theme color settings change (settings exit, login, logout).
' Uses refreshThemeOnTree() to walk the overhang's node tree and update all
' themed elements (labels, buttons, icons) in place — no component recreation
' or per-component refresh functions needed.
sub refreshThemeColors()
  m.scene.backgroundColor = m.global.constants.colorBackgroundPrimary

  if isValid(m.overhang)
    refreshThemeOnTree(m.overhang)
  end if
end sub