//! Pre-decoded glyphs for the launcher chrome — the desktop left rail
//! (logout, settings, suspend, power off, launcher toggle) plus the
//! search-bar magnifier — together with a per-icon tint cache shared
//! with the renderer.
//!
//! Mirrors `quicksettings::icons` but for the launcher's own asset
//! set. Tinting against `palette.text_primary` happens once per theme
//! flip and is then re-used every frame the colour stays the same;
//! without the cache, the GLES backend's pointer-keyed texture cache
//! would re-upload each glyph per redraw.

use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::Arc;

use crate::assets;
use super::RailIcon;

type RgbaIcon = ( Arc<Vec<u8>>, u32, u32 );

pub( crate ) struct Icons
{
	logout:     Option<RgbaIcon>,
	settings:   Option<RgbaIcon>,
	suspend:    Option<RgbaIcon>,
	reboot:     Option<RgbaIcon>,
	power:      Option<RgbaIcon>,
	app_toggle: Option<RgbaIcon>,
	search:     Option<RgbaIcon>,

	tint_cache: RefCell<HashMap<usize, ( ltk::Color, Arc<Vec<u8>> )>>,
}

impl Icons
{
	pub( crate ) fn new() -> Self
	{
		Self
		{
			logout:     assets::decode_svg_bytes( assets::LOGOUT_FILLED,        48 ),
			settings:   assets::decode_svg_bytes( assets::SETTINGS_FILLED,      48 ),
			suspend:    assets::decode_svg_bytes( assets::SUSPEND_FILLED,       48 ),
			reboot:     assets::decode_svg_bytes( assets::REBOOT_FILLED,        48 ),
			power:      assets::decode_svg_bytes( assets::POWER_FILLED,         48 ),
			app_toggle: assets::decode_svg_bytes( assets::APP_SELECTOR_FILLED,  48 ),
			search:     assets::decode_svg_bytes( assets::SEARCH_FILLED,        48 ),
			tint_cache: RefCell::new( HashMap::new() ),
		}
	}

	pub( crate ) fn rail( &self, which: RailIcon ) -> &Option<RgbaIcon>
	{
		match which
		{
			RailIcon::Logout    => &self.logout,
			RailIcon::Settings  => &self.settings,
			RailIcon::Suspend   => &self.suspend,
			RailIcon::Reboot    => &self.reboot,
			RailIcon::Power     => &self.power,
			RailIcon::AppToggle => &self.app_toggle,
		}
	}

	pub( crate ) fn search( &self ) -> &Option<RgbaIcon> { &self.search }

	/// Tint `raw` with `color`, reusing the previous result when the
	/// same `(input pointer, colour)` pair is already cached. Same
	/// rationale as `quicksettings::icons::Icons::tint_cached`.
	pub( crate ) fn tint_cached( &self, raw: &Arc<Vec<u8>>, color: ltk::Color ) -> Arc<Vec<u8>>
	{
		let key = Arc::as_ptr( raw ) as usize;
		let mut guard = self.tint_cache.borrow_mut();
		if let Some( ( cached_color, cached_buf ) ) = guard.get( &key )
		{
			if *cached_color == color
			{
				return Arc::clone( cached_buf );
			}
		}
		let fresh = Arc::new( ltk::tint_symbolic( &raw[..], color ) );
		guard.insert( key, ( color, Arc::clone( &fresh ) ) );
		fresh
	}
}
