//! Homescreen — the wallpaper-with-grid surface that sits behind every
//! application window.
//!
//! Module split mirrors the launcher: state and lifecycle in this file,
//! pure presentation in [`view`], pixel-true sizing primitives in
//! [`geometry`], drop-target hit-testing in [`drop`]. External callers
//! still reach for `homescreen::DragOrigin`, `homescreen::drop_target`,
//! etc. — the public re-exports below preserve the pre-split flat path.

mod drop;
pub( crate ) mod geometry;
mod view;

use std::sync::Arc;

use crate::assets;
use crate::config::Config;
use crate::launcher::AppEntry;
use crate::launcher::icon_cache::IconCache;

// ─── Public re-exports ──────────────────────────────────────────────────────
//
// The flat `homescreen::FOO` path is what the rest of the crate (and
// `app.rs`, `drag.rs`, `editmenu.rs`, …) used before the split — keep
// every external symbol reachable through the same path so no caller
// has to learn the new submodule layout.

pub use drop::
{
	dock_capacity,
	dock_item_anchor,
	dock_temp_anchor,
	dock_preview_index,
	drop_target,
	grid_cell_anchor,
	DragOrigin,
	DropTarget,
};

pub( crate ) use geometry::dock_band;

// ─── State ─────────────────────────────────────────────────────────────────

/// Homescreen state — the desktop-with-wallpaper view shown behind every app
/// window. Owns the wallpaper bundle and the launcher logo. Everything
/// else (grid contents, dock contents, active page) lives in the persisted
/// [`Config`] so user edits survive restarts.
pub struct Homescreen
{
	/// Wallpaper for the homescreen. Wrapped in an `Arc` so a fresh
	/// bundle decoded after a theme flip can be installed via a single
	/// pointer move from `apply_theme_mode`. The launcher used to share
	/// this `Arc`, but it now paints the **lockscreen** variant of the
	/// active mode and owns its own bundle — keeping the wallpapers
	/// distinct lets the launcher reveal feel like a separate "card"
	/// over the desktop instead of a slightly-tinted version of the
	/// same imagery.
	wallpaper: Arc<ltk::WallpaperBundle>,
	/// Logo decoded once at startup, used as the dock launcher button.
	logo: ( Arc<Vec<u8>>, u32, u32 ),
}

impl Homescreen
{
	pub fn new( wallpaper: Arc<ltk::WallpaperBundle> ) -> Self
	{
		Self
		{
			wallpaper,
			logo: assets::decode_launcher_icon(),
		}
	}

	/// Replace the wallpaper bundle. Called by the shell after a Light/Dark
	/// flip with a freshly decoded `Arc<WallpaperBundle>`.
	pub fn set_wallpaper( &mut self, wallpaper: Arc<ltk::WallpaperBundle> )
	{
		self.wallpaper = wallpaper;
	}

	/// Re-decode the launcher logo for the currently active theme mode.
	/// Called alongside `set_wallpaper` on Light/Dark flip so the dock
	/// button switches between `branding/light/launcher.svg` and
	/// `branding/dark/launcher.svg`.
	pub fn reload_logo( &mut self )
	{
		self.logo = assets::decode_launcher_icon();
	}

	/// Build the homescreen view. Pure delegation — see
	/// [`view::build`] for the actual rendering pipeline.
	pub fn view<Message: Clone + 'static>(
		&self,
		config:           &Config,
		all_apps:         &[ AppEntry ],
		icon_cache:       &mut IconCache,
		default_icon:     &( Arc<Vec<u8>>, u32, u32 ),
		screen_width:     u32,
		screen_height:    u32,
		current_page:     usize,
		drag_dx:          f32,
		pages_on_main:    bool,
		launcher_msg:     Message,
		on_launch:        impl Fn( String ) -> Message + Clone + 'static,
		on_activate:      impl Fn( String ) -> Message + Clone + 'static,
		on_long_press:    impl Fn( DragOrigin, String ) -> Message + Clone + 'static,
		on_drag_start:    impl Fn( DragOrigin, String ) -> Message + Clone + 'static,
		on_page_select:   impl Fn( usize ) -> Message + Clone + 'static,
		dock_preview:     Option<usize>,
		running:          &crate::running::RunningApps,
	) -> ltk::Element<Message>
	{
		view::build(
			self, config, all_apps, icon_cache, default_icon,
			screen_width, screen_height,
			current_page, drag_dx, pages_on_main,
			launcher_msg, on_launch, on_activate,
			on_long_press, on_drag_start,
			on_page_select, dock_preview,
			running,
		)
	}

	/// Build one mobile page laid out for its sliding subsurface — a
	/// screen-sized, transparent surface with the page's grid in its usual top
	/// region. Pure delegation to [`view::build_page_subsurface`].
	#[ allow( clippy::too_many_arguments ) ]
	pub( crate ) fn page_subsurface_view<Message: Clone + 'static>(
		&self,
		config:        &Config,
		all_apps:      &[ AppEntry ],
		icon_cache:    &mut IconCache,
		screen_width:  u32,
		screen_height: u32,
		page_idx:      usize,
		on_launch:     impl Fn( String ) -> Message + Clone + 'static,
		on_long_press: impl Fn( DragOrigin, String ) -> Message + Clone + 'static,
		on_drag_start: impl Fn( DragOrigin, String ) -> Message + Clone + 'static,
	) -> ltk::Element<Message>
	{
		view::build_page_subsurface(
			self, config, all_apps, icon_cache,
			screen_width, screen_height, page_idx,
			on_launch, on_long_press, on_drag_start,
		)
	}

	// ── view-side accessors (used by `view::*`) ──────────────────

	/// Borrow the homescreen wallpaper bundle. Default-private so only
	/// the homescreen submodule tree (`view`, `drop`, `geometry`) can
	/// reach the bundle without going through `set_wallpaper`. Callers
	/// outside the module work through the public lifecycle entry
	/// points instead.
	fn wallpaper( &self ) -> &ltk::WallpaperBundle { &self.wallpaper }

	/// Borrow the launcher logo RGBA + dimensions. Used by the
	/// renderer to paint the dock's leftmost button.
	pub( crate ) fn logo( &self ) -> &( Arc<Vec<u8>>, u32, u32 ) { &self.logo }
}
