//! Main map editor module.
//!
//! The entry point is responsible for maintaining the lifetime of the editor
//! and human interactions with it, but is otherwise not permitted to directly
//! edit it.

mod block;

pub use block::*;

use super::{color, draw::*};
use crate::{durandal::image::*, marathon::{machdr, map}};

impl MapEditor
{
   /// Opens the editor with a new map.
   pub fn open_new(&mut self)
   {
      *self = Self::default();
   }

   /// Opens the editor with an existing map.
   pub fn open_buf(&mut self, b: &[u8])
   {
      // TODO: handle errors gracefully
      let b = &b[machdr::try_mac_header(b)..];
      let wad = map::read(b).unwrap();

      let ent = wad.entries.iter().nth(0).unwrap().1;
      let info = ent.chunks.iter().find_map(|cnk| {
         match cnk {
            map::chnk::Chunk::Minf(info) => Some(info),
            _ => None,
         }
      }).unwrap().clone();

      let block = Block{info};

      dbg!(&block);

      *self = Self{blocks: vec![block],
                   tools:  Self::default_tools()};
   }

   /// Draws the screen for this editor state.
   pub fn draw<D, I>(&self, d: &mut D, im: &I)
      where D: DrawArea<NativeImage = I>,
            I: CacheImage
   {
      /*
      let dw = d.w();
      let dh = d.h();
      let iw = im.w();
      let ih = im.h();

      let tx_top = "Map Required To Proceed";
      let tx_bot = "CAS.qterm//CyberAcme Systems Inc.";

      d.clear(Color16::new(0, 0, 0));

      d.image((dw / 2 - iw / 2, dh / 2 - ih / 2), im);

      d.rect(Rect{x: 0, y: 0, w: dw, h: 18}, color::DARK_RED);
      d.text((4, 0), tx_top, color::RED);

      d.rect(Rect{x: 0, y: dh - 18, w: dw, h: 18}, color::DARK_RED);
      d.text((4, dh - 16), tx_bot, color::RED);
      */

      let _ = im;

      let text = &format!("{:#?}", &self);

      d.clear(Color16::new(0, 0, 0));
      d.text((0, 0), text, color::RED);
   }

   // Returns the default tools.
   const fn default_tools() -> (Tool, Tool) {(Tool::Points, Tool::Lines)}

   /// Returns a reference to the current block.
   pub fn cur_block(&self) -> &Block {self.blocks.last().unwrap()}

   /// Pushes a new block.
   pub fn push_block(&mut self, blk: Block) {self.blocks.push(blk);}

   /// Returns the current tool.
   pub fn tool(&self) -> &Tool {&self.tools.0}

   /// Sets the current tool, and returns the previous one.
   pub fn set_tool(&mut self, t: Tool) -> &Tool
   {
      self.tools.1 = self.tools.0.clone();
      self.tools.0 = t;

      &self.tools.1
   }

   /// Returns true if the current map is unclean and needs to be saved.
   pub fn unclean(&self) -> bool {true}
}

impl Default for MapEditor
{
   #[inline]
   fn default() -> Self
   {
      Self{blocks: vec![Block::default()], tools: Self::default_tools()}
   }
}

/// The state of an opened map editor.
#[derive(Debug)]
pub struct MapEditor
{
   blocks: Vec<Block>,
   tools:  (Tool, Tool),
}

/// A tool in the map editor.
#[derive(Clone, Debug)]
pub enum Tool
{
   Points,
   Lines,
   Polygons,
}

// EOF
