//! Shapes file sequence type.

use crate::{durandal::{bin::OptU16, err::*},
            marathon::{text::{mac_roman_conv, pascal_str},
                       xfer::TransferMode}};
use std::convert::TryFrom;

/// Reads a `Sequence`.
pub fn read(b: &[u8]) -> ResultS<Sequence>
{
   read_data! {
      endian: BIG, buf: b, size: 88, start: 0, data {
         let name    = u8[4; 34];
         let v_type  = u16[38] enum ViewType;
         let frames  = u16[40];
         let ticks   = u16[42];
         let key     = u16[44];
         let xfer    = u16[46] enum TransferMode;
         let xfer_pd = u16[48];
         let snd_beg = OptU16[50];
         let snd_key = OptU16[52];
         let snd_end = OptU16[54];
         let loop_f  = u16[58];
      }
   }

   let name = mac_roman_conv(ok!(pascal_str(name), "bad string")?);

   Ok(Sequence{name, v_type, frames, ticks, key, xfer, xfer_pd, snd_beg,
               snd_key, snd_end, loop_f})
}

/// A sequence, also known as a high level shape.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Sequence
{
   /// The display name for this sequence.
   pub name: String,

   /// The view type for each frame in this sequence.
   pub v_type: ViewType,

   /// The number of frames in this sequence.
   pub frames: u16,

   /// The number of ticks each frame in this sequence takes.
   pub ticks: u16,

   /// The key frame index for this sequence.
   pub key: u16,

   /// The transfer mode to play over this sequence.
   pub xfer: TransferMode,

   /// The period in game ticks the transfer mode plays over.
   pub xfer_pd: u16,

   /// The sound to play at the beginning of this sequence.
   pub snd_beg: OptU16,

   /// The sound to play at the key frame of this sequence.
   pub snd_key: OptU16,

   /// The sound to play at the end of this sequence.
   pub snd_end: OptU16,

   /// Which frame to loop on.
   pub loop_f: u16,
}

c_enum! {
   /// The type of or number of views for a sequence.
   #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
   #[derive(Debug)]
   pub enum ViewType: u16
   {
      Anim       = 1,
      Anim8from2 = 2,
      Anim4from3 = 3,
      Anim4      = 4,
      Anim8from5 = 5,
      Anim8      = 8,
      Anim5from3 = 9,
      Still      = 10,
      Anim5      = 11,
   }
}

// EOF
