> ## Documentation Index
> Fetch the complete documentation index at: https://globaliptv.misidev.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture overview

> How GlobalTV Roku is structured: scene tree, source layers, components, tasks, and utilities.

GlobalTV Roku is a native Roku SceneGraph (RSG) channel written in BrightScript. The application is split into two physical layers — pure BrightScript logic under `source/` and SceneGraph XML+BRS components under `components/` — that communicate through the RSG scene tree and shared global state.

## Roku SceneGraph fundamentals

Roku SceneGraph is a declarative UI framework built on a node tree. Every visual element and background task is a node. Key system concepts used by this app:

* **Scene tree** — `MainScene` extends the built-in `Scene` node and is the root of the entire tree. All screens and tasks are children of `MainScene`.
* **roSGScreen** — the Roku system object that renders the SceneGraph. Created in `main.brs`, it owns a single `MainScene`.
* **roMessagePort** — the event loop in `main.brs`. The `while true` loop waits on this port to receive `roSGScreenEvent`, `roSGNodeEvent`, `roInputEvent`, and `roDeviceInfoEvent` messages.
* **Tasks** — SceneGraph `Task` nodes run BrightScript on a background thread. They expose observable fields so the scene thread can react to results without blocking the UI.
* **observeField / onChange** — the wiring mechanism. When a field value changes, RSG calls the registered handler on the same thread as the observer.
* **m.global** — a globally shared `roSGNode` accessible from every component and task in the app. `AppState.brs` initialises all fields on it at startup.

## Source layer (`source/`)

Code under `source/` runs on the render thread inside `MainScene`. It is loaded via `<script>` tags in `MainScene.xml`.

| File                        | Role                                                                                                                                                                                                               |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `main.brs`                  | Entry point. Creates `roSGScreen`, instantiates `MainScene`, detects deep links, runs the event loop, and monitors device memory.                                                                                  |
| `AppConstants.brs`          | Single source of truth for all configuration: server URLs, API paths, timeouts, registry keys, UI constants, colour palette, and auth reason codes.                                                                |
| `AppState.brs`              | `GTV_InitGlobalState()` — adds every `m.global` field with its default value. Also contains layout helpers (`GTV_GetLayoutContext`, `GTV_GetSafeArea`) and auth signal classification (`GTV_AuthClassifyFailure`). |
| `utils/Logger.brs`          | `GTV_Log()` (dev only), `GTV_Warn()`, `GTV_Error()` — tagged log functions.                                                                                                                                        |
| `utils/HttpClient.brs`      | Synchronous HTTP wrapper for use inside Task nodes.                                                                                                                                                                |
| `utils/RegistryManager.brs` | Read/write helpers for the Roku persistent registry (`roRegistrySection`). Stores credentials, last server URL, last channel index, safe-margin percentage, and server profiles.                                   |
| `utils/ServerManager.brs`   | Server profile CRUD, URL normalisation, and health-check probing.                                                                                                                                                  |
| `utils/M3UParser.brs`       | Parses M3U8 playlist files into channel and category arrays.                                                                                                                                                       |
| `utils/HealthCheck.brs`     | HTTP health-check against `/health` with configurable timeout.                                                                                                                                                     |
| `utils/NetworkDetector.brs` | `GTV_IsOnline()` — checks the active network interface without making an HTTP request.                                                                                                                             |

## Components layer (`components/`)

<CardGroup cols={2}>
  <Card title="Screens" icon="display">
    `MainScene`, `SplashScreen`, `OnboardingScreen`, `LoginScreen`, `MainScreen`, `PlayerScreen`, `SettingsScreen` — the full user-facing UI hierarchy from launch through playback.
  </Card>

  <Card title="Background tasks" icon="gear">
    `HandshakeTask`, `AuthTask`, `PlaylistTask`, `ConnectivityTask`, `AdsPollingTask`, `MetricsTask`, `ServerProbeTask` — all network I/O runs off the render thread.
  </Card>

  <Card title="Ad system" icon="rectangle-ad">
    `AdManager` coordinates three format renderers: `AdFormatA`, `AdFormatB`, and `AdFormatC`. Format C reduces the video viewport height. Ad data arrives from `AdsPollingTask` every 10 seconds.
  </Card>

  <Card title="Overlays" icon="layer-group">
    `channelBanner` shows channel name, number, logo, and live status. `numberOverlay` handles direct numeric channel entry. Both overlay the live video during playback.
  </Card>
</CardGroup>

## Component responsibilities

| Component          | Type         | Responsibility                                                                                                                                                              |
| ------------------ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MainScene`        | Scene (root) | Global state init, screen orchestration, task lifecycle, deep link routing, session auth checks, exit flow                                                                  |
| `SplashScreen`     | Screen       | Displays the launch splash for `SPLASH_MS` (1500 ms), then fires `splashDone`                                                                                               |
| `OnboardingScreen` | Screen       | First-run welcome screen; routes to `LoginScreen` via `goToLogin`                                                                                                           |
| `LoginScreen`      | Screen       | On-device credential form; requests Roku email via `ChannelStore.getUserData`; runs `AuthTask`                                                                              |
| `MainScreen`       | Screen       | Category-tabbed channel grid; signals `AppLaunchComplete` beacon on first channel load; doubles as the channel-selection overlay during playback                            |
| `PlayerScreen`     | Screen       | HLS playback via `Video` node; hosts `AdManager`, channel banner, number overlay, error and offline dialogs; spawns `ConnectivityTask`, `AdsPollingTask`, and `MetricsTask` |
| `SettingsScreen`   | Screen       | Safe-area adjustment, channel refresh, logout, server management (admin-unlocked)                                                                                           |
| `HandshakeTask`    | Task         | Discovers the active server via health-check across the server list; writes `activeServer` to `m.global`                                                                    |
| `AuthTask`         | Task         | Authenticates username/password against `/auth/{user}/{pass}`; returns success or failure with a classified reason code                                                     |
| `PlaylistTask`     | Task         | Downloads and parses the M3U8 playlist from `/auth/{user}/{pass}/playlist/m3u8/hls`; returns `channels` and `categories` arrays                                             |
| `ConnectivityTask` | Task         | Polls internet reachability every `NET_RETRY_MS` (30 s); updates `m.global.hasInternet`                                                                                     |
| `AdsPollingTask`   | Task         | Performs ads handshake, then polls `/app/ads/active` every `ADS_POLL_MS` (10 s); signals inactivity and session invalidation                                                |
| `MetricsTask`      | Task         | Batches and POSTs impression events to `/api/v1/app/metrics/track`                                                                                                          |
| `ServerProbeTask`  | Task         | One-shot health-check for a given server URL; used by the settings server-test action                                                                                       |
| `AdManager`        | Component    | Receives ad snapshots; selects and renders the correct format node; manages video viewport reduction for Format C                                                           |
| `AdFormatA/B/C`    | Component    | Individual ad renderers; Format C emits `videoHeightReduction` and `videoOffsetY` to compress the video area                                                                |

## Utility layer

All utilities are pure BrightScript functions loaded as `<script>` includes into `MainScene.xml`. They carry no node state and can be called from any script that shares the same component scope.

```brightscript theme={null}
' Logger — three severity levels
GTV_Log("MainScene", "init")       ' dev build only
GTV_Warn("PlayerScreen", "No net") ' always printed
GTV_Error("AuthTask", "401")       ' always printed

' HttpClient — synchronous request inside a Task
res = GTV_HttpGet(url, headers, timeoutMs)

' RegistryManager — persistent storage
creds = GTV_RegLoadCredentials()   ' returns { username, password } or invalid
GTV_RegSaveCredentials(user, pass)
GTV_RegSaveLastServer(url)

' Layout helpers — resolution-aware scaling
ctx = GTV_GetLayoutContext(m.top)  ' returns safeX, safeY, safeW, safeH, sx, sy
x   = GTV_LX(ctx, 122)            ' design-space x → screen pixels
```

## Design resolution and safe area

`GTV_GetDesignSize()` detects the display mode (`roDeviceInfo.GetDisplayMode()`) and returns `1920×1080` or `1280×720`. `GTV_GetSafeArea()` applies the `uiSafeMarginPct` registry value (0–10 %) to compute inset bounds. All screens call `ApplyResponsiveLayout()` on init and whenever `currentDesignResolution` changes, keeping the layout consistent across FHD and HD Roku models.
