<script lang="ts">
	let log_lvl: number = $state(1);
	interface Props {
		/** @type {import('./$types').LayoutData} */
		data: any;
		children?: import('svelte').Snippet;
	}

	let { data, children }: Props = $props();

	// *** Import Svelte specific
	// import { onMount, tick } from 'svelte';
	import { goto } from '$app/navigation';
	import { sineIn } from 'svelte/easing';

	// *** Import other supporting libraries
	import { liveQuery } from 'dexie';
	import { Drawer, Footer, Modal } from 'flowbite-svelte';
	import { listen, idle, onIdle, restartCountdown } from 'svelte-idle';

	import {
		// Brain,
		// House, Library,
		// RefreshCw,
		Satellite
	} from '@lucide/svelte';

	// *** Import Aether specific variables and functions
	import type { key_val } from '$lib/stores/ae_stores';
	import { ae_util } from '$lib/ae_utils/ae_utils';
	import { api } from '$lib/api/api';
	import { db_events } from '$lib/ae_events/db_events';
	import {
		ae_snip,
		ae_loc,
		ae_sess,
		ae_api,
		ae_trig,
		slct,
		slct_trigger,
		time
	} from '$lib/stores/ae_stores';
	import {
		events_loc,
		events_sess,
		events_slct,
		events_trigger,
		events_trig
	} from '$lib/stores/ae_events_stores';
	// import { events_func } from '$lib/ae_events_functions';

	import Launcher_cfg from '../launcher_cfg.svelte';
	import Launcher_menu from '../launcher_menu.svelte';
	import Launcher_session_view from '../launcher_session_view.svelte';
	import Element_websocket_v2 from '$lib/elements/element_websocket_v2.svelte';

	// *** Set initial variables
	// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
	// $slct.account_id = data.account_id;
	// console.log(`$slct.account_id = `, $slct.account_id);
	let ae_acct = data[$slct.account_id];
	// console.log(`ae_acct = `, ae_acct);

	import {
		// devicePixelRatio,
		// innerHeight,
		// innerWidth,
		online
		// outerHeight,
		// outerWidth,
		// screenLeft,
		// screenTop,
		// scrollX,
		// scrollY
	} from 'svelte/reactivity/window';

	// const online: ReactiveValue<boolean | undefined>;

	$ae_sess.disable_sys_nav = true;
	$ae_sess.disable_sys_header = true;
	$ae_sess.disable_sys_footer = true;

	// This is a just in case check...
	if (!$events_loc?.launcher) {
		$events_loc.launcher = {
			app_mode: 'default',

			controller: 'local',
			controller_group_code: 'launcher-00',
			ws_connect: false,

			hide_drawer__cfg: true,
			hide_drawer__debug: true
		};
	}

	// svelte-ignore state_referenced_locally
	if (log_lvl > 1) {
		console.log(`$events_loc.launcher:`, $events_loc.launcher);
	}
	// svelte-ignore state_referenced_locally
	if (log_lvl) {
		console.log(`event_id: ${data.params.event_id}`);
		console.log(`event_location_id: ${data.params.event_location_id}`);
		console.log(`event_session_id: ${data.url.searchParams.get('session_id')}`);
	}
	$events_slct.event_id = data.params.event_id;
	$events_slct.event_location_id = data.params.event_location_id;
	$events_slct.event_session_id = data.url.searchParams.get('session_id');

	// console.log(`ae_acct.slct.event_id:`, ae_acct.slct.event_id);
	// $events_slct.event_id = ae_acct.slct.event_id;
	// $events_slct.event_obj = ae_acct.slct.event_obj;
	$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li ?? [''];
	$events_slct.id_li__event_location = ae_acct.slct.id_li__event_location ?? [''];
	// svelte-ignore state_referenced_locally
	if (log_lvl > 1) {
		console.log(`$events_slct.event_location_obj_li:`, $events_slct.event_location_obj_li);
		console.log(`$events_slct.id_li__event_location:`, $events_slct.id_li__event_location);
	}

	// *** Functions and Logic

	// Event
	let lq__event_obj = $derived(
		liveQuery(async () => {
			if (log_lvl) {
				console.log(`lq__event_obj: event_id = ${$events_slct?.event_id}`);
			}

			let results = await db_events.event.get($events_slct?.event_id ?? ''); // null or undefined does not reset things like '' does
			if (log_lvl) {
				console.log(`lq__event_obj: results = `, results);
			}
			// tmp_event_obj = { ...results };

			// Check if results are different than the current session version stored under $events_slct
			if ($events_slct.event_obj && results) {
				if (JSON.stringify($events_slct.event_obj) !== JSON.stringify(results)) {
					$events_slct.event_obj = { ...results };
					if (log_lvl) {
						console.log(
							`Session slct stored version has changed for ID = ${$events_slct.event_id}`,
							$events_slct.event_obj
						);
					}
				} else {
					if (log_lvl) {
						console.log(
							`Session slct stored version has not changed for ID = ${$events_slct.event_id}`
						);
					}
				}
			}

			return results;
		})
	);

	// Event Device
	let lq__event_device_obj = $derived(
		liveQuery(async () => {
			if (log_lvl) {
				console.log(`lq__event_device_obj: event_device_id = ${$events_slct?.event_device_id}`);
			}
			let results = await db_events.device.get($events_slct.event_device_id);
			if (log_lvl) {
				console.log(`lq__event_device_obj: results = `, results);
			}

			// Check if results are different than the current session version stored under $events_slct
			if ($events_slct.event_device_obj && results) {
				if (JSON.stringify($events_slct.event_device_obj) !== JSON.stringify(results)) {
					$events_slct.event_device_obj = { ...results };
					if (log_lvl) {
						console.log(
							`Device slct stored version has changed for ID = ${$events_slct.event_device_id}`,
							$events_slct.event_device_obj
						);
					}
				} else {
					if (log_lvl > 1) {
						console.log(
							`Device slct stored version has not changed for ID = ${$events_slct.event_device_id}`
						);
					}
				}
			}

			return results;
		})
	);

	// Event File - For Event
	let lq__event_event_file_obj_li = $derived(
		liveQuery(async () => {
			let results = await db_events.file
				.where('for_id_random')
				.equals($events_slct.event_id ?? '')
				.sortBy('filename');

			return results;
		})
	);

	// Event File - For Location
	let lq__location_event_file_obj_li = $derived(
		liveQuery(async () => {
			let results = await db_events.file
				// .where('event_location_id_random')
				.where('for_id_random')
				.equals($events_slct.event_location_id ?? '')
				.sortBy('filename');

			return results;
		})
	);

	// Event Location
	let lq__event_location_obj = $derived(
		liveQuery(async () => {
			let results = await db_events.location.get($events_slct.event_location_id);

			return results;
		})
	);

	let lq__event_location_obj_li = $derived(
		liveQuery(async () => {
			let results = await db_events.location
				.where('event_id')
				.equals($events_slct.event_id)
				.sortBy('name');

			return results;
		})
	);

	// Event Session
	let lq__event_session_obj = $derived(
		liveQuery(async () => {
			let results = await db_events.session.get($events_slct.event_session_id);

			return results;
		})
	);

	// let lq__event_session_obj_li = $derived(liveQuery(async () => {
	//     let results = await db_events.session
	//         // .bulkGet(event_session_id_random_li);
	//         .where('event_location_id')
	//         .equals($events_slct.event_location_id)
	//         .sortBy('name');

	//     return results;
	// }));

	// let lq__event_session_obj_li = $derived(liveQuery(async () => {
	//     let results = await db_events.session
	//         .where('event_location_id')
	//         .equals($events_slct.event_location_id)
	//         // .and((x) => (x.archive_on === null || x.archive_on > (new Date()).toISOString()))
	//         // .and((x) => (x.archive_on === null || x.archive_on > (new Date()).toISOString())) // null or future events only
	//         // .and((x) => (x.archive_on < (new Date()).toISOString())) // past events only
	//         // .and((x) => (x.archive_on > (new Date()).toISOString())) // future events only
	//         // .orderBy('updated_on')
	//         // .toArray()
	//         .reverse()
	//         // .limit($idaa_loc.bb.qry__limit)
	//         .sortBy('name');
	//         // .sortBy('tmp_sort_1');
	//         // .sortBy('updated_on');
	//         // .sortBy('updated_on, created_on');
	//         // .sortBy('[updated_on+created_on]');
	//         // .sortBy('[created_on+updated_on]');

	//     return results;
	// }));

	let lq__event_session_obj_li = $derived(
		liveQuery(async () => {
			log_lvl = 1;

			if (log_lvl) {
				console.log(`LQ - $lq__event_obj.cfg_json = `, $lq__event_obj?.cfg_json);
				console.log(`LQ - $events_loc.filter__category_code = `, $events_loc.filter__category_code);
			}

			if ($events_sess.session_li_trigger && !$events_sess?.session_li) {
				$events_sess.session_li = null;
				$events_sess.session_li_trigger = false;
			}

			let results;

			if ($events_sess?.session_li && $events_sess?.session_li?.length) {
				// if (log_lvl) {
				//     console.log(`LQ - Using $events_sess.session_li to get event sessions.`);
				// }
				// // $events_sess.session_li_trigger = false;
				// let event_session_id_random_li = []; // This is to prevent the array from constantly updating and triggering the liveQuery.
				// for (let i = 0; i < $events_sess?.session_li.length; i++) {
				//     let event_session_obj = $events_sess?.session_li[i];
				//     let event_session_id_random = event_session_obj.event_session_id_random;
				//     event_session_id_random_li.push(event_session_id_random);
				// }
				// // let event_session_id_random_li = tmp_li;
				// results = await db_events.session
				//     .bulkGet(event_session_id_random_li);
				// } else if ($lq__event_obj?.cfg_json?.session_group_sort === 'DESC') {
				//     if (log_lvl) {
				//         console.log(`LQ - Using DESC sort for Event Session list event_id: ${$events_slct?.event_id}`);
				//     }
				//     results = await db_events.session
				//         // .orderBy('updated_on')
				//         .where('event_id')
				//         .equals($events_slct?.event_id ?? '') // null or undefined does not reset things like '' does
				//         .reverse()
				//         // .sortBy('tmp_sort_2');
				//         .sortBy('updated_on');
				//         // .sortBy('title');
				// } else if ($events_loc.filter__category_code && $events_loc.filter__category_code.length > 0) {
				//     if (log_lvl) {
				//         console.log(`LQ - Using category filter: ${$events_loc.filter__category_code}`);
				//     }
				//     results = await db_events.session
				//         .where('event_id')
				//         .equals($events_slct?.event_id ?? '') // null or undefined does not reset things like '' does
				//         .and(session => session.category_code === $events_loc.filter__category_code)
				//         .reverse()
				//         .sortBy('tmp_sort_1');
			} else if ($events_slct.event_location_id) {
				if (log_lvl) {
					// console.log(`$lq__event_obj.cfg_json = `, $lq__event_obj?.cfg_json);
					console.log(
						`LQ - Using default sort for Event Session list event_id: ${$events_slct?.event_id}`
					);
				}
				results = await db_events.session
					.where('event_location_id')
					.equals($events_slct.event_location_id)
					// .where('event_id')
					// .equals($events_slct?.event_id ?? '') // null or undefined does not reset things like '' does
					.reverse()
					.sortBy('name');
				// .sortBy('tmp_sort_1');
				// .sortBy('updated_on');
			}

			// Check if results are different than the current session version stored under $events_slct
			if (
				$events_slct.event_session_obj_li &&
				JSON.stringify($events_slct.event_session_obj_li) !== JSON.stringify(results)
			) {
				$events_slct.event_session_obj_li = [...results];
				if (log_lvl) {
					console.log(
						`Session slct li stored version has changed for ID = ${$events_slct.event_id}`,
						$events_slct.event_session_obj_li
					);
				}
			} else {
				if (log_lvl > 1) {
					console.log(
						`Session slct li stored version has not changed for ID = ${$events_slct.event_id}`
					);
				}
			}

			return results;
		})
	);

	// $: if (!$events_sess.launcher.modal__open) {
	//     if ($events_loc.launcher.controller == 'local_push' && $events_sess.launcher.ws_connect_status == 'connected') {
	//         console.log(`Local Push Controller Command: ae_close:event_file_modal`);
	//         $events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
	//         $events_sess.launcher.controller_trigger_send = true;
	//     }
	// }

	let ae_promises: key_val = {
		slct_event_session_id: null,
		slct_event_presentation_li: null
	};

	let trigger_handle_ws_conn = $state(false);
	let trigger_handle_ws_recv = $state(false);
	let trigger_handle_ws_sent = $state(false);

	/* *** BEGIN *** Handle WebSocket events */
	function handle_ws_conn(ws_conn_status: any) {
		log_lvl = 1;
		if (log_lvl) {
			console.log('*** handle_ws_conn() ***', ws_conn_status);
		}

		if (ws_conn_status.status == 'connected') {
			$events_sess.launcher.ws = {}; // Reset WS related values on a new connection.
			$events_sess.launcher.ws.status = 'connected';
		} else {
			$events_sess.launcher.ws = {}; // Reset WS related values when disconnected connection.
			$events_sess.launcher.ws.status = 'disconnected';
		}
		$events_sess.launcher = $events_sess.launcher;
	}

	// This client received a WebSocket message.
	// When this is called something seems to go wrong. It creates a loop when connected.
	function handle_ws_recv(ws_recv_status: any) {
		log_lvl = 1;
		if (log_lvl) {
			console.log('*** handle_ws_recv() ***', ws_recv_status);
		}

		if (ws_recv_status.type == 'cmd' && ws_recv_status.cmd) {
			let cmd = ws_recv_status.cmd;
			// console.log(cmd);

			if ($events_loc.launcher.controller != 'remote') {
				if (log_lvl) {
					console.log('Ignoring WS command. Launcher is not set to be remotely controlled.', cmd);
				}
				return;
			}

			// AE Load (event session ID)
			if (cmd.startsWith('ae_load:')) {
				let cmd_parts = cmd.split(':');
				let obj_parts = cmd_parts[1].split('=');
				let obj_type = obj_parts[0];
				let obj_id = obj_parts[1];
				if (log_lvl) {
					console.log(`ae_load: ${obj_type} ${obj_id}`);
				}
				if (log_lvl > 1) {
					console.log(cmd);
				}

				if (obj_type == 'event_session') {
					$events_slct.event_session_id = obj_id;
					// $slct_trigger = 'event_session';
					// $events_sess.launcher.show_launcher_message = false;

					// data.url.searchParams.set('session_id', $events_slct.event_session_id);

					// let new_url = data.url.toString();
					// console.log(new_url);
					// goto(new_url, {replaceState: false});

					// ae_promises.slct_event_session_id = events_func.load_ae_obj_id__event_session({
					//     api_cfg: $ae_api,
					//     event_session_id: $events_slct.event_session_id,
					//     inc_file_li: true,
					//     inc_presentation_li: true,
					//     try_cache: true,
					//     log_lvl: log_lvl
					// })
					// .then(async (load_results) => {

					// });
					// tick();
					console.log(`Current URL`, data.url);
					let new_url = new URL(data.url);
					new_url.pathname = `/events/${$lq__event_session_obj?.event_id}/launcher/${$lq__event_session_obj?.event_location_id}`;
					new_url.searchParams.set('session_id', $events_slct.event_session_id);
					console.log(`New URL: ${new_url}`);
					let new_url_str = new_url.toString();
					goto(new_url_str, { replaceState: false });
				}
				// AE Download (event file ID)
				// This does not yet work with the native app caching.
			} else if (cmd.startsWith('ae_download:')) {
				log_lvl = 1;

				let cmd_parts = cmd.split(':');
				let obj_parts = cmd_parts[1].split('=');
				let obj_type = obj_parts[0];
				let obj_id = obj_parts[1];
				let obj_filename = cmd_parts[2];
				let obj_extension = cmd_parts[3];

				if (log_lvl) {
					console.log(`ae_download: ${obj_type} ${obj_id} ${obj_filename} ${obj_extension}`);
				}
				if (log_lvl > 1) {
					console.log(cmd);
				}

				ae_promises[obj_id] = api.download_hosted_file({
					api_cfg: $ae_api,
					hosted_file_id: obj_id, // +'x'
					return_file: true,
					filename: `${obj_filename}`,
					auto_download: true,
					log_lvl: 1
				});

				// AE Open (event file ID)
			} else if (cmd.startsWith('ae_open:')) {
				let cmd_parts = cmd.split(':');
				let obj_parts = cmd_parts[1].split('=');
				let obj_type = obj_parts[0];
				let obj_id = obj_parts[1];

				if (log_lvl) {
					console.log(`ae_open: ${obj_type} ${obj_id}`);
				}
				if (log_lvl > 1) {
					console.log(cmd);
				}

				// NOTE: This is not finished yet.
				if (obj_type == 'event_file') {
					// We are assuming this is for digital posters and needs to be opened in the modal.

					$events_sess.launcher.modal__open_event_file_id = null;

					clearInterval(idle_timer_interval);
					saver_looping = false;
					restartCountdown();

					$events_slct.event_file_id = obj_id;

					$events_sess.launcher.modal__title = $events_sess.launcher.modal__title ?? '*';

					$events_sess.launcher.modal__open_event_file_id = $events_slct.event_file_id;
					// $events_sess.launcher.modal__event_file_obj = event_file_obj;

					// $events_sess.launcher.modal__img_src = `/event/file/${event_file_obj.event_file_id_random}/download`;

					// $events_slct.event_file_obj = event_file_obj;

					// $slct_trigger = 'event_file';
					// $events_sess.launcher.event_file_open.open_status = 'open';

					// $events_sess.launcher.show_launcher_message = false;
					// NOTE: This is not finished yet.
					// This should now trigger the Svelte component for the event launcher file container. Currently this does nothing. Need to bind to something or use the "events_sess.launcher" object?

					// let as_modal_result = open_event_file_as_modal({event_file_id: event_file_obj.event_file_id_random, method: 'modal', filename: event_file_obj.filename, extension: event_file_obj.extension, modal_title: poster_title});
					// if (as_modal_result) {
					//     console.log($events_sess.launcher);
					//     console.log(event_file_obj);
					//     events_sess.launcher.set({...$events_sess.launcher, ...as_modal_result});
					// }
				}
				// NOTE: This is not finished yet.

				// AE Close (event file modal)
			} else if (cmd.startsWith('ae_close:')) {
				console.log();
				let cmd_parts = cmd.split(':');
				let what = cmd_parts[1];
				// let obj_type = obj_parts[0];
				// let obj_id = obj_parts[1];

				if (what == 'event_file_modal') {
					$events_sess.launcher.modal__title = '';
					$events_sess.launcher.modal__open_event_file_id = null;
					$events_sess.launcher.modal__event_file_obj = null;

					// $events_sess.launcher.modal__img_src = null;
					// $events_slct.event_file_id = null;
					// $slct_trigger = 'event_file';
					// $events_sess.launcher.event_file_open.open_status = 'close';
				}

				clearInterval(idle_timer_interval);
				saver_looping = false;
				restartCountdown();

				// WORKING! AE Refresh (now)
			} else if (cmd.startsWith('ae_refresh:')) {
				console.log();
				let cmd_parts = cmd.split(':');
				let what = cmd_parts[1];
				// let obj_type = obj_parts[0];
				// let obj_id = obj_parts[1];

				if (what == 'now') {
					// window.localStorage.clear();
					location.reload();
				} else {
					console.log('OOPS? What went wrong?');
				}
			}
		} else {
			if (log_lvl) {
				console.log('Unrecognized WS event received. Probably just a message.');
			}
		}
	}

	// This client sent a WebSocket message.
	function handle_ws_sent(ws_sent_status: any) {
		console.log('*** handle_ws_sent() ***', ws_sent_status);
		let command = ws_sent_status.cmd;
		console.log(`CMD: ${command}`);

		$events_sess.launcher.controller_cmd = null;
		$events_sess.launcher.controller_trigger_send = null;
	}
	/* *** END *** Handle WebSocket events */

	$effect(() => {
		if (
			$slct_trigger == 'event_file' &&
			$events_slct.event_file_id &&
			$events_sess.launcher?.event_file_open.open_status == 'open'
		) {
			$slct_trigger = null;
			// handle_event_file_open();
		}

		// if ($events_sess.launcher.trigger_open_file) {
		// $events_sess.launcher.trigger_modal_open_file = false;
		// handle_event_file_open();
		// }
	});

	$effect(() => {
		if (
			$slct_trigger == 'event_file' &&
			$events_sess.launcher?.event_file_open.open_status == 'close'
		) {
			$slct_trigger = null;
			// Assuming just event file modal for now
			// handle_event_file_close();
		}
	});

	$effect(() => {
		if (trigger_handle_ws_conn) {
			let ws_conn_status = trigger_handle_ws_conn; // This a string status
			trigger_handle_ws_conn = false;
			handle_ws_conn(ws_conn_status);
		}
	});

	$effect(() => {
		if (trigger_handle_ws_recv) {
			let ws_recv_status = trigger_handle_ws_recv; // This should be a key value object.
			trigger_handle_ws_recv = false;
			handle_ws_recv(ws_recv_status);
		}
	});

	$effect(() => {
		if (trigger_handle_ws_sent) {
			let ws_sent_status = trigger_handle_ws_sent; // This should be a key value object.
			trigger_handle_ws_sent = false;
			handle_ws_sent(ws_sent_status);
		}
	});

	async function handle_event_file_open() {
		let event_file_obj;
		if ($events_slct.event_file_obj && $events_slct.event_file_obj.event_file_id_random) {
			console.log($events_slct.event_file_obj);
			event_file_obj = $events_slct.event_file_obj;
		} else {
			console.log('Need to look up the event file details first.');
			// let get_event_file_obj_result = await get_event_file_obj({event_file_id: $events_slct.event_file_id});

			// event_file_obj = get_event_file_obj_result;
			// console.log(event_file_obj);
		}

		// let as_modal_result = open_event_file_as_modal({
		//     event_file_id: event_file_obj.event_file_id_random,
		//     filename: event_file_obj.filename,
		//     extension: event_file_obj.extension,
		//     modal_title: ae_util.shorten_filename(event_file_obj.filename, 75)
		// });

		// if (as_modal_result) {
		//     console.log($events_sess.launcher);

		//     events_sess.launcher.set({...$events_sess.launcher, ...as_modal_result});
		//     // $events_sess.launcher.event_file_open = as_modal_result;
		// }
	}

	async function handle_event_file_close() {
		let as_modal_result = close_event_file_as_modal({});

		if (as_modal_result) {
			events_sess.launcher.set({ ...$events_sess.launcher, ...as_modal_result });
		}
	}

	if (!$events_loc.launcher.idle_timer) {
		$events_loc.launcher.idle_timer = 5 * 60 * 1000;
	}
	// $events_loc.launcher.idle_timer = .25 * 60 * 1000;
	if (!$events_loc.launcher.idle_cycle) {
		$events_loc.launcher.idle_cycle = 5 * 1000;
	}
	if (!$events_loc.launcher.idle_loop_period) {
		$events_loc.launcher.idle_loop_period = 3 * 60 * 1000;
	}
	// Safer to run this once the component has mounted and initialized???
	listen({
		timer: $events_loc.launcher.idle_timer, // $events_loc.launcher.idle_timer ?? 30 * 60 * 1000,
		cycle: $events_loc.launcher.idle_cycle ?? 5 * 1000 // How frequently the idle status is checked
	});

	let idle_timer_interval: any = $state();
	// clearInterval(idle_timer_interval);

	let saver_looping: boolean = $state(false);

	function handle_idle_client() {
		// Start the digital poster screen saver after additional idle time.

		if ($lq__event_session_obj && $lq__event_session_obj?.type_code == 'poster') {
			if (log_lvl) {
				console.log(
					`Turned idle! Open poster file for poster session in ${($events_loc.launcher.idle_loop_period / 60000).toPrecision(4)} minutes.`
				);
			}
			if (saver_looping) {
				console.log('Screen saver already looping.');
				return false;
			}

			saver_looping = true;

			idle_timer_interval = setInterval(
				() => {
					if (log_lvl) {
						console.log(
							`Screen saver tick every ${($events_loc.launcher.idle_loop_period / 60000).toPrecision(4)} minutes after initially being idle for ${($events_loc.launcher.idle_timer / 60000).toPrecision(4)} minutes.`
						);
					}

					// console.log($events_loc.launcher.screen_saver_img_kv.length());

					if ($events_loc.launcher.screen_saver_img_kv) {
						console.log($events_loc.launcher.screen_saver_img_kv);

						let modal_title: string = '';

						const rand_index = Math.floor(
							Math.random() * Object.keys($events_loc.launcher.screen_saver_img_kv).length
						);
						if (log_lvl) {
							console.log(`Random index = ${rand_index}`);
						}

						let event_file_obj =
							$events_loc.launcher.screen_saver_img_kv[
								Object.keys($events_loc.launcher.screen_saver_img_kv)[rand_index]
							];

						$events_slct.event_file_id = event_file_obj.event_file_id_random;
						$events_slct.event_file_obj = event_file_obj;
						// $slct_trigger = 'event_file';
						// $events_loc.launcher.event_file_open.open_status = 'open';

						$events_sess.launcher.modal__open_event_file_id = null;
						// clearInterval(idle_timer_interval);
						// if (!modal_title) {
						//     modal_title = event_file_obj.filename;
						// }
						$events_sess.launcher.modal__title = event_file_obj.filename ?? '*';
						$events_sess.launcher.modal__open_event_file_id = $events_slct.event_file_id;
						$events_sess.launcher.modal__event_file_obj = event_file_obj;
						// $events_sess.launcher.modal__img_src = `/event/file/${event_file_obj.event_file_id_random}/download`;

						return true;
					}
					console.log('No screen saver images found.');
					return false;
				},
				$events_loc.launcher.idle_loop_period ?? 2 * 60 * 1000
			);
			// console.log('User is no longer idle???');
		} else {
			console.log('Not a poster session so no screen saver.');
			saver_looping = false;
			return false;
		}
	}

	onIdle(() => {
		// This is called when the user has gone idle for the specified time.

		// alert('USER IS IDLE');

		log_lvl = 1;
		if (log_lvl) {
			console.log(
				`User has gone idle after ${($events_loc.launcher?.idle_timer / 60000).toPrecision(4)} minutes.`,
				$idle
			);
		}
		clearInterval(idle_timer_interval);

		handle_idle_client();
	});

	$effect(() => {
		if ($idle) {
			// log_lvl = 1;
			// if (log_lvl) {
			//     console.log(`User has gone idle after ${($events_loc.launcher?.idle_timer / 60000).toPrecision(4)} minutes.`, $idle);
			// }
			// // clearInterval(idle_timer_interval);
			// if (!saver_looping) {
			//     handle_idle_client();
			// }
		} else {
			log_lvl = 1;
			if (log_lvl) {
				console.log(`User is active again after being idle. End screen saver if active.`, $idle);
			}
			clearInterval(idle_timer_interval);
			saver_looping = false;
		}
	});
</script>

<svelte:head>
	<!-- {ae_util.shorten_string({ string: $lq__event_obj?.name ?? '', max_length: 20, begin_length: 10, end_length: 4 })} -->
	<title>
		&AElig;:
		{$lq__event_location_obj?.name ?? '-- not set --'}
		({$lq__event_session_obj?.name ?? 'Æ loading...'}) - Launcher v3 -
		{$events_loc?.title}
	</title>
</svelte:head>

<!-- outline-2 outline-red-500  -->
<div
	class="
        static
        m-auto
        border-x border-gray-200 dark:border-gray-600
        mt-4 mb-16 sm:mb-12
        h-full
        w-full max-w-7xl
        transition-all
        "
>
	<header
		id="Main-Header"
		class:hidden={$events_loc.launcher.hide__launcher_header}
		class="
        z-20
        absolute top-0 left-0 right-0
        w-full max-w-7xl
        h-12
        p-1 px-12 m-auto

        flex flex-row items-center justify-around sm:justify-between

        text-sm hover:text-base

        bg-slate-200

        opacity-90 hover:opacity-100
        transition-all duration-1000
        "
	>
		<h3 class="h4 text-center italic text-surface-600-400">
			<button
				class=""
				onclick={() => {
					$events_loc.launcher.hide__launcher_menu = !$events_loc.launcher.hide__launcher_menu;
				}}
				title="Toggle Launcher menu"
			>
				<!-- Be sure to explain what &AElig; (Aether) means in the title text or similar! -->
				<Satellite class="text-base mx-1 inline-block text-gray-500" />
				<abbr title="Aether - Events Module Launcher">
					Æ Launcher
					<span class="text-xs align-super font-normal" title="Version 3">v3</span>
				</abbr>
			</button>
		</h3>

		{#if $lq__event_obj}
			<h2 class="hidden md:inline-block h3 text-center text-surface-600-400">
				{$lq__event_obj.cfg_json?.short_name}
			</h2>
			<h3
				class="h4 text-center italic text-surface-600-400"
				title="Location ID: {$lq__event_location_obj?.event_location_id} Name: {$lq__event_location_obj?.name}"
			>
				<button
					class="text-base"
					onclick={() => {
						$ae_loc.edit_mode = !$ae_loc.edit_mode;
					}}
					title="Toggle Edit Mode to show location options and more"
				>
					<span class="fas fa-map-marker-alt"></span>
					<span class="sr-only">Location:</span>
				</button>
				{$lq__event_location_obj?.name}
			</h3>
		{:else}
			<div class="flex flex-row gap-1 items-center justify-center">
				<span class="fas fa-spinner fa-spin mx-1"></span>
				<span>Loading event...</span>
			</div>
		{/if}
	</header>

	<!-- The menu should be to the left of the main session view. -->
	<div
		class="
        h-full min-w-full w-full max-w-full
        flex flex-col sm:flex-row flex-wrap sm:flex-nowrap gap-0
        items-center
        justify-start sm:justify-center
        py-1 px-0.5
        bg-gray-100

        "
	>
		<section
			id="Main-Nav-Menu"
			class="event_launcher_menu
        h-full
        basis-1/5
        min-w-56 md:min-w-64 lg:min-w-72
        max-w-xs
        pt-0.5 pr-0.5
        flex flex-col gap-1 items-center justify-start

        border-r border-gray-200 dark:border-gray-700
        hover:bg-surface-100-900
        "
			class:hidden={$events_loc.launcher.hide__launcher_menu}
		>
			<!-- overflow-y-auto -->

			<!-- {#await $events_slct.id_li__event_location}
        Loading location list... a
    {:then event_location_obj_li} -->
			<!-- {#if $lq__event_obj && $lq__event_location_obj_li && $lq__event_session_obj_li && event_location_obj_li && event_location_obj_li.length > 0} -->
			<!-- {#if $lq__event_obj && $lq__event_location_obj_li} -->
			<Launcher_menu
				data_url={data.url}
				{lq__event_obj}
				{lq__event_event_file_obj_li}
				{lq__location_event_file_obj_li}
				slct__event_file_id={$events_slct.event_file_id}
				{lq__event_location_obj_li}
				{lq__event_location_obj}
				slct__event_location_id={$events_slct.event_location_id}
				bind:loading__session_li_status={$events_sess.launcher.loading__session_li_status}
				{lq__event_session_obj_li}
				bind:loading__session_id_status={$events_sess.launcher.loading__session_id_status}
				{lq__event_session_obj}
				bind:slct__event_session_id={$events_slct.event_session_id}
				bind:trigger_reload__event_session_obj_id={
					$events_sess.launcher.trigger_reload__event_session_obj_id
				}
				bind:trigger_reload__event_session_obj_li={
					$events_sess.launcher.trigger_reload__event_session_obj_li
				}
				bind:trigger_reload__event_location_obj_li={
					$events_sess.launcher.trigger_reload__event_location_obj_li
				}
			></Launcher_menu>
			<!-- {:else}
    <div class="flex flex-row items-center justify-center">
        <span class="fas fa-spinner fa-spin mx-1"></span>
        <span>Loading location list...</span>
    </div>
    {/if} -->
			<!-- {/await} -->
			<!-- Root: slct Location ID: {$events_slct.event_location_id ?? '-- not set --'} -->
		</section>

		<section
			id="Main-Content"
			class="event_launcher_main
        h-full
        min-w-xs
        max-w-full
        py-1 px-0.5
        basis-4/5
        flex flex-col gap-1
        items-center
        justify-center
        overflow-y-auto
        "
		>
			<!-- {#if $events_trigger == 'load__event_session_obj' && $events_slct.event_session_id}
    <Launcher_session_view
        slct_event_session_id={$events_slct.event_session_id}

        lq__event_location_obj={lq__event_location_obj}
        lq__event_location_obj_li={lq__event_location_obj_li}
        lq__event_session_obj={lq__event_session_obj}
        lq__event_session_obj_li={lq__event_session_obj_li}
        >
    </Launcher_session_view>
    {/if} -->
			<!-- {$lq__event_session_obj?.name} -->

			{#if !$events_slct.event_location_id}
				<div class="flex flex-row items-center justify-center">
					<span class="fas fa-exclamation mx-1"></span>
					<span>You must select a location first</span>
					<span class="fas fa-exclamation mx-1"></span>
				</div>
			{/if}

			<!-- Using the loading__session_id_status is kind of a hacky way to determine if the session is still loading or not. -->
			{#if $events_slct.event_session_id && $lq__event_session_obj && !$events_sess.launcher.loading__session_id_status}
				<Launcher_session_view
					bind:slct__event_session_id={$events_slct.event_session_id}
					{lq__event_session_obj}
					bind:type_code={$lq__event_session_obj.type_code}
				></Launcher_session_view>
			{/if}
		</section>
	</div>

	{@render children?.()}
</div>

<!-- hover:z-20 -->
<!-- hover:scale-105 -->
<footer
	id="Main-Footer"
	class:hidden={$events_loc.launcher.hide__launcher_footer}
	class="
        z-20
        absolute bottom-0 left-0 right-0
        w-full max-w-7xl
        p-1 m-auto

        flex flex-row items-center justify-between
        sm:flex-row md:items-center md:justify-between

        text-xs hover:sm:text-sm hover:md:text-base hover:lg:text-lg


        bg-gray-200 border-t border-gray-200
        dark:bg-gray-800 dark:border-gray-600

        opacity-50 hover:opacity-100
        transition-all duration-1000
        "
>
	<!-- <div>
    [Help]
    </div> -->

	<div
		class="slct_location_name transition-all duration-1000"
		title="Location ID: {$lq__event_location_obj?.event_location_id} Name: {$lq__event_location_obj?.name} | Device ID: {$lq__event_device_obj?.event_device_id} Name: {$lq__event_device_obj?.name}"
	>
		<button
			class=""
			onclick={() => {
				$ae_loc.edit_mode = !$ae_loc.edit_mode;
			}}
			title="Toggle Edit Mode to show location options and more"
		>
			<span class="sr-only">Location:</span>
			<span class="fas fa-map-marker-alt"></span>
		</button>
		{$lq__event_location_obj?.name}
		{#if $lq__event_device_obj?.name}
			<span class="fas fa-laptop mx-1"></span>
			{$lq__event_device_obj?.name}
		{/if}
	</div>

	<span
		class:preset-tonal-warning={!$idle}
		class:preset-tonal-success={$idle}
		class="group px-1 rounded-md transition-all duration-1000"
		title="The user is currently {$idle ? 'idle' : 'active'}"
	>
		{#if $idle}
			<span class="fas fa-bed mx-1"></span>
			<span class="hidden group-hover:inline"> Idle </span>
		{:else}
			<span class="fas fa-mouse-pointer mx-1"></span>
			<span class="hidden group-hover:inline"> Active </span>
		{/if}
	</span>

	<!-- Why does this not behave consistently???? Spent a few hours trying to make it work right. -->
	<!-- {#if online.current}
    online
    {:else}
    offline
    {/if} -->

	<!-- class:preset-tonal-warning={!online?.current} -->
	<!-- class:preset-tonal-success={online?.current} -->
	<span
		class="group px-1 rounded-md transition-all duration-1000"
		title="Online status = {online?.current}"
	>
		<!-- {@html online?.current ? '<span class="fas fa-wifi mx-1"></span> Online!' : '--'} -->
		<span class="fas fa-wifi mx-1"></span>
		{online?.current ? '' : 'Offline!'}
		<!-- {@html online?.current ? '--' : 'No Connection'} -->
		<!-- {@html online?.current ? '<span class="fas fa-wifi mx-1"></span> Online!' : '<span class="fas fa-times mx-1 text-red-700"></span> No Connection'} -->

		<!-- current value data type = {online.current ? typeof(online.current) : 'null'} -->
		<!-- {#if online?.current}
            <span class="fas fa-wifi mx-1"></span>
            <span class="hidden group-hover:inline">
            Online
            </span>
        {:else}
            <span class="fas fa-times mx-1 text-red-700"></span>
            <span class="hidden group-hover:inline">
            No Connection!
            </span>
        {/if} -->

		<!-- {#if online.current === true}
            <span class="fas fa-wifi mx-1"></span>
            <span class="hidden group-hover:inline">
            Online
            </span>
        {:else}
            <span class="fas fa-times mx-1 text-red-700"></span>
            <span class="hidden group-hover:inline">
            No Connection!
            </span>
        {/if} -->
	</span>

	<span
		class:hidden={!$events_loc.launcher.ws_connect}
		class:preset-tonal-warning={$events_sess.launcher.ws_connect_status != 'connected'}
		class:preset-tonal-success={$events_sess.launcher.ws_connect_status == 'connected'}
		class="group px-1 rounded-md transition-all duration-1000"
		title="WebSocket is {$events_sess.launcher.ws_connect_status == 'connected'
			? 'connected'
			: 'disconnected'} API: {$ae_api?.base_url}"
	>
		{#if $events_sess.launcher.ws_connect_status == 'connected'}
			<span class="fas fa-sitemap mx-1 text-green-700"></span>
			<span class="hidden group-hover:inline"> WS Connected </span>
		{:else}
			<span class="fas fa-times mx-1"></span>
			<span class="hidden group-hover:inline"> WS Disconnected </span>
		{/if}
	</span>

	<span
		class:hidden={$events_loc.launcher.app_mode != 'native'}
		class="group px-1 rounded-md transition-all duration-1000"
		class:preset-tonal-warning={!$events_sess.launcher?.av_recording_status}
		class:preset-tonal-success={$events_sess.launcher?.av_recording_status}
		title="Audio/Video recording is {$events_sess.launcher?.av_recording_status
			? 'active'
			: 'inactive'}"
	>
		{#if $events_sess.launcher?.av_recording_status}
			<span class="fas fa-video mx-1"></span>
			<span class="hidden group-hover:inline"> AV Recording Active </span>
		{:else}
			<span class="fas fa-video-slash mx-1"></span>
			<span class="hidden group-hover:inline"> AV Recording Inactive </span>
		{/if}
	</span>

	<div class="current_datetime font-mono px-2 hover:font-bold hover:bg-white transition-all">
		<span class="hidden md:inline">
			<span class="fas fa-calendar-alt"></span>
			{ae_util.iso_datetime_formatter($time, 'date_full_no_year')}
		</span>
		<span class="hidden sm:inline">
			<span class="fas fa-clock"></span>
		</span>
		{#if $events_loc.launcher?.time_hours == 12}
			{ae_util.iso_datetime_formatter($time, 'time_12_long')}
		{:else}
			{ae_util.iso_datetime_formatter($time, 'time_long')}
		{/if}
		<!-- <span class="fas fa-hourglass fa-spin"></span> -->
		<!-- <span class="fas fa-hourglass"></span> -->
	</div>
</footer>

<div class="absolute top-0 left-0 z-20 text-center">
	<button
		type="button"
		onclick={() => ($events_loc.launcher.hide_drawer__cfg = false)}
		class="btn btn-sm p-2.5 preset-tonal-error hover:preset-filled-error-500 transition-all duration-1000"
		class:opacity-25={!$ae_loc.trusted_access}
		class:hover:opacity-75={!$ae_loc.trusted_access}
	>
		<span class="fas fa-biohazard"></span>
		<span class="hidden">Launcher Config</span>
	</button>
</div>

<Drawer
	bgColor="bg-blue"
	class="bg-orange-100 opacity-90 hover:opacity-97 transition-all duration-1000 border border-gray-300 dark:border-gray-600"
	placement="left"
	transitionType="fly"
	transitionParams={{
		x: -320,
		duration: 200,
		easing: sineIn
	}}
	width={'w-md'}
	bind:hidden={$events_loc.launcher.hide_drawer__cfg}
	id="sidebar1"
>
	<Launcher_cfg></Launcher_cfg>

	<hr class="my-2 border-gray-300 dark:border-gray-600" />

	<div class="flex flex-row flex-wrap gap-0.5 items-center justify-center max-w-md">
		<a
			href="/events/{$events_slct.event_id}"
			class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
		>
			<span class="fas fa-search m-1"></span>
			Session Search
		</a>
		{#if $events_slct?.event_location_id}
			<a
				href="/events/{$events_slct.event_id}/location/{$events_slct.event_location_id}"
				class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
			>
				<span class="fas fa-map-marker m-1"></span>
				View Selected Location
			</a>
		{/if}
		{#if $events_slct?.event_session_id}
			<a
				href="/events/{$events_slct.event_id}/session/{$events_slct.event_session_id}"
				class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500"
			>
				<span class="fas fa-chalkboard-teacher m-1"></span>
				View Selected Session
			</a>
		{/if}
		<!-- <button
            class="btn btn-sm variant-ghost-tertiary hover:variant-filled-tertiary"
            >Test 1</button> -->
		<!-- <button
            class="btn btn-sm variant-ghost-tertiary hover:variant-filled-tertiary"
            >Test 2</button> -->
	</div>
</Drawer>

<Drawer
	activateClickOutside={false}
	backdrop={false}
	class="bg-red-100 opacity-75 hover:opacity-95 transition-all duration-1000"
	placement="bottom"
	transitionType="fly"
	transitionParams={{
		y: 320,
		duration: 200,
		easing: sineIn
	}}
	width={'min-h-96 h-1/2'}
	bind:hidden={$events_loc.launcher.hide_drawer__debug}
	id="sidebar2"
>
	<div class="flex flex-row items-center justify-between">
		<h2 class="text-center mb-4 text-base font-semibold text-gray-500 dark:text-gray-400">Debug</h2>
		<button
			onclick={() => ($events_loc.launcher.hide_drawer__debug = true)}
			class="mb-4 dark:text-white"
		>
			<span class="fas fa-times"></span>
			<span class="hidden">Close Debug Drawer</span>
		</button>
	</div>

	<div>
		<!-- Show the launcher configuration in JSON format -->
		<pre class="text-xs">
        {JSON.stringify($events_loc.launcher, null, 2)}
    </pre>
		<hr />
		<pre class="text-xs">
        {JSON.stringify($ae_api, null, 2)}
    </pre>
	</div>
</Drawer>

<!-- Main modal -->
<!-- **NOTE:** The modal size is intentionally set to "". This makes it undefined and allows the modal to be as large as the content. **NOTE** -->
<!-- title={$events_sess.launcher?.modal__title} -->
<Modal
	open={$events_sess.launcher?.modal__open_event_file_id}
	autoclose={false}
	placement="top-center"
	size=""
	class="
        bg-gray-500/90 dark:bg-gray-800/90 text-gray-800 dark:text-gray-200
        rounded-lg border-gray-200 dark:border-gray-700
        divide-y divide-gray-200 dark:divide-gray-700 shadow-md
        relative
        flex flex-col items-center justify-center
        {$events_loc.launcher.controller == 'remote' ? 'min-h-full' : ''}
        min-w-full
        "
	bodyClass="p-0 space-y-0 overflow-y-auto flex flex-col gap-1 items-center justify-center"
	headerClass={`fixed top-0 right-0 left-0 p-1 md:p-2 flex flex-row items-center ${$events_loc.launcher.controller == 'remote' ? 'hidden' : ''} bg-white dark:bg-gray-800 opacity-50 ${$events_loc.launcher.hide__modal_header_title ? 'justify-center' : 'justify-between'}`}
	footerClass="text-center hidden"
	onclose={async () => {
		$events_sess.launcher.modal__open_event_file_id = null;
		if (
			$events_loc.launcher.controller == 'local_push' &&
			$events_sess.launcher.ws_connect_status == 'connected'
		) {
			// // This should work....????
			// console.log(`TEST - FAIL??? Local Push Controller Command: ae_close:event_file_modal`);
			// console.log(`Before: ${$events_sess.launcher.controller_trigger_send}`);
			// // $events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
			// // $events_sess.launcher.controller_trigger_send = true;
			// // $events_sess = $events_sess;
			// // events_sess.set($events_sess);
			// // tick();
			// // events_sess.set($events_sess);
			// console.log(`After: ${$events_sess.launcher.controller_trigger_send}`);
		}
	}}
>
	{#snippet header()}
		<!-- <div class="flex flex-row items-center justify-between"> -->
		<h3
			class:hidden={$events_loc.launcher.hide__modal_header_title}
			class="text-lg font-semibold opacity-20 hover:opacity-100 transition-all"
		>
			{$events_sess.launcher?.modal__title ?? 'Digital Poster Display'}
		</h3>
		<button
			type="button"
			class="btn flex-row-reverse group transition-all justify-self-end"
			onclick={() => {
				$events_sess.launcher.modal__open_event_file_id = null;
				if (
					$events_loc.launcher.controller == 'local_push' &&
					$events_sess.launcher.ws_connect_status == 'connected'
				) {
				}
			}}
			title="Close Modal"
		>
			<span class="fas fa-times my-1.5"></span>
			<span class="hidden group-hover:inline"> Close</span>
		</button>
		<!-- </div> -->
	{/snippet}

	<!-- <svelte:fragment slot="header">
        <div class="flex flex-row items-center justify-between">
            <h3 class="text-lg font-semibold">
                {$events_sess.launcher?.modal__title}
            </h3>
        </div>
    </svelte:fragment> -->
	<button
		onclick={() => {
			console.log(`TEST - THIS WORKS... Local Push Controller Command: ae_close:event_file_modal`);
			// This is not terrible if we set autoclose to true.
			$events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
			$events_sess.launcher.controller_trigger_send = true;
			// $events_sess.launcher.modal__open = false;
		}}
		class="
            absolute top-0 right-12
            m-1 p-1
            btn btn-sm
            preset-tonal-error preset-outlined-error hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
		class:hidden={$events_loc.launcher.controller != 'local_push' ||
			$events_sess.launcher.ws_connect_status != 'connected'}
		title="Close the remote device's display of the poster"
	>
		<span class="fas fa-times m-1"></span>
		<span class="fas fa-tv"></span>
		Close Remote Poster Display Only
	</button>
	<!-- Open: {$ae_api.base_url} {$events_sess.launcher.modal__open_event_file_id} -->
	<!-- /event/file/{$events_slct.event_file_obj.event_file_id_random}/download?filename={$events_slct.event_file_obj.filename}&x_no_account_id_token=direct-download -->
	<!-- <span class="aspect-9/16 max-h-96"> -->
	{#if $events_sess.launcher.modal__open_event_file_id}
		<img
			src="{$ae_api.base_url}/event/file/{$events_sess.launcher
				.modal__open_event_file_id}/download?filename={$events_slct.event_file_obj
				.filename}&x_no_account_id_token=direct-download"
			alt="Placeholder: /event/file/{$events_sess.launcher
				.modal__open_event_file_id}/download?filename={$events_slct.event_file_obj
				.filename}&x_no_account_id_token=direct-download"
			class="min-h-28 min-w-md max-h-full max-w-full"
		/>
	{:else}
		<div class="flex flex-row items-center justify-center p-4">
			<span class="fas fa-info-circle mx-1"></span>
			<span>No image selected</span>
		</div>
	{/if}

	<!-- </span> -->

	<button
		onclick={() => {
			console.log(`TEST - THIS WORKS... Local Push Controller Command: ae_close:event_file_modal`);
			// This is not terrible if we set autoclose to true.
			$events_sess.launcher.controller_cmd = `ae_close:event_file_modal`;
			$events_sess.launcher.controller_trigger_send = true;
			// $events_sess.launcher.modal__open = false;
		}}
		class="
            absolute bottom-0 left-12
            m-1 p-1
            btn btn-sm
            preset-tonal-error preset-outlined-error hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
		class:hidden={$events_loc.launcher.controller != 'local_push' ||
			$events_sess.launcher.ws_connect_status != 'connected'}
		title="Close the remote device's display of the poster"
	>
		<span class="fas fa-times m-1"></span>
		<span class="fas fa-tv"></span>
		Close Remote Poster Display Only
	</button>

	<!-- Need to add a re-open button... -->

	<button
		onclick={() => {
			// $events_sess.launcher.modal__open = false;
			$events_sess.launcher.modal__title = '';
			$events_sess.launcher.modal__open_event_file_id = null;
			$events_sess.launcher.modal__event_file_obj = null;
		}}
		class="
            absolute bottom-0 right-12
            m-1 p-1
            btn btn-sm
            preset-tonal-success preset-outlined-success hover:preset-filled-success-200-800
            opacity-80 hover:opacity-100 active:opactiy-100
            transition-all
            "
		class:hidden={!$ae_loc.trusted_access &&
			($events_loc.launcher.controller != 'local_push' ||
				$events_sess.launcher.ws_connect_status != 'connected')}
		title="Close this controller's local modal display of this poster"
	>
		<span class="fas fa-times m-1"></span>
		<span class="fas fa-list"></span>
		Close
		<!-- Controller -->
		<!-- Local -->
		Poster
		<!-- Here -->
		on This Device
		<!-- Only -->
	</button>

	<!-- <svelte:fragment slot="footer">
        <div class="text-center w-full">

            <button
                on:click={() => {
                    $events_sess.launcher.modal__open = false;
                }}
                class="btn btn-sm variant-soft-warning hover:variant-ghost-warning"
                >
                <span class="fas fa-times m-1"></span>
                Close
            </button>
        </div>
    </svelte:fragment> -->
</Modal>

<!-- {:else}
{$events_sess.launcher.modal__open_event_file_id}
{/if} -->

{#if $events_loc.launcher.controller_group_code && $events_loc.launcher.ws_connect}
	<!-- {$ae_api.base_url} -->
	<Element_websocket_v2
		{log_lvl}
		bind:ws_connect={$events_loc.launcher.ws_connect}
		bind:ws_connect_status={$events_sess.launcher.ws_connect_status}
		ws_server={$ae_api.fqdn}
		bind:group_id={$events_loc.launcher.controller_group_code}
		bind:client_id={$events_loc.launcher.controller_client_id}
		bind:cmd={$events_sess.launcher.controller_cmd}
		type={'cmd'}
		bind:trigger_send={$events_sess.launcher.controller_trigger_send}
		bind:trigger_connect={$events_sess.launcher.trigger__ws_connect}
		bind:trigger_disconnect={$events_sess.launcher.trigger__ws_disconnect}
		bind:hide__ws_element={$events_loc.launcher.hide__ws_element}
		bind:hide__ws_form={$events_loc.launcher.hide__ws_form}
		bind:hide__ws_messages={$events_loc.launcher.hide__ws_messages}
		bind:hide__ws_commands={$events_loc.launcher.hide__ws_commands}
		bind:ws_conn_status={trigger_handle_ws_conn}
		bind:ws_recv_status={trigger_handle_ws_recv}
		bind:ws_sent_status={trigger_handle_ws_sent}
	/>
	<!-- on:ws_recv={handle_ws_recv} -->
{/if}
