<script lang="ts">
let log_lvl: number = $state(1);

// *** 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 } from 'svelte-idle'

// *** Import Aether specific variables and functions
interface Props {
    /** @type {import('./$types').LayoutData} */
    data: any;
    children?: import('svelte').Snippet;
}

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


import type { key_val } from '$lib/ae_stores';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { api } from '$lib/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/ae_stores';
import { events_loc, events_sess, events_slct, events_trigger, events_trig } from '$lib/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/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);

$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.events
        .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 File - For Event
let lq__event_event_file_obj_li = $derived(liveQuery(async () => {
    let results = await db_events.files
        .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.files
        // .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.locations
        .get($events_slct.event_location_id);

    return results;
}));

let lq__event_location_obj_li = $derived(liveQuery(async () => {
    let results = await db_events.locations
        .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.sessions
        .get($events_slct.event_session_id);

    return results;
}));

// let lq__event_session_obj_li = $derived(liveQuery(async () => {
//     let results = await db_events.sessions
//         // .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.sessions
//         .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.sessions
            .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.sessions
    //         // .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.sessions
    //         .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 (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.sessions
            .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
};


/* *** BEGIN *** Handle WebSocket events */
function handle_ws_conn(event) {
    console.log('*** handle_ws_conn() ***');
    console.log(event);
    if (event.detail.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(event) {
    if (log_lvl) {
        console.log('*** handle_ws_recv() ***', event);
    }

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

        if ($events_loc.launcher.controller != 'remote') {
            if (log_lvl) {
                console.log('Controller is not set to remote. Ignoring command.', 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)
        } 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') {
                clearInterval(idle_timer_interval);
                $events_slct.event_file_id = obj_id;

                $events_sess.launcher.modal__open = $events_slct.event_file_id;
                let modal_title = null;
                if (!modal_title) {
                    modal_title = '*'; // event_file_obj.filename;
                }
                $events_sess.launcher.modal__title = modal_title;
                // $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__open = false;
                // $events_slct.event_file_id = null;
                // $slct_trigger = 'event_file';
                // $events_sess.launcher.event_file_open.open_status = 'close';
            }

        // 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(event) {
    console.log('*** handle_ws_sent() ***');
    console.log(event);
    let command = event.detail.cmd;
    console.log(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();
    }
});

$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();
    }
});

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});
    }
}



// Updated 2023-3-31
// export let open_event_file_as_modal = function open_event_file_as_modal({event_file_id, filename=null, extension=null, modal_title='Poster'}) {
//     console.log('*** open_event_file_as_modal() ***');

//     // NOTE: I can not set the ae_event_launcher values directly. Passing them back to the component and setting them there. Not ideal. This might be improved/fixed in the future?
//     let launcher_modal_values = {'show_modal_file': true, 'event_file_open': {}};

//     // launcher_modal_values.show_modal_file = true;
//     if (extension == 'png' || extension == 'jpg') {
//         launcher_modal_values.event_file_open.file_type = 'image';
//     } else if (extension == 'mp4' || extension == 'mov') {
//         launcher_modal_values.event_file_open.file_type = 'video';
//     } else {
//         return false;
//     }

//     launcher_modal_values.event_file_open.file_src = `/event/file/${event_file_id}/download`;
//     launcher_modal_values.event_file_open.modal_title = modal_title;

//     // NOTE: Be sure to set these values in the actual ae_event_launcher object!
//     return launcher_modal_values;
// }


    // interface Props {
    //     /** @type {import('./$types').LayoutData} */
    //     data: any;
    //     // Updated 2023-3-31
    //     close_event_file_as_modal?: any;
    //     children?: import('svelte').Snippet;
    // }

// let { data = $bindable(), close_event_file_as_modal = function close_event_file_as_modal({}) {
//     console.log('*** close_event_file_as_modal() ***');

//     // NOTE: I can not set the ae_event_launcher values directly. Passing them back to the component and setting them there. Not ideal. This might be improved/fixed in the future?
//     let launcher_modal_values = {'show_modal_file': false, 'event_file_open': {}};

//     // NOTE: Be sure to set these values in the actual ae_event_launcher object!
//     return launcher_modal_values;
// }, children }: Props = $props();






if (!$events_loc.launcher.idle_timer) {
    $events_loc.launcher.idle_timer = 4 * 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 = 1 * 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);

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

    if ($events_slct?.event_session_obj && $events_slct.event_session_obj?.type_code == 'poster') {
        console.log('Open poster file in poster session...');

        idle_timer_interval = setInterval(() => {
            if (log_lvl) {
                console.log('Screen saver tick!');
                // console.log($events_loc.launcher.screen_saver_img_kv);

            }

            // 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);
                console.log(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_obj.event_file_id_random;
                if (!modal_title) {
                    modal_title = event_file_obj.filename;
                }
                $events_sess.launcher.modal__title = modal_title;
                // $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 {
        return false;
    }

}

$effect(() => {
    if ($idle) {
        log_lvl = 1;
        console.log(`User is idle after ${$events_loc.launcher?.idle_timer} milliseconds.`);
        handle_idle_client();
    } else {
        console.log('User is no longer idle.');
        log_lvl = 0;
        clearInterval(idle_timer_interval);
    }
});
</script>



<svelte:head>
	<title>
        Launcher:
        {ae_util.shorten_string({ string: $lq__event_obj?.name ?? '', max_length: 20, begin_length: 10, end_length: 4 })}
        ({$lq__event_obj?.event_id ?? 'loading...'}) - Pres Mgmt - {$ae_loc?.title}
    </title>
</svelte:head>

<!-- max-w-(--breakpoint-xl)  -->
<div
    class="
        static

        m-auto
        border border-gray-200 dark:border-gray-600
        mt-12 mb-14 sm:mb-12
        h-full w-full max-w-7xl
        "
        >



<header
    id="Main-Header"
    class="
        absolute top-0 start-0 z-20 w-full p-1
        flex flex-row items-center justify-evenly bg-slate-200
        text-sm hover:text-base
        m-auto
        opacity-50 hover:opacity-100
        transition-all duration-1000
        "
    >
    <h3 class="hidden sm:inline-block h4 text-center italic text-surface-600-400">
        Æ Presentation Launcher
    </h3>

    {#if $lq__event_obj}
        <h2 class="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}"
            >
            {$lq__event_location_obj?.name}
            <!-- {$events_slct.event_location_id} -->
        </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-center
        py-1 px-1
        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
        py-1 px-0.5
        flex flex-col gap-1 items-center justify-start
        overflow-y-auto
        border-r border-gray-300 dark:border-gray-600
        "
    class:hidden={$events_loc.launcher.hide__launcher_menu}
    >

    <!-- {#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_obj}

        lq__event_event_file_obj_li={lq__event_event_file_obj_li}
        lq__location_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_li}
        lq__event_location_obj={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={lq__event_session_obj_li}
        lq__event_session_obj={lq__event_session_obj}
        slct__event_session_id={$events_slct.event_session_id}
        >
    </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-1
        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}

    {#if $events_slct.event_session_id && $lq__event_session_obj}
    <Launcher_session_view
        lq__event_session_obj={lq__event_session_obj}
        >
    </Launcher_session_view>
    {/if}

</section>

</div>


{@render children?.()}


</div>


<Footer
    class="
        absolute bottom-0 start-0 z-20 w-full p-1
        flex flex-row items-center justify-between
        sm:flex-row md:items-center md:justify-between
        text-xs hover:text-base
        shadow
        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">
    <span class="fas fa-map-marker-alt"></span>
    {$lq__event_location_obj?.name}
    </div>

    <span
        class="*:hover:inline px-1 rounded-md"
        class:preset-tonal-warning={!$events_loc.launcher.ws_connect}
        class:preset-tonal-success={$events_loc.launcher.ws_connect}
        >
        {#if $events_sess.launcher.ws_connect_status == 'connected'}
            <span class="fas fa-wifi mx-1"></span>
            <span class="hidden">
            WebSocket Connected
            </span>
        {:else}
        <span class="fas fa-times mx-1"></span>
            <span class="hidden">
            WebSocket Disconnected
            </span>
        {/if}
    </span>

    <span
        class:hidden={$events_loc.launcher.app_mode != 'native'}
        class="*:hover:inline px-1 rounded-md"
        class:preset-tonal-warning={!$events_sess.launcher?.av_recording_status}
        class:preset-tonal-success={$events_sess.launcher?.av_recording_status}
        >
    {#if $events_sess.launcher?.av_recording_status}
        <span class="fas fa-video mx-1"></span>
        <span class="hidden">
        AV Recording Active
        </span>
    {:else}
        <span class="fas fa-video-slash mx-1"></span>
        <span class="hidden">
        AV Recording Inactive
        </span>
    {/if}
    </span>

    <div class="current_datetime">
        {ae_util.iso_datetime_formatter($time,'date_full_no_year')}
        {#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}
    </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={'min-w-80 w-1/2 max-w-(--breakpoint-lg)'}
    bind:hidden={$events_loc.launcher.hide_drawer__cfg}
    id="sidebar1"
    >

    <Launcher_cfg></Launcher_cfg>


    <hr />

    <div class="flex flex-row flex-wrap gap-0.5 items-center justify-center">
        <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. -->
<Modal
    title="{$events_sess.launcher?.modal__title}"
    bind:open={$events_sess.launcher.modal__open}
    autoclose={false}
    size=""
    class="bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md relative flex flex-col mx-auto w-full divide-y m-0"
    dialogClass="fixed top-0 start-0 end-0 h-modal md:inset-0 md:h-full z-50 w-full p-0 flex"
    classHeader="px-1 py-0 md:px-1 md:py-0 absolute top-0 start-0 end-0 bg-gray-200 dark:bg-gray-800 opacity-50 hover:opacity-75"
    bodyClass='p-0 flex-1 overflow-y-auto overscroll-contain'
    classBody="flex flex-col items-center p-0 md:px-0 py-0"
    on:close={async () => {
        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}`);
        }
    }}
    >

    <!-- <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-20 m-1 p-1 btn btn-sm preset-tonal-error hover:preset-filled-error-500"
        class:hidden={$events_loc.launcher.controller != 'local_push' || $events_sess.launcher.ws_connect_status != 'connected'}
        >
        <span class="fas fa-times m-1"></span>
        Close Remote Poster Display Only
    </button>

    <!-- <span class="aspect-9/16 max-h-96"> -->
    <img
        src="{$ae_api.base_url}/event/file/{$events_sess.launcher.modal__open}/download?filename={$events_slct.event_file_obj.filename}&x_no_account_id_token=direct-download"
        alt="Placeholder"
        class="margin-auto max-h-full max-w-full"
        />
    <!-- </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-20 m-1 p-1 btn btn-sm preset-tonal-error hover:preset-filled-error-500"
        class:hidden={$events_loc.launcher.controller != 'local_push' || $events_sess.launcher.ws_connect_status != 'connected'}
        >
        <span class="fas fa-times m-1"></span>
        Close Remote Poster Display Only
    </button>

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

    <button
        onclick={() => {
            $events_sess.launcher.modal__open = false;
        }}
        class="absolute bottom-0 right-20 m-1 p-1 btn btn-sm preset-tonal-warning hover:preset-tonal-warning border border-warning-500"
        class:hidden={!$ae_loc.trusted_access && ($events_loc.launcher.controller != 'local_push' || $events_sess.launcher.ws_connect_status != 'connected')}
        >
        <span class="fas fa-times m-1"></span>
        Close Controller Poster 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>


{#if $events_loc.launcher.controller_group_code && $events_loc.launcher.ws_connect}
    <!-- {$ae_api.base_url} -->
    <Element_websocket_v2
        log_lvl={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: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}

        on:ws_conn={handle_ws_conn}
        on:ws_recv={handle_ws_recv}
        on:ws_sent={handle_ws_sent}

        />
        <!-- on:ws_recv={handle_ws_recv} -->
{/if}