//! `Projectile` type.

use crate::durandal::{bin::OptU16,
                      err::*,
                      fixed::{Fixed, Unit}};
use bitflags::bitflags;

use super::damg;

/// Reads a `PRpx` chunk.
pub fn read(b: &[u8]) -> ResultS<(Projectile, usize)>
{
   read_data! {
      endian: BIG, buf: b, size: 48, start: 0, data {
         let collection    = OptU16[0];
         let shape         = u16[2];
         let fxt_explode   = OptU16[4];
         let fxt_exp_media = OptU16[6];
         let fxt_trail     = OptU16[8];
         let tic_trail     = u16[10];
         let max_trail     = OptU16[12];
         let typ_media     = OptU16[14];
         let radius        = Unit[16];
         let dmg_rad       = Unit[18];
         let dmg_def       = damg::read[20; 12];
         let flags         = u32[32] flag ProjectileFlags;
         let speed         = Unit[36];
         let range         = Unit[38];
         let snd_pitch     = Fixed[40];
         let snd_fly       = OptU16[44];
         let snd_bounce    = OptU16[46];
      }
   }

   Ok((Projectile{collection, shape, fxt_explode, fxt_exp_media, fxt_trail,
                  tic_trail, max_trail, typ_media, radius, dmg_rad, dmg_def,
                  flags, speed, range, snd_pitch, snd_fly, snd_bounce}, 48))
}

/// A projectile definition.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Debug, Eq, PartialEq)]
pub struct Projectile
{
   pub collection:    OptU16,
   pub shape:         u16,
   pub fxt_explode:   OptU16,
   pub fxt_exp_media: OptU16,
   pub fxt_trail:     OptU16,
   pub tic_trail:     u16,
   pub max_trail:     OptU16,
   pub typ_media:     OptU16,
   pub radius:        Unit,
   pub dmg_rad:       Unit,
   pub dmg_def:       damg::Damage,
   pub flags:         ProjectileFlags,
   pub speed:         Unit,
   pub range:         Unit,
   pub snd_pitch:     Fixed,
   pub snd_fly:       OptU16,
   pub snd_bounce:    OptU16,
}

bitflags! {
   /// Flags for a projectile.
   #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
   pub struct ProjectileFlags: u32
   {
      const GUIDED            = 1;
      const STOP_ON_LOOP      = 1 << 1;
      const PERSISTENT        = 1 << 2;
      const ALIEN             = 1 << 3;
      const GRAVITY           = 1 << 4;
      const NO_HORZ_ERROR     = 1 << 5;
      const NO_VERT_ERROR     = 1 << 6;
      const TOGGLE_PANELS     = 1 << 7;
      const POS_VERT_ERROR    = 1 << 8;
      const MELEE             = 1 << 9;
      const RIPPER            = 1 << 10;
      const PASS_TRANS_RANDOM = 1 << 11;
      const PASS_TRANS_MORE   = 1 << 12;
      const DOUBLE_GRAVITY    = 1 << 13;
      const REBOUND_FLOOR     = 1 << 14;
      const THROUGH_MEDIA     = 1 << 15;
      const BECOME_ITEM       = 1 << 16;
      const BLOODY            = 1 << 17;
      const WANDER_HORZ       = 1 << 18;
      const USE_LOW_GRAV      = 1 << 19;
      const PASS_MEDIA        = 1 << 20;
   }
}

// EOF
