// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright © 2024 Mike Robeson [dijksterhuis]

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

use ot_tools_io::identifiers::SavedState;
use ot_tools_io::types::ProjectFile;
use ot_tools_io::IsDefault;

use crate::projects::DataItem;
use crate::projects::R;

/// Alias of a [`DataItem`] container for the [`ProjectFile`][ot_tools_io::types::ProjectFile] type
///
/// # DANGER
///
/// Do not update slots via this type.
/// Any changes you make to slot attributes via this type will be overriden when
/// project state is saved.
/// Use the dedicated [`crate::projects::slots::Slots`] type instead.
/// Refer to that type's documentation for more information.
pub type ProjDataFile = DataItem<ProjectFile>;

impl ProjDataFile {
    fn get_path(dirpath: &Path, state: &SavedState) -> PathBuf {
        dirpath
            .join(format!["project.{}", state.file_extension()])
            .to_path_buf()
    }

    // DO NOT WRITE
    pub fn create(dirpath: &Path) -> Self {
        let path = Self::get_path(dirpath, &SavedState::Working);
        let data = ProjectFile::default();
        Self::new(path, data)
    }

    pub fn load(dirpath: &Path, state: &SavedState) -> R<Self> {
        let path = Self::get_path(dirpath, state);
        ProjDataFile::read(path)
    }

    // noinspection DuplicatedCode
    pub fn to_new(&self, new_dirpath: &Path, state: &SavedState) -> Self {
        let mut new = self.clone();
        new.source = Self::get_path(new_dirpath, state);
        new
    }

    pub fn is_default(&self) -> R<bool> {
        Ok(self.data.is_default())
    }

    /*
    pub fn slot_attr(
        self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
    ) -> Option<SlotAttributes> {
        let attr = match slot_type {
            SlotType::Static => &self.data_ref().slots.static_slots[slot_id.as_index()],
            SlotType::Flex => &self.data_ref().slots.flex_slots[slot_id.as_index()],
        };

        attr.clone()
    }
    */

    /*
    pub fn slot_attr_ref(
        &self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
    ) -> Option<&SlotAttributes> {
        let attr = match slot_type {
            SlotType::Static => &self.data_ref().slots.static_slots[slot_id.as_index()],
            SlotType::Flex => &self.data_ref().slots.flex_slots[slot_id.as_index()],
        };

        if let Some(a) = attr {
            Some(a)
        } else {
            None
        }
    }
    */

    /*
    pub fn slot_attr_mut(
        &mut self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
    ) -> Option<&mut SlotAttributes> {
        let attr = match slot_type {
            SlotType::Static => &mut self.data_mut().slots.static_slots[slot_id.as_index()],
            SlotType::Flex => &mut self.data_mut().slots.flex_slots[slot_id.as_index()],
        };

        if let Some(a) = attr {
            Some(a)
        } else {
            None
        }
    }
    */

    /*
    pub fn update_slot_attr(
        &mut self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
        new: Option<SlotAttributes>,
    ) {
        match slot_type {
            SlotType::Static => self.data_mut().slots.static_slots[slot_id.as_index()] = new,
            SlotType::Flex => self.data_mut().slots.flex_slots[slot_id.as_index()] = new,
        }
    }
    */
}
