//! Map model.

use super::qobj::*;
use maraiah::{backtrace, err::*, map::{self, data::*}};
use crate::cc;

impl AbstractMapModel
{
   pub fn open_map(path: String) -> ResultS<EntryDataMap>
   {
      let mut fp = maraiah::file::open_mac(path)?;

      let map = map::head::read(&mut fp)?;
      let ent = map::entr::read_all(&map)?;

      map::data::read_all(map.head(), &ent)
   }

   pub fn get(&self, index: usize) -> (&u16, &EntryData)
   {
      self.map.iter().nth(index).unwrap()
   }

   /*
   pub fn get_mut(&mut self, index: usize) -> (&u16, &mut EntryData)
   {
      self.map.iter_mut().nth(index).unwrap()
   }
   */
}

impl AbstractMapModelTrait for AbstractMapModel
{
   /// Returns a new `AbstractMapModel` instance.
   fn new(emit: AbstractMapModelEmitter, _: AbstractMapModelList) -> Self
   {
      if cfg!(debug_assertions) {
         eprintln!("new AbstractMapModel");
      }

      Self{emit, map: EntryDataMap::default(), selected: None}
   }

   /// Returns the emitter of `self`.
   fn emit(&mut self) -> &mut AbstractMapModelEmitter {&mut self.emit}

   fn row_count(&self) -> usize {self.map.len()}

   fn prop_index(&self, index: usize) -> u64 {(*self.get(index).0).into()}

   fn prop_icon(&self, index: u16) -> String
   {
      match self.get(index.into()).1.get_type() {
         EntryType::Image   => "image-x-generic".to_string(),
         EntryType::Map     => ":/tycho/color/map.png".to_string(),
         EntryType::Other   => "image-missing".to_string(),
         EntryType::Physics => "applications-system".to_string(),
      }
   }

   /// Opens the map file at `path`.
   fn open(&mut self, path: String) -> bool
   {
      if cfg!(debug_assertions) {
         eprintln!("opening project: {}", &path);
      }

      match Self::open_map(path) {
         Ok(map) => {
            self.map = map;
            true
         }
         Err(e) => {
            backtrace!(e);
            cc::critical_msg("Error opening map", e);
            false
         }
      }
   }

   /// Saves the project into the original file.
   fn save(&self) -> bool
   {
      if cfg!(debug_assertions) {
         eprintln!("saving project");
      }

      false
   }

   /// Saves the project into `path`.
   fn save_as(&self, path: String) -> bool
   {
      if cfg!(debug_assertions) {
         eprintln!("saving project as {}", path);
      }

      false
   }

   /// Returns `true` if the file has been modified from its original state.
   fn is_dirty(&self) -> bool {false}

   fn deselect(&mut self) {self.selected = None;}

   fn select(&mut self, index: u16)
   {
      if cfg!(debug_assertions) {
         eprintln!("selecting map {}", index);
      }

      self.selected = Some(index);
   }
}

impl Drop for AbstractMapModel
{
   fn drop(&mut self)
   {
      if cfg!(debug_assertions) {
         eprintln!("drop AbstractMapModel");
      }
   }
}

pub struct AbstractMapModel {
   emit:     AbstractMapModelEmitter,
   map:      EntryDataMap,
   selected: Option<u16>,
}

// EOF
