//! Marathon Shapes format handling.

pub mod bmap;
pub mod clut;
pub mod coll;
pub mod fram;
pub mod sequ;

use crate::durandal::{bin::usize_from_u32, err::*};

/// Reads a collection at an offset provided by the Shapes header.
pub fn read_coll_at_offset(b: &[u8], ofs: u32, len: usize)
   -> ResultS<Option<coll::Collection>>
{
   if ofs != u32::max_value() {
      let ofs = usize_from_u32(ofs);
      let dat = ok!(b.get(ofs..ofs + len), "bad offset")?;
      Ok(Some(coll::read(dat)?))
   } else {
      Ok(None)
   }
}

/// Read all of the collections in a Shapes file.
pub fn read(b: &[u8]) -> ResultS<Vec<CollectionDef>>
{
   let mut cl = Vec::with_capacity(32);
   let mut p  = 0;

   for _ in 0..32 {
      read_data! {
         endian: BIG, buf: b, size: 32, start: p, data {
            let lo_ofs = u32[4];
            let lo_len = u32[8] usize;
            let hi_ofs = u32[12];
            let hi_len = u32[16] usize;
         }
      }

      let lo = read_coll_at_offset(b, lo_ofs, lo_len)?;
      let hi = read_coll_at_offset(b, hi_ofs, hi_len)?;

      cl.push((lo, hi));

      p += 32;
   }

   Ok(cl)
}

/// A collection, which may have low- and high-definition variations, or none.
pub type CollectionDef = (Option<coll::Collection>, Option<coll::Collection>);

// EOF
