use core::{ffi::c_void, mem::variant_count};

use flipperzero_sys as sys;

use crate::{app::App, main_menu, popup_one, popup_two};

#[derive(Primitive)]
pub enum Scenes {
    MainMenu = 0,
    PopupOne = 1,
    PopupTwo = 2
}

pub const SCENE_ON_ENTER_HANDLERS : [sys::AppSceneOnEnterCallback; variant_count::<Scenes>()] = [
    Some(main_menu::scene_on_enter),
    Some(popup_one::scene_on_enter),
    Some(popup_two::scene_on_enter)
];

pub const SCENE_ON_EVENT_HANDLERS : [sys::AppSceneOnEventCallback; variant_count::<Scenes>()] = [
    Some(main_menu::scene_on_event),
    Some(popup_one::scene_on_event),
    Some(popup_two::scene_on_event)
];

pub const SCENE_ON_EXIT_HANDLERS : [sys::AppSceneOnExitCallback; variant_count::<Scenes>()] = [
    Some(main_menu::scene_on_exit),
    Some(popup_one::scene_on_exit),
    Some(popup_two::scene_on_exit)
];

pub const SCENE_EVENT_HANDLERS : sys::SceneManagerHandlers = sys::SceneManagerHandlers {
    on_enter_handlers: SCENE_ON_ENTER_HANDLERS.as_ptr(),
    on_event_handlers: SCENE_ON_EVENT_HANDLERS.as_ptr(),
    on_exit_handlers: SCENE_ON_EXIT_HANDLERS.as_ptr(),
    scene_num: variant_count::<Scenes>() as u32
};

pub unsafe extern "C" fn custom_event_callback(context: *mut c_void, event: u32) -> bool {
    let app = context as *mut App;
    sys::scene_manager_handle_custom_event((*app).scene_manager.unwrap(), event)
}

pub unsafe extern "C" fn navigation_event_callback(context: *mut c_void) -> bool {
    let app = context as *mut App;
    sys::scene_manager_handle_back_event((*app).scene_manager.unwrap())
}