use std::rc::Rc;
use std::cell::RefCell;
use libc::{c_float, c_uint};
use std::ptr;
use traits::{Wrappable, Drawable};
use graphics::{Color, Texture, RenderTarget, FloatRect, IntRect, Transform, rc, RenderStates};
use sfml_types::Vector2f;
use sfml_types::sfBool;
use ffi::graphics::convex_shape as ffi;
pub struct ConvexShape {
convex_shape: *mut ffi::sfConvexShape,
texture: Option<Rc<RefCell<Texture>>>
}
pub struct ConvexShapePoints {
convex_shape: *mut ffi::sfConvexShape,
pos: u32
}
impl ConvexShape {
pub fn new(points_count: u32) -> Option<ConvexShape> {
let shape = unsafe { ffi::sfConvexShape_create() };
if shape.is_null() {
None
}
else {
unsafe {
ffi::sfConvexShape_setPointCount(shape, points_count as c_uint);
}
Some(ConvexShape {
convex_shape: shape,
texture: None
})
}
}
pub fn new_with_texture(texture: Rc<RefCell<Texture>>,
points_count: u32) -> Option<ConvexShape> {
let shape = unsafe { ffi::sfConvexShape_create() };
if shape.is_null() {
None
} else {
unsafe {
ffi::sfConvexShape_setTexture(shape, (*texture).borrow().unwrap(), sfBool::SFTRUE);
ffi::sfConvexShape_setPointCount(shape, points_count as c_uint)
}
Some(ConvexShape {
convex_shape: shape,
texture: Some(texture)
})
}
}
pub fn clone_opt(&self) -> Option<ConvexShape> {
let shape = unsafe { ffi::sfConvexShape_copy(self.convex_shape) };
if shape.is_null() {
None
} else {
Some(ConvexShape {
convex_shape: shape,
texture: self.texture.clone()
})
}
}
pub fn set_position(&mut self, position: &Vector2f) {
unsafe {
ffi::sfConvexShape_setPosition(self.convex_shape, *position)
}
}
pub fn set_position2f(&mut self, x: f32, y: f32) {
unsafe {
ffi::sfConvexShape_setPosition(self.convex_shape, Vector2f::new(x, y))
}
}
pub fn set_scale(&mut self, scale: &Vector2f) {
unsafe {
ffi::sfConvexShape_setScale(self.convex_shape, *scale)
}
}
pub fn set_scale2f(&mut self, scale_x: f32, scale_y: f32) {
unsafe {
ffi::sfConvexShape_setScale(self.convex_shape,
Vector2f::new(scale_x, scale_y))
}
}
pub fn set_origin(&mut self, origin: &Vector2f) {
unsafe {
ffi::sfConvexShape_setOrigin(self.convex_shape, *origin)
}
}
pub fn set_origin2f(&mut self, x: f32, y: f32) {
unsafe {
ffi::sfConvexShape_setOrigin(self.convex_shape, Vector2f::new(x, y))
}
}
pub fn move_(&mut self, offset: &Vector2f) {
unsafe {
ffi::sfConvexShape_move(self.convex_shape, *offset)
}
}
pub fn move2f(&mut self, offset_x: f32, offset_y: f32) {
unsafe {
ffi::sfConvexShape_move(self.convex_shape,
Vector2f::new(offset_x, offset_y))
}
}
pub fn scale(&mut self, factors: &Vector2f) {
unsafe {
ffi::sfConvexShape_scale(self.convex_shape, *factors)
}
}
pub fn scale2f(&mut self, factor_x: f32, factor_y: f32) {
unsafe {
ffi::sfConvexShape_scale(self.convex_shape,
Vector2f::new(factor_x, factor_y))
}
}
pub fn set_point(&mut self, index: u32, point: &Vector2f) {
unsafe {
ffi::sfConvexShape_setPoint(self.convex_shape,
index as c_uint, *point)
}
}
pub fn get_position(&self) -> Vector2f {
unsafe {
ffi::sfConvexShape_getPosition(self.convex_shape)
}
}
pub fn get_scale(&self) -> Vector2f {
unsafe {
ffi::sfConvexShape_getScale(self.convex_shape)
}
}
pub fn get_origin(&self) -> Vector2f {
unsafe {
ffi::sfConvexShape_getOrigin(self.convex_shape)
}
}
pub fn get_point(&self, index: u32) -> Vector2f {
unsafe {
ffi::sfConvexShape_getPoint(self.convex_shape, index as c_uint)
}
}
pub fn set_rotation(&self, angle: f32) {
unsafe {
ffi::sfConvexShape_setRotation(self.convex_shape, angle as c_float)
}
}
pub fn get_rotation(&self) -> f32 {
unsafe {
ffi::sfConvexShape_getRotation(self.convex_shape) as f32
}
}
pub fn rotate(&mut self, angle: f32) {
unsafe {
ffi::sfConvexShape_rotate(self.convex_shape, angle as c_float)
}
}
pub fn set_texture(&mut self, texture: Rc<RefCell<Texture>>, reset_rect: bool) {
unsafe {
ffi::sfConvexShape_setTexture(self.convex_shape, (*texture).borrow().unwrap(), sfBool::from_bool(reset_rect))
}
self.texture = Some(texture);
}
pub fn disable_texture(&mut self) {
self.texture = None;
unsafe {
ffi::sfConvexShape_setTexture(self.convex_shape,
ptr::null_mut(),
sfBool::SFTRUE)
}
}
pub fn set_fill_color(&mut self, color: &Color) {
unsafe {
ffi::sfConvexShape_setFillColor(self.convex_shape, *color)
}
}
pub fn set_outline_color(&mut self, color: &Color) {
unsafe {
ffi::sfConvexShape_setOutlineColor(self.convex_shape, *color)
}
}
pub fn set_outline_thickness(&mut self, thickness: f32) {
unsafe {
ffi::sfConvexShape_setOutlineThickness(self.convex_shape,
thickness as c_float)
}
}
pub fn get_texture(&self) -> Option<Rc<RefCell<Texture>>> {
self.texture.clone()
}
pub fn get_fill_color(&self) -> Color {
unsafe {
ffi::sfConvexShape_getFillColor(self.convex_shape)
}
}
pub fn get_outline_color(&self) -> Color {
unsafe {
ffi::sfConvexShape_getOutlineColor(self.convex_shape)
}
}
pub fn get_outline_thickness(&self) -> f32 {
unsafe {
ffi::sfConvexShape_getOutlineThickness(self.convex_shape) as f32
}
}
pub fn get_point_count(&self) -> u32 {
unsafe {
ffi::sfConvexShape_getPointCount(self.convex_shape) as u32
}
}
pub fn set_point_count(&mut self, count: u32) {
unsafe {
ffi::sfConvexShape_setPointCount(self.convex_shape, count as c_uint)
}
}
pub fn set_texture_rect(&mut self, rect: &IntRect) {
unsafe {
ffi::sfConvexShape_setTextureRect(self.convex_shape, *rect)
}
}
pub fn get_local_bounds(&self) -> FloatRect {
unsafe {
ffi::sfConvexShape_getLocalBounds(self.convex_shape)
}
}
pub fn get_global_bounds(&self) -> FloatRect {
unsafe {
ffi::sfConvexShape_getGlobalBounds(self.convex_shape)
}
}
pub fn get_texture_rect(&self) -> IntRect {
unsafe {
ffi::sfConvexShape_getTextureRect(self.convex_shape)
}
}
pub fn get_transform(&self) -> Transform {
unsafe {
ffi::sfConvexShape_getTransform(self.convex_shape)
}
}
pub fn get_inverse_transform(&self) -> Transform {
unsafe {
ffi::sfConvexShape_getInverseTransform(self.convex_shape)
}
}
pub fn points(&self) -> ConvexShapePoints {
ConvexShapePoints {
convex_shape: self.convex_shape,
pos: 0
}
}
}
impl Clone for ConvexShape {
fn clone(&self) -> ConvexShape {
let shape = unsafe { ffi::sfConvexShape_copy(self.convex_shape) };
if shape.is_null() {
panic!("Not enough memory to clone ConvexShape")
} else {
ConvexShape {
convex_shape: shape,
texture: self.texture.clone()
}
}
}
}
impl Iterator for ConvexShapePoints {
type Item = Vector2f;
fn next(&mut self) -> Option<Vector2f> {
let point_count =
unsafe { ffi::sfConvexShape_getPointCount(self.convex_shape) as u32 };
if self.pos == point_count {
None
} else {
self.pos += 1;
unsafe {
Some(ffi::sfConvexShape_getPoint(self.convex_shape,
self.pos as c_uint))
}
}
}
}
impl Wrappable<*mut ffi::sfConvexShape> for ConvexShape {
fn wrap(convex_shape: *mut ffi::sfConvexShape) -> ConvexShape {
ConvexShape {
convex_shape: convex_shape.clone(),
texture: None
}
}
fn unwrap(&self) -> *mut ffi::sfConvexShape {
self.convex_shape
}
}
impl Drawable for ConvexShape {
fn draw<RT: RenderTarget>(&self, render_target: &mut RT, render_states: &mut RenderStates) {
render_target.draw_convex_shape(self, render_states)
}
}
impl Drop for ConvexShape {
fn drop(&mut self) {
unsafe {
ffi::sfConvexShape_destroy(self.convex_shape)
}
}
}