// Copyright 2022 pyke.io
// 2019-2021 Tauri Programme within The Commons Conservancy
// [https://tauri.studio/]
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Millennium Core is a cross-platform application window creation and event
//! loop management library.
//!
//! # Building windows
//!
//! Before you can build a [`Window`], you first need to build an [`EventLoop`].
//! This is done with the [`EventLoop::new()`] function.
//!
//! ```no_run
//! use millennium_core::event_loop::EventLoop;
//! let event_loop = EventLoop::new();
//! ```
//!
//! Once this is done there are two ways to create a [`Window`]:
//!
//! - Calling [`Window::new(&event_loop)`][window_new].
//! - Calling [`let builder = WindowBuilder::new()`][window_builder_new] then
//! [`builder.build(&event_loop)`][window_builder_build].
//!
//! The first method is the simplest, and will give you default values for
//! everything. The second method allows you to customize the way your
//! [`Window`] will look and behave by modifying the fields of the
//! [`WindowBuilder`] object before you create the [`Window`].
//!
//! # Event handling
//!
//! Once a [`Window`] has been created, it will generate different *events*. A
//! [`Window`] object can generate [`WindowEvent`]s when certain input events
//! occur, such as a cursor moving over the window or a key getting pressed
//! while the window is focused. Devices can generate [`DeviceEvent`]s, which
//! contain unfiltered event data that isn't specific to a certain window.
//! Some user activity, like mouse movement, can generate both a [`WindowEvent`]
//! *and* a [`DeviceEvent`]. You can also create and handle your own custom
//! [`UserEvent`]s, if desired.
//!
//! You can retrieve events by calling [`EventLoop::run`][event_loop_run]. This
//! function will dispatch events for every [`Window`] that was created with
//! that particular [`EventLoop`], and will run until the `control_flow`
//! argument given to the closure is set to [`ControlFlow`]`::`[`ExitWithCode`]
//! (which [`ControlFlow`]`::`[`Exit`] aliases to), at which point [`Event`]`::
//! `[`LoopDestroyed`] is emitted and the entire program terminates.
//!
//! Millennium Core no longer uses a `EventLoop::poll_events() -> impl
//! Iterator<Event>`-based event loop model, since that can't be implemented
//! properly on some platforms (e.g web, iOS) and works poorly on most other
//! platforms. However, this model can be re-implemented to an extent with
//! [`EventLoopExtRunReturn::run_return`]. See that method's documentation for
//! more reasons about why it's discouraged, beyond compatibility reasons.
//!
//!
//! ```no_run
//! use millennium_core::{
//! event::{Event, WindowEvent},
//! event_loop::{ControlFlow, EventLoop},
//! window::WindowBuilder
//! };
//!
//! let event_loop = EventLoop::new();
//! let window = WindowBuilder::new().build(&event_loop).unwrap();
//!
//! event_loop.run(move |event, _, control_flow| {
//! // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
//! // dispatched any events. This is ideal for games and similar applications.
//! *control_flow = ControlFlow::Poll;
//!
//! // ControlFlow::Wait pauses the event loop if no events are available to process.
//! // This is ideal for non-game applications that only update in response to user
//! // input, and uses significantly less power/CPU time than ControlFlow::Poll.
//! *control_flow = ControlFlow::Wait;
//!
//! match event {
//! Event::WindowEvent {
//! event: WindowEvent::CloseRequested, ..
//! } => {
//! println!("The close button was pressed; stopping");
//! *control_flow = ControlFlow::Exit
//! }
//! Event::MainEventsCleared => {
//! // Application update code.
//!
//! // Queue a RedrawRequested event.
//! //
//! // You only need to call this if you've determined that you need to redraw, in
//! // applications which do not always need to. Applications that redraw continuously
//! // can just render here instead.
//! window.request_redraw();
//! }
//! Event::RedrawRequested(_) => {
//! // Redraw the application.
//! //
//! // It's preferable for applications that do not render continuously to render in
//! // this event rather than in MainEventsCleared, since rendering in here allows
//! // the program to gracefully handle redraws requested by the OS.
//! }
//! _ => ()
//! }
//! });
//! ```
//!
//! [`Event`]`::`[`WindowEvent`] has a [`WindowId`] member. In multi-window
//! environments, it should be compared to the value returned by
//! [`Window::id()`][window_id_fn] to determine which [`Window`] dispatched the
//! event.
//!
//! # Drawing on the window
//!
//! Millennium Core doesn't directly provide any methods for drawing on a
//! [`Window`]. However it allows you to retrieve the raw handle of the window
//! (see the [`platform`] module and/or the [`raw_window_handle`] method), which
//! in turn allows you to create an OpenGL/Vulkan/DirectX/Metal/etc. context
//! that can be used to render graphics.
//!
//! Note that many platforms will display garbage data in the window's client
//! area if the application doesn't render anything to the window by the time
//! the desktop compositor is ready to display the window to the user. If you
//! notice this happening, you should create the window with [`visible` set to
//! `false`](crate::window::WindowBuilder::with_visible) and explicitly make the
//! window visible only once you're ready to render into it.
//!
//! [`EventLoop`]: event_loop::EventLoop
//! [`EventLoopExtRunReturn::run_return`]: ./platform/run_return/trait.EventLoopExtRunReturn.html#tymethod.run_return
//! [`EventLoop::new()`]: event_loop::EventLoop::new
//! [event_loop_run]: event_loop::EventLoop::run
//! [`ControlFlow`]: event_loop::ControlFlow
//! [`Exit`]: event_loop::ControlFlow::Exit
//! [`ExitWithCode`]: event_loop::ControlFlow::ExitWithCode
//! [`Window`]: window::Window
//! [`WindowId`]: window::WindowId
//! [`WindowBuilder`]: window::WindowBuilder
//! [window_new]: window::Window::new
//! [window_builder_new]: window::WindowBuilder::new
//! [window_builder_build]: window::WindowBuilder::build
//! [window_id_fn]: window::Window::id
//! [`Event`]: event::Event
//! [`WindowEvent`]: event::WindowEvent
//! [`DeviceEvent`]: event::DeviceEvent
//! [`UserEvent`]: event::Event::UserEvent
//! [`LoopDestroyed`]: event::Event::LoopDestroyed
//! [`platform`]: platform
//! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle
extern crate lazy_static;
extern crate log;
extern crate serde;
extern crate bitflags;
extern crate objc;