//! Shell-wide message enum.
//!
//! `Message` is the single union of every event that routes through
//! [`ltk::App::update`]. It lives in its own module so helper modules
//! (`paging.rs`, `drag.rs`, `overlays.rs`, …) can emit or match on
//! variants without pulling in the whole `app` module.

use crate::homescreen::DragOrigin;
use crate::powermenu::PowerAction;
use crate::system::toggles::ToggleId;

#[derive( Clone )]
pub enum Message
{
	// System updates
	Tick,
	AnimationFrame,
	/// External change to `org.gnome.desktop.interface color-scheme`
	/// (gnome-control-center, another shell, a `gsettings set` from a
	/// terminal, …). Crustace's own QS Dark toggle also rounds through
	/// gsettings so this variant fires for in-shell flips too; the
	/// handler compares against `current_mode` and no-ops on redundant
	/// sets.
	ExternalColorScheme( ltk::ThemeMode ),

	// Top bar actions
	OpenQuickSettings,
	StartQuickSettingsWipe,
	QuickSettingsWiping( f32 ),
	FinishQuickSettingsWipe { committed: bool, progress: f32 },
	ToggleCalendar,
	CalendarNavigate { year: i32, month: u8 },

	// Dock auto-hide (forge bottom-edge recogniser → IPC).
	RevealDock,
	HideDock,

	// Launcher
	LaunchApp( String ),
	LauncherSearchSubmit,
	LauncherSearchPrev,
	LauncherSearchNext,
	LauncherSearchRowUp,
	LauncherSearchRowDown,
	/// Bring the first window of `app_id` to the front via forge IPC.
	/// Fired by dock icons when the app is already running, so a
	/// click reactivates the existing window instead of spawning a
	/// second instance.
	ActivateApp( String ),
	/// New text in the launcher's search box. Fired by the search field
	/// on every keystroke; the shell writes it into the launcher's
	/// `search_query` so the next view rebuild filters the grid.
	LauncherSearch( String ),
	/// Open the edit-mode context menu for a homescreen icon (Dock or
	/// Grid origin). Fires on touch hold or right-click; never armed
	/// for Launcher icons because launcher items are append-only and
	/// have no menu. Sets `edit_mode = true` and stores the menu in
	/// `edit_menu`. The drag arm — if any — is a separate
	/// [`StartDrag`](Self::StartDrag) sent in the same batch.
	ShowEditMenu { origin: DragOrigin, app_id: String },
	/// Arm a drag of an icon. Fires on touch hold (alongside
	/// [`ShowEditMenu`](Self::ShowEditMenu) for dock / grid items, or
	/// alone for launcher items) and on mouse left-button motion past
	/// the drag-promotion threshold (alone, no menu). The shell tracks
	/// the finger until the next release, at which point
	/// [`ltk::App::on_drop`] applies the drop (or discards it if the
	/// user never crossed the drag threshold).
	StartDrag { origin: DragOrigin, app_id: String },

	// Edit mode — context menu actions. The operand is always the item
	// carried by [`crate::state::Crustace::edit_menu`]; these variants carry
	// no payload so the menu state remains the single source of truth.
	EditMenuInfo,
	EditMenuRemove,
	EditMenuUninstall,
	EditMenuClose,
	EditMenuCancel,
	/// Dismiss the app-info overlay opened from the edit menu.
	CloseAppInfo,

	// Quick settings — connectivity
	SetBrightness( f32 ),
	SetVolume( f32 ),
	CloseQuickSettings,

	// Quick settings — additional toggles
	Toggle( ToggleId ),

	// Power menu
	ShowPowerMenu,
	PowerAction( PowerAction ),

	// App switcher
	ToggleOverview,
	ToggleLauncher,
	StartLauncherWipe,
	LauncherWiping( f32 ),
	FinishLauncherWipe { committed: bool, progress: f32 },
	ShowHomescreen,

	/// Tap on a page-indicator pill: jump straight to page `usize` from
	/// wherever the user currently is. The settle animation handles the
	/// slide so a multi-page jump still reads as a smooth slide rather
	/// than a teleport.
	GoToPage( usize ),

	// Media controls
	MediaPlayPause,
	MediaNext,
	MediaPrevious,
	/// Pushed by `poll_external` when `mpris_poller.try_recv` returns
	/// a fresh `MediaState` (track change, play/pause flip, new active
	/// player, cover art arrived). The `update` handler is a no-op —
	/// the state mutation already happened in `poll_external`. The
	/// message exists purely so the run loop's `apply_invalidation`
	/// gets a chance to fire and the QS overlay redraws with the
	/// updated card. `invalidate_after` scopes it to the QS overlay.
	MediaStateChanged,

	// WiFi picker
	OpenWifiPicker,
	ConnectWifi( String ),

	// Bluetooth picker
	OpenBluetoothPicker,
	ConnectBluetooth( String ),

	// Settings — opens the system settings app. Currently a stub: the
	// handler logs the intent and closes the QS panel; replace with an
	// `Eydos Settings` D-Bus activation once that app exists.
	OpenSettings,

	// Hardware buttons
	HwVolumeUp,
	HwVolumeDown,
	HwMute,
	HwBrightnessUp,
	HwBrightnessDown,

	// Wayland `ext-foreign-toplevel-list-v1`. ltk forwards every open /
	// update / close event it sees from the compositor; we translate it
	// here into a `running_apps` mutation so the dock's indicator dots
	// and temporary slot column always match what the compositor says
	// is live.
	ToplevelEvent( ltk::ToplevelEvent ),
}
