mod load;
mod save;

use super::{snap, Editor};

use crate::state_info::StateInfo;

use pns::SafeNet;
use rfd::{FileDialog, MessageButtons, MessageDialog, MessageLevel};

use std::path::{Path, PathBuf};

impl Editor {
    fn file_dialog(&self) -> FileDialog {
        let dialog = FileDialog::new();

        if let Some(path) = &self.net_path {
            dialog.set_directory(path)
        } else {
            if let Ok(path) = std::env::current_dir() {
                dialog.set_directory(path)
            } else {
                dialog
            }
        }
    }

    fn project_paths(
        &self,
        folder_path: &Path,
    ) -> Option<(PathBuf, PathBuf, PathBuf, PathBuf, PathBuf)> {
        let folder_name = if let Some(folder_name) = folder_path.file_stem() {
            folder_name
        } else {
            MessageDialog::new()
                .set_level(MessageLevel::Error)
                .set_title("Error!")
                .set_description("Invalid project directory name")
                .set_buttons(MessageButtons::Ok)
                .show();
            return None;
        };

        let mut path = folder_path.to_path_buf();
        path.push(folder_name);

        Some((
            path.with_extension("pns"),
            path.with_extension("pnl"),
            path.with_extension("pnk"),
            path.with_extension("pnkp"),
            path.with_extension("story"),
        ))
    }

    /// Saves the current progress of a simulation.
    pub fn save_progress(&mut self, force_path: bool) {
        if self.net.simulated().is_some() {
            let info = &mut self.state_infos[self.simulation];
            if info.state_path.is_none() || force_path {
                if let Some(path) = info.file_dialog().save_file() {
                    info.state_path = Some(path);
                } else {
                    return;
                }
            }
            if let Some(net) = self.net.simulated() {
                let _ = net
                    .state(self.simulation)
                    .save(info.state_path.as_ref().unwrap());
            }
            info.changes = false;
        }
    }

    /// Loads the some progress for the simulation.
    pub fn load_progress(&mut self) {
        if self.net.simulated_mut().is_some() {
            let info = &self.state_infos[self.simulation];
            if let Some(path) = info.file_dialog().pick_file() {
                if let Some(net) = self.net.simulated_mut() {
                    if let Ok(_) = net.load_state(&path) {
                        let new_index = net.states.len() - 1;
                        let mut info = StateInfo {
                            state_path: Some(path),
                            changes: false,
                            callables: net
                                .transition_ids()
                                .map(|tid| (tid, (false, false)))
                                .collect(),
                        };
                        self.simulation = new_index;
                        info.update_state(&mut net.state_mut(new_index).state);
                        self.state_infos.push(info);
                    }
                }
            }
        }
    }
}
