// Shell assets — icons embedded from ltk's theme catalogue

use std::sync::Arc;

// ─── Filled symbolic icons (shell chrome) ────────────────────────────────────
//
// Sourced from ltk's icon catalogue. All filled-style: tinted on use via
// `ltk::tint_symbolic` so the SVG fill colour is irrelevant.
// The `concat!(env!(…))` form lets us reach across the workspace boundary
// without copying the SVGs into the crustace source tree.

pub const WIFI_FULL_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/system/wifi-signal-full.svg" )
);
pub const MOBILE_DATA_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/system/traffic.svg" )
);
pub const BLUETOOTH_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/system/bluetooth-not-connected.svg" )
);
pub const SETTINGS_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/customisation/settings.svg" )
);
pub const AIRPLANE_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/system/airplane-mode.svg" )
);
pub const NOTIFICATIONS_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/communication/notifications.svg" )
);

// Slider glyphs overlaid at the bottom of each QS vslider pill.
pub const BRIGHTNESS_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/brightness-maximum.svg" )
);
pub const SPEAKER_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/speaker-high.svg" )
);

// Min/mute counterparts for desktop QS horizontal slider pills.
pub const BRIGHTNESS_LOW_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/brightness-minimum.svg" )
);
pub const SPEAKER_MUTE_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/speaker-mute.svg" )
);

// Transport glyphs for the QS media card.
pub const PLAY_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/multimedia/play.svg" )
);
pub const PAUSE_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/multimedia/pause.svg" )
);
pub const PREVIOUS_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/multimedia/previous.svg" )
);
pub const NEXT_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/multimedia/next.svg" )
);

// Launcher left-rail glyphs (logout, settings, suspend, power, launcher
// toggle). Drawn at ~22 px tinted to `palette.text_primary` so they read
// as plain monochrome icons without a pill envelope.
pub const LOGOUT_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/session/log-out.svg" )
);
pub const SUSPEND_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/session/sleep.svg" )
);
pub const REBOOT_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/session/restart.svg" )
);
pub const POWER_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/session/power.svg" )
);
pub const APP_SELECTOR_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/navigation/app-selector.svg" )
);
pub const SEARCH_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/actions/search.svg" )
);

// Round-button glyphs for the second row of the QS toggle bank.
pub const DARK_MODE_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/night-mode.svg" )
);
pub const ROTATION_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/rotation.svg" )
);
pub const VPN_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/system/vpn-connected.svg" )
);
pub const FLASHLIGHT_FILLED: &[u8] = include_bytes!(
	concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/catalogue/filled/hardware/light-mode.svg" )
);

// ─── Decode helpers ──────────────────────────────────────────────────────────

/// Decode an SVG byte slice into (rgba_bytes, width, height) at the requested
/// pixel size. Returns `None` only on a malformed SVG.
///
/// Thin wrapper over [`ltk::decode_svg_bytes`] kept for source compatibility
/// with the rest of crustace; new code can call the ltk function directly.
pub fn decode_svg_bytes( svg_bytes: &[u8], size: u32 ) -> Option<( Arc<Vec<u8>>, u32, u32 )>
{
	ltk::decode_svg_bytes( svg_bytes, size )
}

/// Decode the launcher logo from the active theme at 64 px.
/// Falls back to the default theme's `branding/dark/launcher.svg`
/// embedded at compile time when the active theme has no launcher
/// icon on disk.
pub fn decode_launcher_icon() -> ( Arc<Vec<u8>>, u32, u32 )
{
	const FALLBACK: &[u8] = include_bytes!(
		concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/branding/dark/launcher.svg" )
	);
	let bytes: Vec<u8> = ltk::theme_launcher_icon()
		.and_then( |p| std::fs::read( &p ).ok() )
		.unwrap_or_else( || FALLBACK.to_vec() );
	decode_svg_bytes( &bytes, 64 ).expect( "launcher icon SVG must decode" )
}

/// Decode the default app icon from the active theme at 64 px.
/// Falls back to the default theme's `app-default.svg` embedded at compile time.
pub fn decode_app_default_icon() -> ( Arc<Vec<u8>>, u32, u32 )
{
	const FALLBACK: &[u8] = include_bytes!(
		concat!( env!( "CARGO_MANIFEST_DIR" ), "/../ltk/themes/default/icons/apps/default.svg" )
	);
	let bytes: Vec<u8> = ltk::theme_app_default_icon()
		.and_then( |p| std::fs::read( &p ).ok() )
		.unwrap_or_else( || FALLBACK.to_vec() );
	decode_svg_bytes( &bytes, 64 ).expect( "app-default icon SVG must decode" )
}

/// Build an orientation-aware [`ltk::WallpaperBundle`] for the active theme
/// variant. Resolves through `theme_branding_image("wallpaper", sw, sh)` so
/// a pre-rendered raster (`branding/{mode}/wallpaper/<W>x<H>.webp`) is
/// preferred over the canonical SVG when one covers the surface. Falls
/// back to a solid dark background when the active theme has no wallpaper
/// or the file cannot be read / decoded.
///
/// Pass `(0, 0)` for `(sw, sh)` at startup when the surface size is not
/// yet known; the lookup returns the smallest available raster (typically
/// `1280x720.webp`, ~10 ms decode), avoiding the much slower SVG
/// rasterisation on the hot startup path. The first `on_resize` upgrades
/// to the size-appropriate variant.
///
/// The active theme must already be installed (see `ltk::set_active_document`).
pub fn decode_wallpaper_bundle( sw: u32, sh: u32 ) -> ltk::WallpaperBundle
{
	let path = ltk::theme_branding_image( "wallpaper", sw, sh );
	bundle_from_path_or_solid( path.as_deref() )
}

/// Same as [`decode_wallpaper_bundle`] but reads the lockscreen / greeter
/// image of the active mode. Used by the QS panel so its pull-down
/// background is the (typically darker, quieter) lockscreen crop, not the
/// busy homescreen wallpaper that would clash with the translucent chrome
/// on top.
pub fn decode_lockscreen_bundle( sw: u32, sh: u32 ) -> ltk::WallpaperBundle
{
	let path = ltk::theme_branding_image( "lockscreen", sw, sh );
	bundle_from_path_or_solid( path.as_deref() )
}

/// Longest-edge size used to rasterise SVG wallpapers. 1920 px covers FHD
/// landscape displays at native resolution; portrait crops are taken from
/// this raster.
const WALLPAPER_RASTER_SIZE: u32 = 1920;

/// Load `path` into a [`ltk::WallpaperBundle`], routing `.svg` files
/// through ltk's resvg-backed decoder (the bundle's own `from_path` path
/// only handles raster formats via the `image` crate). Falls back to a
/// solid dark background when the path is missing, unreadable, or fails
/// to decode.
fn bundle_from_path_or_solid( path: Option<&std::path::Path> ) -> ltk::WallpaperBundle
{
	if let Some( p ) = path
	{
		let is_svg = p.extension()
			.and_then( |e| e.to_str() )
			.map( |e| e.eq_ignore_ascii_case( "svg" ) )
			.unwrap_or( false );
		if is_svg
		{
			if let Ok( bytes ) = std::fs::read( p )
			{
				if let Some( decoded ) = ltk::decode_svg_bytes( &bytes, WALLPAPER_RASTER_SIZE )
				{
					return ltk::WallpaperBundle::from_decoded( decoded );
				}
				eprintln!( "crustace: failed to decode wallpaper SVG {}", p.display() );
			}
			else
			{
				eprintln!( "crustace: failed to read wallpaper {}", p.display() );
			}
			return ltk::WallpaperBundle::from_path_or_solid( None, 0x0a, 0x0a, 0x14 );
		}
	}
	ltk::WallpaperBundle::from_path_or_solid( path, 0x0a, 0x0a, 0x14 )
}
