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

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

use ot_tools_io::identifiers::{PlaybackSlotId, SavedState};
use ot_tools_io::markers::SlotMarkers;
use ot_tools_io::settings::SlotType;
use ot_tools_io::types::MarkersFile;
use ot_tools_io::IsDefault;

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

/// Alias of a DataFile container for the MarkersFile type
pub type MarkersDataFile = DataItem<MarkersFile>;

impl MarkersDataFile {
    fn get_path(dirpath: &Path, state: &SavedState) -> PathBuf {
        let path = dirpath.join(format!["markers.{}", state.file_extension()]);
        path
    }

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

    pub fn load(dirpath: &Path, state: &SavedState) -> R<Self> {
        let path = Self::get_path(dirpath, state);
        Self::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_mark(self, slot_type: &SlotType, slot_id: &PlaybackSlotId) -> SlotMarkers {
        match slot_type {
            SlotType::Static => self.data_ref().static_slots[slot_id.as_index()],
            SlotType::Flex => self.data_ref().flex_slots[slot_id.as_index()],
        }
    }

    pub fn slot_mark_ref(&self, slot_type: &SlotType, slot_id: &PlaybackSlotId) -> &SlotMarkers {
        match slot_type {
            SlotType::Static => &self.data_ref().static_slots[slot_id.as_index()],
            SlotType::Flex => &self.data_ref().flex_slots[slot_id.as_index()],
        }
    }

    pub fn slot_mark_mut(
        &mut self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
    ) -> &mut SlotMarkers {
        match slot_type {
            SlotType::Static => &mut self.data_mut().static_slots[slot_id.as_index()],
            SlotType::Flex => &mut self.data_mut().flex_slots[slot_id.as_index()],
        }
    }

    pub fn update_slot_mark(
        &mut self,
        slot_type: &SlotType,
        slot_id: &PlaybackSlotId,
        new: SlotMarkers,
    ) {
        match slot_type {
            SlotType::Static => self.data_mut().static_slots[slot_id.as_index()] = new,
            SlotType::Flex => self.data_mut().flex_slots[slot_id.as_index()] = new,
        }
    }
}
