//! QuickDraw PICT `PixMap` headers.

use crate::{bin::*, err::*, image::*};

/// Reads a `PixMap` header.
pub fn read<'a>(b: &'a [u8],
                pack: bool,
                clip: bool,
                im: &Image8) -> ResultS<(&'a [u8], Header)>
{
	read_data! {
		endian: BIG, buf: b, size: 36, start: 0, data {
			let pt_fl  = u16[0];
			let top    = u16[2] usize;
			let left   = u16[4] usize;
			let bottom = u16[6] usize;
			let right  = u16[8] usize;
			let pack_t = u16[12] enum PackType;
			let depth  = u16[28] enum Depth;
		}
	}

	if pt_fl & 0x8000 == 0 {
		bail!("PICT1 not supported");
	}

	if right - left != im.w() || bottom - top != im.h() {
		bail!("image bounds are incorrect");
	}

	let mut p = 46;

	// get CLUT if packed
	let clut = if pack {
		let (clut, sz) = pict::clut::read(&b[p..])?;
		p += sz;
		Some(clut)
	} else {
		None
	};

	p += 18; // srcRect, dstRect, mode

	if clip {
		p += usize::from(u16b(&b[p..])); // maskRgn
	}

	let rle = pack_t == PackType::Default ||
		       pack_t == PackType::Rle16 && depth == Depth::_16 ||
		       pack_t == PackType::Rle32 && depth == Depth::_32;

	let pitch = usize::from(pt_fl & 0x3FFF);

	Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
}

pub struct Header {
	pub pitch:  usize,
	pub pack_t: PackType,
	pub depth:  Depth,
	pub clut:   Option<Vec<Color8>>,
	pub rle:    bool,
}

c_enum! {
	pub enum Depth: u16 {
		_1  = 1,
		_2  = 2,
		_4  = 4,
		_8  = 8,
		_16 = 16,
		_32 = 32,
	}
}

c_enum! {
	pub enum PackType: u16 {
		Default = 0,
		None    = 1,
		NoPad   = 2,
		Rle16   = 3,
		Rle32   = 4,
	}
}

// EOF
