//! Trait for mesh vertices that may use vertex components from the mesh file
//! Minimum data is position, maximum includes uvs, colours and normals

#[cfg(feature = "vertex-impls")]
mod impls;

#[cfg(feature = "vertex-impls")]
pub use impls::*;

use crate::features::*;

// exported for easy implementing
pub use bytemuck::{Pod, Zeroable};
#[cfg(feature = "mesh")]
use wgpu::*;

pub type Index = u32;

/// The vertex trait implemented by vertex types
/// # Example
/// ```
/// # use bytemuck::{Pod, Zeroable};
/// # use chair::{features, MeshFeatures, Vertex};
/// # use wgpu::*;
/// #[derive(Clone, Copy, Pod, Zeroable)]
/// #[repr(C)]
/// pub struct BasicVertex {
/// 	pub pos: [f32; 3]
/// }
///
/// const ATTRIBS: &[VertexAttribute] = &vertex_attr_array![
/// 	0 => Float32x3
/// ];
///
/// impl Vertex for BasicVertex {
/// 	fn new(pos: [f32; 3], _: [f32; 4], _: [f32; 3], _: [f32; 2]) -> Self {
/// 		Self {
/// 			pos
/// 		}
/// 	}
///
///		fn features() -> MeshFeatures {
///			features!()
///		}
///
/// 	fn attribs() -> &'static [VertexAttribute] {
/// 		ATTRIBS
/// 	}
/// }
/// ```

pub trait Vertex: Pod + Zeroable {
	/// Create a new vertex, using at least position
	fn new(pos: [f32; 3], col: [f32; 4], normals: [f32; 3], uvs: [f32; 2]) -> Self;

	/// Return the features required by this vertex format
	fn features() -> MeshFeatures;

	/// Return the attributes for each field in this vertex format
	#[cfg(feature = "mesh")]
	fn attribs() -> &'static [VertexAttribute];

	/// Return the vertex buffer layout for this vertex format
	#[cfg(feature = "mesh")]
	fn layout() -> VertexBufferLayout<'static> {
		VertexBufferLayout {
			array_stride: std::mem::size_of::<Self>() as BufferAddress,
			step_mode: VertexStepMode::Vertex,
			attributes: Self::attribs()
		}
	}
}
