#[derive(Debug, Clone, Copy, Default)]
pub struct ViewportRect {
    pub x: f32,
    pub y: f32,
    pub width: f32,
    pub height: f32,
}

impl ViewportRect {
    pub fn contains(&self, screen_pos: crate::ecs::world::Vec2) -> bool {
        screen_pos.x >= self.x
            && screen_pos.x <= self.x + self.width
            && screen_pos.y >= self.y
            && screen_pos.y <= self.y + self.height
    }

    pub fn to_local(&self, screen_pos: crate::ecs::world::Vec2) -> crate::ecs::world::Vec2 {
        crate::ecs::world::Vec2::new(screen_pos.x - self.x, screen_pos.y - self.y)
    }
}

#[derive(Default)]
pub struct Window {
    pub handle: Option<std::sync::Arc<winit::window::Window>>,
    pub should_exit: bool,
    pub timing: WindowTiming,
    pub cached_viewport_size: Option<(u32, u32)>,
    pub active_viewport_rect: Option<ViewportRect>,
}

pub struct WindowTiming {
    pub frames_per_second: f32,
    pub delta_time: f32,
    pub raw_delta_time: f32,
    pub time_speed: f32,
    pub last_frame_start_instant: Option<web_time::Instant>,
    pub current_frame_start_instant: Option<web_time::Instant>,
    pub initial_frame_start_instant: Option<web_time::Instant>,
    pub frame_counter: u32,
    pub uptime_milliseconds: u64,
}

impl Default for WindowTiming {
    fn default() -> Self {
        Self {
            frames_per_second: 0.0,
            delta_time: 0.0,
            raw_delta_time: 0.0,
            time_speed: 1.0,
            last_frame_start_instant: None,
            current_frame_start_instant: None,
            initial_frame_start_instant: None,
            frame_counter: 0,
            uptime_milliseconds: 0,
        }
    }
}
