//! Some implementations of Vertex that you might find useful

use crate::*;

use bytemuck::{Pod, Zeroable};
#[cfg(feature = "mesh")]
use wgpu::*;

/// A vertex that just has position
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct BasicVertex {
	pub pos: [f32; 3]
}

#[cfg(feature = "mesh")]
impl BasicVertex {
	const ATTRIBS: &'static [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 {
		// nothing special
		features!()
	}

	#[cfg(feature = "mesh")]
	fn attribs() -> &'static [VertexAttribute] {
		Self::ATTRIBS
	}
}

/// A vertex with position and colour
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct ColouredVertex {
	pub pos: [f32; 3],
	pub col: [f32; 4]
}

#[cfg(feature = "mesh")]
impl ColouredVertex {
	const ATTRIBS: &'static [VertexAttribute] = &vertex_attr_array![
		0 => Float32x3,
		1 => Float32x4
	];
}

impl Vertex for ColouredVertex {
	fn new(pos: [f32; 3], col: [f32; 4], _: [f32; 3], _: [f32; 2]) -> Self {
		Self {
			pos,
			col
		}
	}

	fn features() -> MeshFeatures {
		features!(Coloured)
	}

	#[cfg(feature = "mesh")]
	fn attribs() -> &'static [VertexAttribute] {
		Self::ATTRIBS
	}
}

/// A vertex with position and texture coordinates
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
#[repr(C)]
pub struct TexturedVertex {
	pub pos: [f32; 3],
	pub uvs: [f32; 2]
}

#[cfg(feature = "mesh")]
impl TexturedVertex {
	const ATTRIBS: &'static [VertexAttribute] = &vertex_attr_array![
		0 => Float32x3,
		1 => Float32x2
	];
}

impl Vertex for TexturedVertex {
	fn new(pos: [f32; 3], _: [f32; 4], _: [f32; 3], uvs: [f32; 2]) -> Self {
		Self {
			pos,
			uvs
		}
	}

	fn features() -> MeshFeatures {
		features!(Textured)
	}

	#[cfg(feature = "mesh")]
	fn attribs() -> &'static [VertexAttribute] {
		Self::ATTRIBS
	}
}
