//! `Endpoint` type.

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

/// Reads an `EPNT` chunk.
pub fn read(b: &[u8]) -> ResultS<(Endpoint, usize)>
{
   read_data! {
      endian: BIG, buf: b, size: 16, start: 0, data {
         let flags   = u16[0] flag EndpointFlags;
         let hei_hi  = Unit[2];
         let hei_lo  = Unit[4];
         let pos     = pnts::read_o[6; 4];
         let support = u16[10];
      }
   }

   Ok((Endpoint{flags, hei_hi, hei_lo, pos, support}, 16))
}

/// Converts a vector of `Endpoint`s to a vector of `Point`s.
pub fn to_pnts(v: &[Endpoint]) -> Vec<pnts::Point>
{
   v.iter().map(|p| p.pos).collect()
}

/// A pre-processed point in world-space.
#[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Endpoint
{
   pub flags:   EndpointFlags,
   pub hei_hi:  Unit,
   pub hei_lo:  Unit,
   pub pos:     pnts::Point,
   pub support: u16,
}

bitflags! {
   /// Flags for `Endpoint`.
   #[cfg_attr(feature = "serde_obj", derive(serde::Serialize))]
   pub struct EndpointFlags: u16
   {
      const SOLID       = 1;
      const SAME_HEIGHT = 1 << 1;
      const TRANSPARENT = 1 << 2;
   }
}

// EOF
