use libc::c_uint;
use std::mem;
use std::ops::Index;
use traits::Wrappable;
use graphics::{Drawable, Vertex, FloatRect, primitive_type, PrimitiveType, RenderTarget, RenderStates};
use csfml_graphics_sys as ffi;
pub struct VertexArray {
vertex_array: *mut ffi::sfVertexArray
}
pub struct Vertices<'a> {
vertex_array: &'a VertexArray,
pos: u32
}
impl VertexArray {
pub fn new() -> Option<VertexArray> {
let ver = unsafe { ffi::sfVertexArray_create() };
if ver.is_null() {
None
} else {
Some(VertexArray {
vertex_array: ver
})
}
}
pub fn new_init(primitive_type: PrimitiveType,
vertex_count: u32) -> Option<VertexArray> {
let ver = unsafe { ffi::sfVertexArray_create() };
if ver.is_null() {
None
} else {
let mut tmp_vertex = VertexArray {
vertex_array: ver
};
tmp_vertex.set_primitive_type(primitive_type);
tmp_vertex.resize(vertex_count);
Some(tmp_vertex)
}
}
pub fn clone_opt(&self) -> Option<VertexArray> {
let ver = unsafe { ffi::sfVertexArray_copy(self.vertex_array) };
if ver.is_null() {
None
} else {
Some(VertexArray {
vertex_array: ver
})
}
}
pub fn get_vertex_count(&self) -> u32 {
unsafe {
ffi::sfVertexArray_getVertexCount(self.vertex_array) as u32
}
}
pub fn clear(&mut self) {
unsafe {
ffi::sfVertexArray_clear(self.vertex_array)
}
}
pub fn resize(&mut self, vertex_count: u32) {
unsafe {
ffi::sfVertexArray_resize(self.vertex_array, vertex_count as c_uint)
}
}
pub fn append(&mut self, vertex: &Vertex) {
unsafe {
ffi::sfVertexArray_append(self.vertex_array, vertex.0)
}
}
pub fn get_bounds(&self) -> FloatRect {
unsafe {
ffi::sfVertexArray_getBounds(self.vertex_array)
}
}
pub fn set_primitive_type(&mut self, primitive_type: PrimitiveType) {
unsafe {
match primitive_type {
primitive_type::Points =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfPoints),
primitive_type::Lines =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfLines),
primitive_type::LinesStrip =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfLinesStrip),
primitive_type::Triangles =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfTriangles),
primitive_type::TrianglesStrip =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfTrianglesStrip),
primitive_type::TrianglesFan =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfTrianglesFan),
primitive_type::Quads =>
ffi::sfVertexArray_setPrimitiveType(self.vertex_array,
ffi::sfQuads)
}
}
}
pub fn get_primitive_type(&self) -> PrimitiveType {
match unsafe { ffi::sfVertexArray_getPrimitiveType(self.vertex_array) } {
ffi::sfPoints => primitive_type::Points,
ffi::sfLines => primitive_type::Lines,
ffi::sfLinesStrip => primitive_type::LinesStrip,
ffi::sfTriangles => primitive_type::Triangles,
ffi::sfTrianglesStrip => primitive_type::TrianglesStrip,
ffi::sfTrianglesFan => primitive_type::TrianglesFan,
ffi::sfQuads => primitive_type::Quads,
}
}
pub fn get_vertex(&self, index: u32) -> &mut Vertex {
unsafe {
mem::transmute(ffi::sfVertexArray_getVertex(self.vertex_array,
index as c_uint))
}
}
pub fn vertices(&self) -> Vertices {
Vertices {
vertex_array: self,
pos: 0
}
}
}
impl Clone for VertexArray {
fn clone(&self) -> VertexArray {
let ver = unsafe { ffi::sfVertexArray_copy(self.vertex_array) };
if ver.is_null() {
panic!("Not enough memory to clone Font")
} else {
VertexArray {
vertex_array: ver
}
}
}
}
impl<'a> Iterator for Vertices<'a> {
type Item = &'a Vertex;
fn next(&mut self) -> Option<&'a Vertex> {
let point_count =
unsafe { ffi::sfVertexArray_getVertexCount(self.vertex_array.vertex_array) as u32 };
if self.pos == point_count {
None
} else {
self.pos += 1;
unsafe {
mem::transmute(ffi::sfVertexArray_getVertex(self.vertex_array.vertex_array,
self.pos as c_uint))
}
}
}
}
impl Index<u32> for VertexArray {
type Output = Vertex;
fn index(&self, rhs: u32) -> &Vertex {
unsafe {
mem::transmute::<*const Vertex, &Vertex>
(ffi::sfVertexArray_getVertex(self.vertex_array,
rhs as c_uint) as *const Vertex)
}
}
}
impl Wrappable<*mut ffi::sfVertexArray> for VertexArray {
fn wrap(vertex_array: *mut ffi::sfVertexArray) -> VertexArray {
VertexArray {
vertex_array: vertex_array
}
}
fn unwrap(&self) -> *mut ffi::sfVertexArray {
self.vertex_array
}
}
impl Drawable for VertexArray {
fn draw<RT: RenderTarget>(&self,
render_target: &mut RT,
render_states: &mut RenderStates) {
render_target.draw_vertex_array(self, render_states)
}
}
impl Drop for VertexArray {
fn drop(&mut self) {
unsafe {
ffi::sfVertexArray_destroy(self.vertex_array)
}
}
}