//! Map model.

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

impl IMapModel
{
	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 IMapModelTrait for IMapModel
{
	/// Returns a new `IMapModel` instance.
	fn new(emit: IMapModelEmitter, _: IMapModelList) -> Self
	{
		if cfg!(debug_assertions) {
			eprintln!("new IMapModel");
		}

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

	/// Returns the emitter of `self`.
	fn emit(&mut self) -> &mut IMapModelEmitter {&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-map".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 dirty(&self) -> bool {self.dirty}

	fn set_dirty(&mut self, dirty: bool) {self.dirty = dirty;}

	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 IMapModel
{
	fn drop(&mut self)
	{
		if cfg!(debug_assertions) {
			eprintln!("drop IMapModel");
		}
	}
}

pub struct IMapModel {
	emit:     IMapModelEmitter,
	map:      EntryDataMap,
	selected: Option<u16>,
	dirty:    bool,
}

// EOF
