//! Marathon Shapes format handling.

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

use crate::{bin::usize_from_u32, err::*};
use std::io::prelude::*;

/// 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(fp: &mut impl Read) -> ResultS<Collections>
{
	let mut b = Vec::new();
	fp.read_to_end(&mut b)?;

	let mut collections = vec![(None, None); 32];

	for (i, co) in collections.iter_mut().enumerate() {
		read_data! {
			endian: BIG, buf: &b, size: 32, start: i * 32, 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)?;

		*co = (lo, hi);
	}

	Ok(collections)
}

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

/// The set of all collections in a Shapes file.
pub type Collections = Vec<CollectionDef>;

// EOF
