#![allow(dead_code, unused_imports)]
use crossbeam::channel::{Receiver, Sender};

mod util;
mod error; pub use error::Error;
mod config; pub use config::Config;
mod system; use system::{
    Subsystem,
    Query, QueryData,
    SupervisorQuery,
    WindowManager,
};
pub use system::{
    System,
    window::WindowConfig,
};
pub mod hid;
mod platform;
mod app;

pub struct Donten {
    supervisor:Sender<Query>,
    sender:Sender<Query>,
    receiver:Receiver<Query>,
}
impl Donten {
    pub fn init(_config:Config) -> Result<Self, Error>
    {
        // Initialize supervisor.
        let supervisor = system::Supervisor::start(None)?;
        let (sender, receiver) = crossbeam::channel::bounded::<Query>(16);

        // Parse config and push instructions to supervisor.

        // ... //

        Ok(Self {
            supervisor,
            sender,
            receiver,
        })
    }

    pub fn start(&self, system:System, block:bool) -> bool
    {
        let resp = if block { Some(self.sender.clone()) } else { None };
        if self.supervisor.send(Query::new(resp, QueryData::Supervisor(
            SupervisorQuery::Start { system }
        ))).is_ok() {
            if block {
                while let Ok(query) = self.receiver.recv() {
                    match query.data {
                        QueryData::Supervisor(query) => match query {
                            SupervisorQuery::Status {
                                system,
                                channel,
                            } => match system {
                                System::Window => { return channel.is_some() }
                                _ => { }
                            }
                            _ => { }
                        }
                        _ => { }
                    }
                }
            }
            return true;
        }
        return false;
    }

    pub fn sys_window(&self) -> Option<system::WindowManager>
    {
        if self.supervisor.send(Query::new(Some(self.sender.clone()), QueryData::Supervisor(
            SupervisorQuery::Status { system: System::Window, channel: None }
        ))).is_ok() {
            match self.receiver.recv() {
                Ok(query) => match query.data {
                    QueryData::Supervisor(query) => match query {
                        SupervisorQuery::Status {
                            system,
                            channel
                        } => match system {
                            System::Window => {
                                if let Some(channel) = channel {
                                    Some(WindowManager::from(channel))
                                } else {
                                    None
                                }
                            }
                            _ => None
                        }
                        _ => None
                    }
                    _ => None
                }
                Err(_) => None
            }
        } else {
            None
        }
    }
}
