use libc::c_float;
use std::mem;
use std::rc::Rc;
use std::cell::RefCell;
use audio::{SoundStatus, SoundBuffer, SoundSource};
use system::Time;
use sfml_types::Vector3f;
use traits::Wrappable;
use sfml_types::sfBool;
use csfml_audio_sys as ffi;
pub struct Sound {
sound: *mut ffi::sfSound,
buffer: Option<Rc<RefCell<SoundBuffer>>>
}
impl Sound {
pub fn new() -> Option<Sound> {
let s = unsafe {ffi::sfSound_create()};
if s.is_null() {
None
}
else {
Some(Sound {
sound: s,
buffer: None
})
}
}
pub fn new_with_buffer(buffer: Rc<RefCell<SoundBuffer>>) -> Option<Sound> {
let s = unsafe {ffi::sfSound_create()};
if s.is_null() {
None
}
else {
unsafe {
ffi::sfSound_setBuffer(s, (*buffer).borrow().unwrap());
}
Some(Sound {
sound: s,
buffer: Some(buffer)
})
}
}
pub fn set_loop(&mut self, lloop: bool) {
unsafe {
ffi::sfSound_setLoop(self.sound, sfBool::from_bool(lloop))
}
}
pub fn get_loop(&self) -> bool {
unsafe {ffi::sfSound_getLoop(self.sound)}.to_bool()
}
pub fn play(&mut self) {
unsafe {ffi::sfSound_play(self.sound)}
}
pub fn pause(&mut self) {
unsafe {ffi::sfSound_pause(self.sound)}
}
pub fn stop(&mut self) {
unsafe {ffi::sfSound_stop(self.sound)}
}
pub fn get_status(&self) -> SoundStatus {
unsafe { mem::transmute(ffi::sfSound_getStatus(self.sound)) }
}
pub fn get_playing_offset(&self) -> Time {
Wrappable::wrap( unsafe {ffi::sfSound_getPlayingOffset(self.sound)})
}
pub fn set_playing_offset(&mut self, time_offset: Time) {
unsafe {
ffi::sfSound_setPlayingOffset(self.sound, time_offset.unwrap())
}
}
pub fn set_buffer(&mut self, buffer: Rc<RefCell<SoundBuffer>>) {
unsafe {
ffi::sfSound_setBuffer(self.sound, (*buffer).borrow().unwrap());
}
self.buffer = Some(buffer);
}
pub fn get_buffer(&self) -> Option<Rc<RefCell<SoundBuffer>>> {
self.buffer.clone()
}
}
impl SoundSource for Sound {
fn set_pitch(&mut self, pitch: f32) {
unsafe {ffi::sfSound_setPitch(self.sound, pitch as c_float)}
}
fn set_volume(&mut self, volume: f32) {
unsafe {ffi::sfSound_setVolume(self.sound, volume as c_float)}
}
fn set_position(&mut self, position: &Vector3f) {
unsafe {
ffi::sfSound_setPosition(self.sound, *position)
}
}
fn set_position3f(&mut self, x: f32, y: f32, z: f32) {
unsafe {
ffi::sfSound_setPosition(self.sound, Vector3f::new(x, y, z))
}
}
fn set_relative_to_listener(&mut self, relative: bool) {
unsafe {
ffi::sfSound_setRelativeToListener(self.sound, sfBool::from_bool(relative))
}
}
fn set_min_distance(&mut self, distance: f32) {
unsafe {ffi::sfSound_setMinDistance(self.sound, distance as c_float)}
}
fn set_attenuation(&mut self, attenuation: f32) {
unsafe {ffi::sfSound_setAttenuation(self.sound, attenuation as c_float)}
}
fn get_pitch(&self) -> f32 {
unsafe {
ffi::sfSound_getPitch(self.sound) as f32
}
}
fn get_volume(&self) -> f32 {
unsafe {
ffi::sfSound_getVolume(self.sound) as f32
}
}
fn get_position(&self) -> Vector3f {
unsafe {
ffi::sfSound_getPosition(self.sound)
}
}
fn is_relative_to_listener(&self) -> bool {
unsafe {ffi::sfSound_isRelativeToListener(self.sound)}.to_bool()
}
fn get_min_distance(&self) -> f32 {
unsafe {
ffi::sfSound_getMinDistance(self.sound) as f32
}
}
fn get_attenuation(&self) -> f32 {
unsafe {
ffi::sfSound_getAttenuation(self.sound) as f32
}
}
}
impl Clone for Sound {
fn clone(&self) -> Self {
let s = unsafe {ffi::sfSound_copy(self.sound)};
if s.is_null() {
panic!("Sound is null");
} else {
Sound {
sound: s,
buffer: self.get_buffer()
}
}
}
}
impl Drop for Sound {
fn drop(&mut self) {
unsafe {
ffi::sfSound_destroy(self.sound);
}
}
}