//! Components for the windowed application.

use std::sync::Arc;
use log::warn;
use winit::window::{CursorGrabMode, Window as WinitWindow};

/// Contains the windowing implementation.
pub struct Window {
    pub window: Arc<WinitWindow>,
}

impl Window {
    /// Initializes [`self`] from a [`WinitWindow`].
    pub(crate) fn from_window(window: WinitWindow) -> Self {
        let window = Arc::new(window);

        Self { window }
    }

    /// Sets the window's title.
    pub fn set_title(&self, title: &str) {
        self.window.set_title(title);
    }

    /// Locks the cursor onto the window.
    pub fn lock_cursor(&self) {
        self.window.set_cursor_visible(false);
        self.window
            .set_cursor_grab(CursorGrabMode::Locked)
            .unwrap_or_else(|_| warn!("Failed to grab the cursor!"));
    }

    /// Performs a redraw on the window.
    pub(crate) fn redraw(&self) {
        self.window.request_redraw();
    }
}

/// Contains application state.
#[derive(Default)]
pub struct ApplicationLifecycle {
    is_exiting: bool,
}

impl ApplicationLifecycle {
    /// Instructs the application to exit.
    pub fn exit(&mut self) {
        self.is_exiting = true;
    }

    /// Whether the application is exiting or not.
    pub fn is_exiting(&self) -> bool {
        self.is_exiting
    }
}
