use crate::{
    edit_list::SelectionList,
    feature_types::{Grab, StringSearcher, ViewMode},
    node::NodeContainer,
    node_settings::NodeSettings,
    state_info::StateInfo,
    vector::Vector,
};

use copypasta::ClipboardContext;
use pns::{DynamicNet, Net, SafeNet};

use std::path::PathBuf;

/// This represents the editor you want to use to edit and display petri nets.
pub struct Editor {
    net: DynamicNet,
    text_content_shown: bool,
    nodes: NodeContainer,
    transition_index: usize,
    window_size: Vector,
    zoom: f32,
    selected: SelectionList,
    grab: Option<Grab>,
    view_mode: ViewMode,
    net_path: Option<PathBuf>,
    state_infos: Vec<StateInfo>,
    simulation: usize,
    mouse_pos: Vector,
    view_offset: Vector,
    clipboard: ClipboardContext,
    string_searcher: Option<StringSearcher>,
    changes: bool,
    snapping: Option<f32>,
    node_settings: NodeSettings,
}

impl Editor {
    /// Creates a new editor, which contains a renderer and knows about the window size.
    pub fn new(width: f32, height: f32, node_settings: NodeSettings) -> Editor {
        let net = Net::new();

        Editor {
            net: net.dynamic(),
            nodes: NodeContainer::empty(),
            transition_index: 0,
            text_content_shown: false,
            window_size: Vector::new(width, height),
            zoom: 1.0,
            selected: SelectionList::new(),
            grab: None,
            view_mode: ViewMode::Default,
            net_path: None,
            state_infos: Vec::new(),
            simulation: 0,
            mouse_pos: Vector::new(0.0, 0.0),
            view_offset: Vector::new(0.0, 0.0),
            string_searcher: None,
            clipboard: ClipboardContext::new().unwrap(),
            changes: false,
            snapping: Some(16.0),
            node_settings,
        }
    }

    fn relative_mouse_pos(&self) -> Vector {
        (self.mouse_pos - self.window_size / 2.0) * self.zoom + self.view_offset
    }
}

mod input;
mod render;
mod update;
