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

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

impl WindowContext {
    /// Initializes [`self`] from a [`WinitWindow`].
    pub(crate) fn from_window(window: Window) -> 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!"));
    }

    /// Returns whether the window is in fullscreen or not.
    pub fn is_fullscreen(&self) -> bool {
        self.window
            .fullscreen()
            .is_some()
    }

    /// Sets the window on the current monitor to borderless fullscreen.
    pub fn borderless_fullscreen(&self) {
        let mode = Fullscreen::Borderless(None);

        self.window.set_fullscreen(Some(mode));
    }

    /// Exits out of fullscreen.
    pub fn exit_fullscreen(&self) {
        self.window.set_fullscreen(None);
    }

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