//! `Object` type.

use crate::{err::*, fixed::{Angle, Unit}};

/// Reads an `OBJS` chunk.
pub fn read(b: &[u8]) -> ResultS<(Object, usize)>
{
	read_data! {
		endian: BIG, buf: b, size: 16, start: 0, data {
			let group = u16[0];
			let index = u16[2];
			let angle = Angle[4];
			let poly  = u16[6];
			let pos_x = Unit[8];
			let pos_y = Unit[10];
			let pos_z = Unit[12];
			let flags = u16[14];
		}
	}

	let bias  = flags & 0xF0_00;
	let flags = flags & 0x0F_FF;
	let bias  = bias >> 12;
	let flags = flag_ok!(ObjectFlags, flags)?;

	Ok((Object{group, index, angle, poly, pos_x, pos_y, pos_z, flags, bias}, 16))
}

/// An object in the world.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Object {
	pub group: u16,
	pub index: u16,
	pub angle: Angle,
	pub poly:  u16,
	pub pos_x: Unit,
	pub pos_y: Unit,
	pub pos_z: Unit,
	pub flags: ObjectFlags,
	pub bias:  u16,
}

c_bitfield! {
	/// Flags for `Object`.
	#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
	pub struct ObjectFlags: u16 {
		INVISIBLE = 0,
		CEILING   = 1,
		BLIND     = 2,
		DEAF      = 3,
		FLOATING  = 4,
		NET_ONLY  = 5,
	}
}

// EOF
