mod add_remove;
mod assembly;
mod display;
mod engine;
mod outline;
mod specified;

#[cfg(test)]
mod tests;

use std::{collections::BTreeSet, rc::Rc};
use sycamore::prelude::*;

use add_remove::AddRemove;
use assembly::{Assembly, Element};
use display::Display;
use outline::Outline;

#[derive(Clone)]
struct AppState {
    assembly: Assembly,
    selection: Signal<BTreeSet<Rc<dyn Element>>>
}

impl AppState {
    fn new() -> AppState {
        AppState {
            assembly: Assembly::new(),
            selection: create_signal(BTreeSet::default())
        }
    }
    
    // in single-selection mode, select the given element. in multiple-selection
    // mode, toggle whether the given element is selected
    fn select(&self, element: &Rc<dyn Element>, multi: bool) {
        if multi {
            self.selection.update(|sel| {
                if !sel.remove(element) {
                    sel.insert(element.clone());
                }
            });
        } else {
            self.selection.update(|sel| {
                sel.clear();
                sel.insert(element.clone());
            });
        }
    }
}

fn main() {
    // set the console error panic hook
    #[cfg(feature = "console_error_panic_hook")]
    console_error_panic_hook::set_once();
    
    sycamore::render(|| {
        provide_context(AppState::new());
        
        view! {
            div(id="sidebar") {
                AddRemove {}
                Outline {}
            }
            Display {}
        }
    });
}