# KTag King of the Hill Subapp

A Jetpack Compose Android application for running King of the Hill games with KTag devices.

## Overview

The King of the Hill (KOTH) app manages timed team-based games where teams compete for possession of the "hill." The app scans for KTag devices, tracks which team has more players present, and accumulates time for the team in possession. At game end, the team with more accumulated time wins.

## Architecture

The app follows the **MVVM (Model-View-ViewModel)** pattern with Jetpack Compose for the UI layer.

```
┌─────────────────────────────────────────────────────────┐
│                    KothActivity                         │
│                   (Compose Host)                        │
└─────────────────────┬───────────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────────┐
│                   KothViewModel                         │
│  • State machine (Idle→Initiating→Countdown→Play→End)   │
│  • Timer management (coroutines)                        │
│  • BLE scanning & advertising                           │
│  • MQTT integration                                     │
└─────────────────────┬───────────────────────────────────┘
                      │
┌─────────────────────▼───────────────────────────────────┐
│                    UI Layer                             │
│  KothScreen → GameTimer + StatusDisplay + FABs          │
└─────────────────────────────────────────────────────────┘
```

## File Structure

```
src/main/java/club/clubk/ktag/apps/koth/
├── KothActivity.kt         # Compose activity with permissions
├── KothViewModel.kt        # State machine, timer, BLE, MQTT
├── KothState.kt            # Sealed classes for states/events
├── GameData.kt             # Score tracking data class
├── KTagDeviceContact.kt    # Device data class
├── KothSubApp.kt           # Subapp registration
├── KothSettingsActivity.kt
├── KothInitializer.kt
├── HexUtils.java           # Hex conversion
├── ble/
│   └── Packet.java         # BLE packet parsing
├── mqtt/
│   └── KTagMQTTServer.java # MQTT client
└── ui/
    ├── KothScreen.kt       # Main game screen
    ├── GameTimer.kt        # Seven Segment countdown display
    ├── StatusDisplay.kt    # Fourteen Segment status text
    ├── GameControlFabs.kt  # Play/Stop/Reset FABs
    └── theme/
        ├── Theme.kt
        ├── Color.kt
        └── Type.kt         # Custom segment fonts
```

## State Machine

The game progresses through five states:

```
┌──────┐  START   ┌────────────┐  TIMEOUT  ┌──────────────┐
│ IDLE │─────────▶│ INITIATING │──────────▶│ COUNTING_DOWN│
└──────┘          └────────────┘           └──────────────┘
   ▲                                              │
   │ RESET                                 TIMEOUT│
   │                                              ▼
┌──────────┐  TIMEOUT/STOP                   ┌─────────┐
│ FINISHED │◀───────-─────----------------───│ PLAYING │
└──────────┘                                 └─────────┘
```

| State | Description |
|-------|-------------|
| `Idle` | Waiting to start, shows countdown delay |
| `Initiating` | Broadcasting game start, countdown to begin |
| `CountingDown` | 5-second countdown before play |
| `Playing` | Active game, tracking possession |
| `Finished` | Game over, showing results |

## Key Components

### KothViewModel

Manages game state and logic:

- **State Machine**: Transitions between game states via sealed classes
- **Timer**: Coroutine-based 100ms tick for accurate timing
- **BLE Scanning**: Detects nearby KTag devices and their team
- **BLE Advertising**: Broadcasts "Instigating Game" packets
- **Possession Tracking**: Determines which team has more players
- **MQTT**: Publishes possession updates

### GameData

Immutable data class tracking team scores:

```kotlin
data class GameData(
    val redTeamMillis: Long,
    val blueTeamMillis: Long
)
```

### UI Features

| Component | Description |
|-----------|-------------|
| `GameTimer` | Seven Segment font countdown display |
| `StatusDisplay` | Fourteen Segment font for status/scores |
| `GameControlFabs` | Animated FABs based on game state |
| Background | Animates red/blue/white based on possession |
| Tower Images | Crossfade to winner's tower at game end |

## Settings

| Setting | Description |
|---------|-------------|
| `countdown_delay_s` | Seconds before countdown starts |
| `game_duration_min` | Game length in minutes |
| `mqtt_*` | MQTT server configuration |

## Dependencies

- Jetpack Compose (Material3)
- ViewModel + Compose integration
- BLE (BluetoothLeScanner, BluetoothLeAdvertiser)
- MQTT (Paho Android client)
- Custom fonts (Seven Segment, Fourteen Segment)
