//! Shapes file frame type.

use crate::durandal::{err::*, fixed::*};
use bitflags::bitflags;

/// Reads a `Frame`.
pub fn read(b: &[u8]) -> ResultS<Frame>
{
   read_data! {
      endian: BIG, buf: b, size: 36, start: 0, data {
         let flags   = u16[0] flag FrameFlags;
         let min_lt  = Fixed[2];
         let bmp_ind = u16[6] usize;
         let wrl_l   = Unit[16];
         let wrl_r   = Unit[18];
         let wrl_t   = Unit[20];
         let wrl_b   = Unit[22];
         let wrl_x   = Unit[24];
         let wrl_y   = Unit[26];
      }
   }

   Ok(Frame{flags, min_lt, bmp_ind, wrl_l, wrl_r, wrl_t, wrl_b, wrl_x, wrl_y})
}

/// A frame, also known as a low level shape.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Frame
{
   /// The flags for this frame.
   pub flags: FrameFlags,

   /// The minimum light level for this frame.
   pub min_lt: Fixed,

   /// The index of the bitmap this frame uses.
   pub bmp_ind: usize,

   /// The left translation for this frame.
   pub wrl_l: Unit,

   /// The right translation for this frame.
   pub wrl_r: Unit,

   /// The top translation for this frame.
   pub wrl_t: Unit,

   /// The bottom translation for this frame.
   pub wrl_b: Unit,

   /// The X translation for this frame.
   pub wrl_x: Unit,

   /// The Y translation for this frame.
   pub wrl_y: Unit,
}

bitflags! {
   /// Flags for `Frame`.
   #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
   pub struct FrameFlags: u16
   {
      /// The player's torso will obscure the player's legs.
      const OBSCURE = 1 << 13;
      /// The bitmap will be flipped on the vertical axis.
      const FLIP_Y  = 1 << 14;
      /// The bitmap will be flipped on the horizontal axis.
      const FLIP_X  = 1 << 15;
   }
}

// EOF
