//! QuickDraw PICT format loader.

pub mod clut;
pub mod pm;
pub mod rle;

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

/// Load a `PICT` image.
pub fn read(b: &[u8]) -> ResultS<Image8>
{
	read_data! {
		endian: BIG, buf: b, size: 10, start: 0, data {
			let h = u16[6] usize;
			let w = u16[8] usize;
		}
	}

	if w * h > 16_000_000 {
		bail!("image is too large");
	}

	let im = Image8::new(w, h);

	let mut p = 10; // size of header

	while p < b.len() {
		read_data! {
			endian: BIG, buf: b, size: 2, start: p, data {
				let op = u16[0];
			}
		}

		p += 2;

		match op {
			0x0098 => {
				// PackBitsRect
				return pm::area::read(im, &b[p..], true, false);
			}
			0x0099 => {
				// PackBitsRgn
				return pm::area::read(im, &b[p..], true, true);
			}
			0x009a => {
				// DirectBitsRect
				return pm::area::read(im, &b[p..], false, false);
			}
			0x009b => {
				// DirectBitsRgn
				return pm::area::read(im, &b[p..], false, true);
			}
			0x8200 => {
				// CompressedQuickTime
				unimplemented!();
			}
			0x00ff => {
				// OpEndPic
				break;
			}
			// help i'm trapped in an awful metafile format from the 80s
			0x0000 |           // NoOp
			0x001c |           // HiliteMode
			0x001e |           // DefHilite
			0x0038 |           // FrameSameRect
			0x0039 |           // PaintSameRect
			0x003a |           // EraseSameRect
			0x003b |           // InvertSameRect
			0x003c |           // FillSameRect
			0x8000 |           // Reserved
			0x8100 => (),      // Reserved
			0x0003 |           // TxFont
			0x0004 |           // TxFace
			0x0005 |           // TxMode
			0x0008 |           // PnMode
			0x000d |           // TxSize
			0x0011 |           // VersionOp
			0x0015 |           // PnLocHFrac
			0x0016 |           // ChExtra
			0x0023 |           // ShortLineFrom
			0x00a0 => p += 2,  // ShortComment
			0x0006 |           // SpExtra
			0x0007 |           // PnSize
			0x000b |           // OvSize
			0x000c |           // Origin
			0x000e |           // FgCol
			0x000f |           // BkCol
			0x0021 => p += 4,  // LineFrom
			0x001a |           // RGBFgCol
			0x001b |           // RGBBkCol
			0x001d |           // TxRatio
			0x0022 => p += 6,  // ShortLine
			0x0002 |           // BkPat
			0x0009 |           // PnPat
			0x0010 |           // TxRatio
			0x0020 |           // Line
			0x002e |           // GlyphState
			0x0030 |           // FrameRect
			0x0031 |           // PaintRect
			0x0032 |           // EraseRect
			0x0033 |           // InvertRect
			0x0034 => p += 8,  // FillRect
			0x002d => p += 10, // LineJustify
			0x0001 => p += usize::from(u16b(&b[p..  ]) & !1),     // Clip
			0x00a1 => p += usize::from(u16b(&b[p+2..]) & !1) + 2, // LongComment
			0x100..=
			0x7fff => p += usize::from(op >> 8) * 2, // Reserved
			_      => {
				bail!("invalid op in PICT");
			}
		}
	}

	Err(err_msg("no image in data"))
}

// EOF
