//
// IrrKlang Wrapper for PB
// Michael Taupitz (2007)
//
/* //////////////////////////////////////////////////////////////////////////// */


#ifdef USE_IRRKLANG
#include "irrlichtwrapper.h"
#include <irrKlang.h>

#pragma comment(lib, "irrKlang.lib")


#include "CFileFactoryIW.h"

using namespace irr;
using namespace core;
using namespace audio;


ISoundEngine* audiodevice;



/****h* IrrKlang
* NAME
*    IrrKlang-Wrapper Dokumentation
* DESCRIPTION
*   IrrKlang is a free high level 2D and 3D cross platform sound engine and audio library which plays several
*   file formats like
*   [TAB]
*   RIFF WAVE - (*.wav)
*   Ogg Vorbis - (*.ogg)
*   MPEG-1 Audio Layer 3 - (*.mp3)
*   Amiga Modules - (*.mod)
*   Impulse Tracker - (*.it)
*   Scream Tracker 3 - (*.s3d)
*   Fast Tracker 2 - (*.xm)
*   [/TAB]
****
*/

extern "C"
{


/****f* IrrKlang/IrrKlangStart
* NAME
*    IrrKlangStart - Load a Texture
* SYNOPSIS
*    bResult.l = IrrKlangStart( driver.l, option.l )
* FUNCTION
*    Creates an irrKlang device. The irrKlang device is the root object for using the sound engine.
* INPUTS
*    driver.l   - The sound output driver to be used for sound output. #IRRKLANG_ESOD_AUTO_DETECT to let irrKlang decide which driver will be best.
*   option.l    - A combination of #IRRKLANG_ESOE_ literals. Default value is #IRRKLANG_ESEO_DEFAULT_OPTIONS
* RESULT
*    #True, if the Device initialising are successfull
* EXAMPLE
*    bRes.l = IrrKlangStart(#IRRKLANG_ESOD_AUTO_DETECT, #IRRKLANG_ESEO_DEFAULT_OPTIONS)
* NOTES
*
****
#PBIMPORT:IrrKlangStart( driver.l=#IRRKLANG_ESOD_AUTO_DETECT, option.l=#IRRKLANG_ESEO_DEFAULT_OPTIONS)
*/

STATIC_EXPORT bool DLL_EXPORT IrrKlangStart(E_SOUND_OUTPUT_DRIVER driver, int option )
{
    audiodevice=createIrrKlangDevice( driver,  option);
    if (audiodevice)
        return true;
    return false;
}

/****f* IrrKlang/IrrKlangStop
* NAME
*    IrrKlangStop - Stop/Delete IrrKlang
* SYNOPSIS
*    IrrKlangStop( )
* FUNCTION
*    Stop all sounds and delete device
* RESULT
*    nothing
* EXAMPLE
*    IrrKlangStop()
****
#PBIMPORT:IrrKlangStop()
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangStop()
{
    audiodevice->stopAllSounds();
    audiodevice->drop();
}


/****f* IrrKlang/IrrKlangAddSound
* NAME
*    IrrKlangAddSound - Adds sound source
* SYNOPSIS
*    *soundsource.l = IrrKlangAddSound(filename.s, [[ mode.l ],[ preload=#False]] )
* FUNCTION
*    Adds sound source into the sound engine as file.
*
*   Please note: For performance reasons most implementations will not try to load
*   the sound file when calling this method, but only when IrrKlangPlay..() is called
*   with this sound source as parameter.
* INPUTS
*   filename.s  - name of the sound-file
*   mode.l      - Streaming mode for this sound source  (#IRRKLANG_EXSM_*)
*   preload.l   - If this flag is set to #False (which is default) the sound engine will not try to load the
*                 sound file when calling this method, but only when play() is called with this sound source
*                 as parameter.
* RESULT
*    pointer to a Sound source if success, otherwise #Null
* EXAMPLE
*   *soundsource.l = IrrKlangAddSound("mysound.ogg")
****
#PBIMPORT:IrrKlangAddSound(filename.p-ascii,mode.l=#IRRKLANG_ESM_AUTO_DETECT, preload=#False)
*/
STATIC_EXPORT void * DLL_EXPORT  IrrKlangAddSound(const c8 * cptrFile, E_STREAM_MODE streamMode,  bool preload)
{
    return (void *)audiodevice->addSoundSource( cptrFile, streamMode, preload );
}
/****f* IrrKlang/IrrKlangCatchSound
* NAME
*    IrrKlangCatchSound - Adds sound source from memory
* SYNOPSIS
*    *soundsource.l = IrrKlangCatchSound(*memory.l, length.lfilename.s )
* FUNCTION
*    Adds sound source into the sound engine from Memory.
* INPUTS
*   *memory.l   - pointer to the Memory whre the sound lies
*   length.l    - length of the soundfile in memory
*   filename.s  - name of the sound-file
* RESULT
*    pointer to a Sound source if success, otherwise #Null
* EXAMPLE
*   *soundsource.l = IrrKlangCatchSound("mysound.ogg")
****
#PBIMPORT:IrrKlangCatchSound(*memory.l, lemgth.l, filename.p-ascii)
*/
STATIC_EXPORT void * DLL_EXPORT  IrrKlangCatchSound(void *memory, s32 sizeInBytes, const c8 *soundName)
{
    return (void *)audiodevice->addSoundSource( memory,sizeInBytes,soundName );
}

/****f* IrrKlang/IrrKlangPlay2D
* NAME
*    IrrKlangPlay2D - plays a sound
* SYNOPSIS
*    *sound.l = IrrKlangPlay2D(*soundsource.l, [playLoped.l, [startPaused.l, [track.l]]] )
* FUNCTION
*    Plays a sound source as 2D sound with its default settings stored in the SoundSource.
* INPUTS
*   *soundsource.l  - pointer to a soundsource, previously added with IrrKLangAddSoundSource()
*   playLooped.l    - determine if the sound should play looped (default = #False)
*   startPaused.l   - determine if the sound initalized but not started (default = #False)
*   track.l         - Makes it possible to track the sound.
* RESULT
*    pointer to a Sound or #Null, please read the NOTES
* EXAMPLE
*   *sound.l = IrrKlangPlay2D("mysound.ogg")
* NOTES
*   It is important to know, thet you have the Sound play paused or tracked to get a pointer
*   back. And only with this pointer you can use the IrrKLangSound...()-Functions.
*   For example to change the volume.
****
#PBIMPORT:IrrKlangPlay2D(*soundsource.l, playLooped.l=#False, startPaused.l=#False,track.l=#false )
*/
STATIC_EXPORT void * DLL_EXPORT IrrKlangPlay2D (ISoundSource* sound ,bool playLooped,bool startPaused,bool track)
{
    return (void *)audiodevice-> play2D(sound, playLooped, startPaused,  track);
}

/****f* IrrKlang/IrrKlangPlay3D
* NAME
*    IrrKlangPlay3D - plays a 3D sound
* SYNOPSIS
*    *sound.l = IrrKlangPlay3D(*soundsource.l,x.f,y.f,z.f, [playLoped.l, [startPaused.l, [track.l]]] )
* FUNCTION
*    Plays a sound source as 3D sound with its default settings stored in the SoundSource.
*   The Position and volume now based on the position of the listener (IrrKlangSetListener())
* INPUTS
*   *soundsource.l  - pointer to a soundsource, previously added with IrrKLangAddSoundSource()
*   x.f,y.f,z.f     - position of the Sound in the 3D-Space
*   playLooped.l    - determine if the sound should play looped (default = #False)
*   startPaused.l   - determine if the sound initalized but not started (default = #False)
*   track.l         - Makes it possible to track the sound.
* RESULT
*    pointer to a Sound or #Null, please read the NOTES
* EXAMPLE
*   *sound.l = IrrKlangPlay3D("mysound.ogg",-20.0,0.0,-12.10)
* NOTES
*   It is important to know, thet you have the Sound play paused or tracked to get a pointer
*   back. And only with this pointer you can use the IrrKLangSound...()-Functions.
*   For example to change the volume.
****
#PBIMPORT:IrrKlangPlay3D(*soundsource.l, x.f, y.f, z.f, playLooped.l=#False, startPaused.l=#False,track.l=#false )
*/
STATIC_EXPORT void * DLL_EXPORT IrrKlangPlay3D (ISoundSource* sound, float X, float Y, float Z, bool playLooped,bool startPaused,bool track)
{
     return (void *)audiodevice-> play3D(sound, vector3df(X,Y,Z), playLooped, startPaused,  track);

}

/****f* IrrKlang/IrrKlangGetSoundVolume
* NAME
*    IrrKlangGetSoundVolume - Get the volume level from 0 to 1
* SYNOPSIS
*    volume.f = IrrKlangGetSoundVolume()
* FUNCTION
*    Get the volume level from 0 to 1
* RESULT
*    volume as float
* EXAMPLE
*   volume.f = IrrKlangGetSoundVolume()
****
#PBIMPORT:IrrKlangGetSoundVolume.f()
*/
STATIC_EXPORT float DLL_EXPORT IrrKlangGetSoundVolume (void)
{
    return audiodevice->getSoundVolume();
}

/****f* IrrKlang/IrrKLangSetSoundVolume
* NAME
*    IrrKLangSetSoundVolume - Set the volume level from 0 to 1
* SYNOPSIS
*    IrrKLangSetSoundVolume(level.f)
* INPUTS
*   level.f     - volume level from 0 to 1
* FUNCTION
*    Set the volume level from 0 to 1
* RESULT
*    volume as float
* EXAMPLE
*   IrrKLangSetSoundVolume(0.5)
****
#PBIMPORT:IrrKLangSetSoundVolume(level.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKLangSetSoundVolume (float level)
{
    audiodevice->setSoundVolume(level);
}

/****f* IrrKlang/IrrKlangGetSoundSource
* NAME
*    IrrKlangGetSoundSource - Get the SoundSource by Index
* SYNOPSIS
*    *SoundSource.l = IrrKlangGetSoundSource(index.l)
* INPUTS
*   index.l - index of the SoundSource
* FUNCTION
*    Get the SoundSource by Index
* RESULT
*    pointer to a SoundSource if successfull, otherwise #Null
* EXAMPLE
*   *SoundSource.l = IrrKlangGetSoundSource(2)
****
#PBIMPORT:IrrKlangGetSoundSource(index.l)
*/
STATIC_EXPORT void * DLL_EXPORT IrrKlangGetSoundSource(s32 index)
{
    return (void *)audiodevice->getSoundSource(index);
}

/****f* IrrKlang/IrrKlangGetSoundSourceByName
* NAME
*    IrrKlangGetSoundSourceByName - Get the SoundSource by Name
* SYNOPSIS
*    *SoundSource.l = IrrKlangGetSoundSourceByName(name.s)
* INPUTS
*   name.s  - Name of teh SoundSource requested
* FUNCTION
*    Get the SoundSource by Name
* RESULT
*    pointer to a SoundSource if successfull, otherwise #Null
* EXAMPLE
*   *SoundSource.l = IrrKlangGetSoundSourceByName("mysound.ogg")
****
#PBIMPORT:IrrKlangGetSoundSourceByName(name.p-ascii)
*/
STATIC_EXPORT void * DLL_EXPORT IrrKlangGetSoundSourceByName(const c8 *soundName)
{
    return (void *)audiodevice->getSoundSource(soundName);
}

//returns amount of loaded sound sources
/****f* IrrKlang/IrrKlangGetSoundSourceCount
* NAME
*    IrrKlangGetSoundSourceCount - returns amount of loaded sound sources
* SYNOPSIS
*    amount.l = IrrKlangGetSoundSourceCount()
* FUNCTION
*    returns amount of loaded sound sources
* RESULT
*    amount of SoundSources
* EXAMPLE
*   amount.l = IrrKlangGetSoundSourceCount()
****
#PBIMPORT:IrrKlangGetSoundSourceCount()
*/
STATIC_EXPORT s32 DLL_EXPORT IrrKlangGetSoundSourceCount()
{
    return audiodevice->getSoundSourceCount();
}

/****f* IrrKlang/IrrKlangIsCurrentlyPlaying
* NAME
*    IrrKlangIsCurrentlyPlaying - Returns if a sound with the specified source is currently playing.
* SYNOPSIS
*    bool.l = IrrKlangIsCurrentlyPlaying(*soundsource.l)
* INPUTS
*   *soundsource.l  - pointer to a SoundSource
* FUNCTION
*    Returns if a sound with the specified source is currently playing.
* RESULT
*    #True if the sound is playing
* EXAMPLE
*   bool.l = IrrKlangIsCurrentlyPlaying(*soundsource)
****
#PBIMPORT:IrrKlangIsCurrentlyPlaying(*soundsource.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangIsCurrentlyPlaying (ISoundSource *source)
{
    return audiodevice->isCurrentlyPlaying(source);
}

//Returns if a sound with the specified name is currently playing.

/****f* IrrKlang/IrrKlangIsCurrentlyPlayingByName
* NAME
*    IrrKlangIsCurrentlyPlayingByName - Returns if a sound with the specified name is currently playing.
* SYNOPSIS
*    bool.l = IrrKlangIsCurrentlyPlayingByName(soundname.s)
* INPUTS
*   soundname   - name of the Sound
* FUNCTION
*    Returns if a sound with the specified name is currently playing.
* RESULT
*    #True idf the sound is playing
* EXAMPLE
*   bool.l = IrrKlangIsCurrentlyPlayingByName("mysound.ogg")
****
#PBIMPORT:IrrKlangIsCurrentlyPlayingByName(soundname.p-ascii)
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangIsCurrentlyPlayingByName (const char *soundName)
{
    return audiodevice->isCurrentlyPlaying(soundName);
}

/****f* IrrKlang/IrrKlangIsMultiThreaded
* NAME
*    IrrKlangIsMultiThreaded - Returns if irrKlang is running in the same thread as the application or is using multithreading.
* SYNOPSIS
*    bool.l = IrrKlangIsMultiThreaded()
* FUNCTION
*    Returns if irrKlang is running in the same thread as the application or is using multithreading.
* RESULT
*    #True if is mulktithreaded
* EXAMPLE
*   bool.l = IrrKlangIsMultiThreaded()
****
#PBIMPORT:IrrKlangIsMultiThreaded()
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangIsMultiThreaded()
{
    return audiodevice->isMultiThreaded();
}

/****f* IrrKlang/IrrKlangRemoveAllSoundSources
* NAME
*    IrrKlangRemoveAllSoundSources - Removes all sound sources from the engine.
* SYNOPSIS
*   IrrKlangRemoveAllSoundSources()
* FUNCTION
*   Removes all sound sources from the engine.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangRemoveAllSoundSources()
****
#PBIMPORT:IrrKlangRemoveAllSoundSources()
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangRemoveAllSoundSources()
{
    audiodevice->removeAllSoundSources();
}

/****f* IrrKlang/IrrKlangRemoveSoundSource
* NAME
*    IrrKlangRemoveSoundSource - Removes a sound source from the engine
* SYNOPSIS
*   IrrKlangRemoveSoundSource(*soundsource.l)
* INPUTS
*   *soundsource.l  - pointer to a SoundSource
* FUNCTION
*   Removes a sound source from the engine, freeing the memory it occupies.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangRemoveSoundSource(*soundsource)
****
#PBIMPORT:IrrKlangRemoveSoundSource(*soundsource.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangRemoveSoundSource(ISoundSource *source)
{
    audiodevice->removeSoundSource(source);
}

/****f* IrrKlang/IrrKlangSetAllSoundsPaused
* NAME
*    IrrKlangSetAllSoundsPaused - pauses or unpauses all currently playing sounds
* SYNOPSIS
*   IrrKlangSetAllSoundsPaused(bPaused.l)
* INPUTS
*   bPaused.l  - #True to pause all sounds, #False to unpause
* FUNCTION
*   pauses or unpauses all currently playing sounds
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangSetAllSoundsPaused(#True)
****
#PBIMPORT:IrrKlangSetAllSoundsPaused(bPaused.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSetAllSoundsPaused(bool bPaused)
{
    audiodevice->setAllSoundsPaused(bPaused);
}

/****f* IrrKlang/IrrKlangListenerPosition
* NAME
*    IrrKlangListenerPosition - Set the Listener 3D position
* SYNOPSIS
*   IrrKlangListenerPosition (posx.f, posy.f, posZ.f, lookX.f, lookY.f, lookZ.f, velpersecX.f, velpersecY.f, velpersecZ.f, upVectorX.f, upVectorY.f,  upVectorZ.f)
* INPUTS
*   posx.f,posy.f,posZ.f       - position of the listener in the 3D-Space
*   lookX.f,lookY.f,lookZ.f    - looking direction of the listener
*   velpersecX.f,velpersecY.f,velpersecZ.f  -
*   upVectorX.f, upVectorY.f,  upVectorZ.f  -
* FUNCTION
*   Sets the current listener 3d position.
*   The velocity per second is only needed for doppler effects.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangListenerPosition(10,10,10 , 0,0,0, 0,0,0 , 0,0,0)
****
#PBIMPORT:IrrKlangListenerPosition (posx.f, posy.f, posZ.f, lookX.f, lookY.f, lookZ.f, velpersecX.f, velpersecY.f, velpersecZ.f, upVectorX.f, upVectorY.f,  upVectorZ.f)
*/
void  DLL_EXPORT IrrKlangListenerPosition (float posX, float posY, float posZ,
                                           float lookX, float lookY, float lookZ,
                                           float velpersecX, float velpersecY, float velpersecZ,
                                           float upVectorX, float upVectorY, float upVectorZ)
{

     audiodevice->setListenerPosition(vector3df(posX,posY,posZ),
                                       vector3df(lookX,lookY,lookZ),
		                               vector3df(velpersecX,velpersecY,velpersecZ),
			                           vector3df(upVectorX,upVectorY,upVectorZ));

}


/****f* IrrKlang/IrrKlangGetDefault3DSoundMaxDistance
* NAME
*    IrrKlangGetDefault3DSoundMaxDistance - Returns the default maximal distance for 3D sounds.
* SYNOPSIS
*   maxDist.f = IrrKlangGetDefault3DSoundMaxDistance()
* FUNCTION
*   Returns the default maximal distance for 3D sounds.
* RESULT
*    maximal distance
* EXAMPLE
*   maxDist.f = IrrKlangGetDefault3DSoundMaxDistance()
****
#PBIMPORT:IrrKlangGetDefault3DSoundMaxDistance.f()
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangGetDefault3DSoundMaxDistance()
{
    return audiodevice->getDefault3DSoundMaxDistance ();
}

/****f* IrrKlang/IrrKlangGetDefault3DSoundMinDistance
* NAME
*    IrrKlangGetDefault3DSoundMinDistance - Returns the default minimal distance for 3D sounds.
* SYNOPSIS
*   minDist.f = IrrKlangGetDefault3DSoundMinDistance()
* FUNCTION
*   Returns the default minimal distance for 3D sounds.
* RESULT
*    minimal distance
* EXAMPLE
*   minDist.f = IrrKlangGetDefault3DSoundMinDistance()
****
#PBIMPORT:IrrKlangGetDefault3DSoundMinDistance.f()
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangGetDefault3DSoundMinDistance()
{
    return audiodevice->getDefault3DSoundMinDistance ();
}


/****f* IrrKlang/IrrKlangSetDefault3DSoundMaxDistance
* NAME
*    IrrKlangSetDefault3DSoundMaxDistance - Sets the default maximal distance for 3D sounds.
* SYNOPSIS
*    IrrKlangSetDefault3DSoundMaxDistance(maxDistance.f)
* INPUTS
*   maxDistance.f - maximal distance for 3D Sounds
* FUNCTION
*   Sets the default maximal distance for 3D sounds.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSetDefault3DSoundMaxDistance(20.00)
****
#PBIMPORT:IrrKlangSetDefault3DSoundMaxDistance(maxDistance.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSetDefault3DSoundMaxDistance(f32 maxDistance)
{
    audiodevice->setDefault3DSoundMaxDistance (maxDistance);
}


/****f* IrrKlang/IrrKlangSetDefault3DSoundMinDistance
* NAME
*    IrrKlangSetDefault3DSoundMinDistance - Sets the default minimal distance for 3D sounds.
* SYNOPSIS
*    IrrKlangSetDefault3DSoundMinDistance(minDistance.f)
* INPUTS
*   minDistance.f - minimal distance for 3D Sounds
* FUNCTION
*   Sets the default minimal distance for 3D sounds.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSetDefault3DSoundMinDistance(2.00)
****
#PBIMPORT:IrrKlangSetDefault3DSoundMinDistance(minDistance.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSetDefault3DSoundMinDistance(f32 minDistance)
{
    audiodevice->setDefault3DSoundMinDistance (minDistance);
}

/****f* IrrKlang/IrrKlangStopAllSounds
* NAME
*    IrrKlangStopAllSounds - Stop all sounds
* SYNOPSIS
*    IrrKlangStopAllSounds()
* FUNCTION
*   Stop all sounds
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangStopAllSounds()
****
#PBIMPORT:IrrKlangStopAllSounds()
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangStopAllSounds()
{
    audiodevice->stopAllSounds();
}


// Here we wrap ISound (a playing Sound)

/****f* IrrKlang/IrrKlangSoundGetIsPaused
* NAME
*    IrrKlangSoundGetIsPaused - returns if the sound is paused
* SYNOPSIS
*    bool.l = IrrKlangSoundGetIsPaused(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns if the sound is paused
* RESULT
*   #True if the sound is paused
* EXAMPLE
*   bool.l = IrrKlangSoundGetIsPaused(*sound)
****
#PBIMPORT:IrrKlangSoundGetIsPaused(*sound.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangSoundGetIsPaused(ISound* sound)
{
    return sound->getIsPaused();
}

/****f* IrrKlang/IrrKlangSoundGetMaxDistance
* NAME
*    IrrKlangSoundGetMaxDistance - Returns the maximal distance
* SYNOPSIS
*    maxDist.f = IrrKlangSoundGetMaxDistance(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   Returns the maximal distance if this is a 3D sound.
* RESULT
*   maximal distance
* EXAMPLE
*   maxDist.f = IrrKlangSoundGetMaxDistance(*sound)
****
#PBIMPORT:IrrKlangSoundGetMaxDistance.f(*sound.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSoundGetMaxDistance(ISound* sound)
{
    return sound->getMaxDistance();
}

/****f* IrrKlang/IrrKlangSoundGetMinDistance
* NAME
*    IrrKlangSoundGetMinDistance - Returns the minimal distance
* SYNOPSIS
*    minDist.f = IrrKlangSoundGetMinDistance(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   Returns the minimal distance if this is a 3D sound.
* RESULT
*   minimal distance
* EXAMPLE
*   minDist.f = IrrKlangSoundGetMinDistance(*sound)
****
#PBIMPORT:IrrKlangSoundGetMinDistance.f(*sound.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSoundGetMinDistance(ISound* sound)
{
    return sound->getMinDistance();
}

/****f* IrrKlang/IrrKlangSoundGetPan
* NAME
*    IrrKlangSoundGetPan - returns the pan of the sound
* SYNOPSIS
*    pan.f = IrrKlangSoundGetPan(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns the pan of the sound. Takes a value between -1 and 1, 0 is center.
* RESULT
*   pan
* EXAMPLE
*   pan.f = IrrKlangSoundGetPan(*sound)
****
#PBIMPORT:IrrKlangSoundGetPan.f(*sound.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSoundGetPan(ISound* sound)
{
    return sound->getPan();
}

/****f* IrrKlang/IrrKlangSoundGetPlayLength
* NAME
*    IrrKlangSoundGetPlayLength - returns the play length of the sound
* SYNOPSIS
*    length.l = IrrKlangSoundGetPlayLength(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns the play length of the sound in milliseconds.
* RESULT
*   length
* EXAMPLE
*   length.l = IrrKlangSoundGetPlayLength(*sound)
****
#PBIMPORT:IrrKlangSoundGetPlayLength(*sound.l)
*/
STATIC_EXPORT u32 DLL_EXPORT IrrKlangSoundGetPlayLength(ISound* sound)
{
    return sound->getPlayLength();
}

/****f* IrrKlang/IrrKlangSoundGetPlayPosition
* NAME
*    IrrKlangSoundGetPlayPosition - returns the current play position of the sound
* SYNOPSIS
*    pos.l = IrrKlangSoundGetPlayPosition(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns the current play position of the sound in milliseconds.
* RESULT
*   length
* EXAMPLE
*   pos.l = IrrKlangSoundGetPlayPosition(*sound)
****
#PBIMPORT:IrrKlangSoundGetPlayPosition(*sound.l)
*/
STATIC_EXPORT u32 DLL_EXPORT IrrKlangSoundGetPlayPosition(ISound* sound)
{
    return sound->getPlayPosition();
}

/****f* IrrKlang/IrrKlangSoundGetPosition
* NAME
*    IrrKlangSoundGetPosition - returns the position of the sound in 3d space
* SYNOPSIS
*    pos.l = IrrKlangSoundGetPosition(*sound.l, *x.f,*y.f,*z.f)
* INPUTS
*   *sound.l        - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*   *x.f,*y.f,*z.f  - returns the position of that sound
* FUNCTION
*   returns the position of the sound in 3d space
* RESULT
*   nothing, only via INOUT-Parameters
* EXAMPLE
*   IrrKlangSoundGetPosition(*sound,@x.f,@y.f,@z.f)
****
#PBIMPORT:IrrKlangSoundGetPosition(*sound.l,*x.f,*y.f,*z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundGetPosition(ISound* sound, f32 &x, f32 &y, f32 &z)
{
    vector3df pos = sound->getPosition();
    x = pos.X;
    y = pos.Y;
    z = pos.Z;
}

/****f* IrrKlang/IrrKlangSoundGetSoundSource
* NAME
*    IrrKlangSoundGetSoundSource - returns source of the sound
* SYNOPSIS
*    *soundsource.l = IrrKlangSoundGetSoundSource(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns source of the sound (with which you can get the filename or similar)
* RESULT
*   pointer to a sound source
* EXAMPLE
*   *soundsource.l = IrrKlangSoundGetSoundSource(*sound)
****
#PBIMPORT:IrrKlangSoundGetSoundSource(*sound.l)
*/
STATIC_EXPORT void* DLL_EXPORT IrrKlangSoundGetSoundSource(ISound* sound)
{
    return (void *)sound->getSoundSource();
}

/****f* IrrKlang/IrrKlangSoundGetVolume
* NAME
*    IrrKlangSoundGetVolume - returns volume of the sound
* SYNOPSIS
*    volume.f = IrrKlangSoundGetVolume(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns volume of the sound, a value between 0 (mute) and 1 (full volume).
* RESULT
*   volume of the sound
* EXAMPLE
*   volume.f = IrrKlangSoundGetVolume(*sound)
****
#PBIMPORT:IrrKlangSoundGetVolume.f(*sound.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSoundGetVolume(ISound* sound)
{
    return sound->getVolume();
}

/****f* IrrKlang/IrrKlangSoundIsFinished
* NAME
*    IrrKlangSoundIsFinished - returns if the sound has finished playing.
* SYNOPSIS
*    bool.l = IrrKlangSoundIsFinished(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns if the sound has finished playing.
* RESULT
*   #True if the Sound has finished
* EXAMPLE
*   bool.l = IrrKlangSoundIsFinished(*sound)
****
#PBIMPORT:IrrKlangSoundIsFinished(*sound.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangSoundIsFinished(ISound* sound)
{
    return sound->isFinished();
}

/****f* IrrKlang/IrrKlangSoundIsLooped
* NAME
*    IrrKlangSoundIsLooped - returns if the sound has been started to play looped
* SYNOPSIS
*    bool.l = IrrKlangSoundIsLooped(*sound.l)
* INPUTS
*   *sound.l - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   returns if the sound has been started to play looped
* RESULT
*   #True if the Sound play looped
* EXAMPLE
*   bool.l = IrrKlangSoundIsLooped(*sound)
****
#PBIMPORT:IrrKlangSoundIsLooped(*sound.l)
*/
STATIC_EXPORT bool DLL_EXPORT IrrKlangSoundIsLooped(ISound* sound)
{
    return sound->isLooped();
}

/****f* IrrKlang/IrrKlangSoundSetIsPaused
* NAME
*    IrrKlangSoundSetIsPaused - set the sound to paused or unpaused
* SYNOPSIS
*    IrrKlangSoundSetIsPaused(*sound.l,bPaused.l)
* INPUTS
*   *sound.l  - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*   bPaused.l - #True to pause , #False to unpause
* FUNCTION
*   set the sound to paused or unpaused
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetIsPaused(*sound,#False)
****
#PBIMPORT:IrrKlangSoundSetIsPaused(*sound.l, bPaused.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetIsPaused(ISound* sound,bool bPaused)
{
    sound->setIsPaused(bPaused);
}

/****f* IrrKlang/IrrKlangSoundSetMaxDistance
* NAME
*    IrrKlangSoundSetMaxDistance - Sets the maximal distance if this is a 3D sound.
* SYNOPSIS
*    IrrKlangSoundSetMaxDistance(*sound.l, max.f)
* INPUTS
*   *sound.l  - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*    max.f - maximal distance
* FUNCTION
*   Sets the maximal distance if this is a 3D sound.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetMaxDistance(*sound,40.0)
****
#PBIMPORT:IrrKlangSoundSetMaxDistance(*sound.l, max.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetMaxDistance(ISound* sound,f32 max)
{
    sound->setMaxDistance(max);
}

/****f* IrrKlang/IrrKlangSoundSetMinDistance
* NAME
*    IrrKlangSoundSetMinDistance - Sets the minimal distance if this is a 3D sound.
* SYNOPSIS
*    IrrKlangSoundSetMinDistance(*sound.l, min.f)
* INPUTS
*   *sound.l  - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*    min.f - minimal distance
* FUNCTION
*   Sets the minimal distance if this is a 3D sound.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetMinDistance(*sound,20.0)
****
#PBIMPORT:IrrKlangSoundSetMinDistance(*sound.l, min.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetMinDistance(ISound* sound,f32 min)
{
    sound->setMinDistance(min);
}

/****f* IrrKlang/IrrKlangSoundSetPan
* NAME
*    IrrKlangSoundSetPan - sets the pan of the sound
* SYNOPSIS
*    IrrKlangSoundSetPan(*sound.l, pan.f)
* INPUTS
*   *sound.l   - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*    pan.f     - pan of the sound
* FUNCTION
*   sets the pan of the sound. Takes a value between -1 and 1, 0 is center.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetPan(*sound,0.0)
****
#PBIMPORT:IrrKlangSoundSetPan(*sound.l, pan.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetPan(ISound* sound,f32 pan)
{
    sound->setPan(pan);
}

/****f* IrrKlang/IrrKlangSoundSetPosition
* NAME
*    IrrKlangSoundSetPosition - sets the position of the sound in 3d space
* SYNOPSIS
*    IrrKlangSoundSetPosition(*sound.l, x.f,y.f,z.f)
* INPUTS
*   *sound.l     - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*    x.f,y.f,z.f - position of the sound
* FUNCTION
*   sets the position of the sound in 3d space
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetPosition(*sound,0.0,20.0, 10.0)
****
#PBIMPORT:IrrKlangSoundSetPosition(*sound.l, x.f,y.f,z.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetPosition(ISound* sound,f32 x, f32 y, f32 z)
{
    sound->setPosition(vector3df(x,y,z));
}

/****f* IrrKlang/IrrKlangSoundSetVolume
* NAME
*    IrrKlangSoundSetVolume - sets the volume of the sound (0.0 - 1.0)
* SYNOPSIS
*    IrrKlangSoundSetVolume(*sound.l, vol.f)
* INPUTS
*   *sound.l    - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
*   vol.f       - volume of the sound
* FUNCTION
*   sets the volume of the sound, a value between 0 (mute) and 1 (full volume).
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundSetVolume(*sound,0.0)
****
#PBIMPORT:IrrKlangSoundSetVolume(*sound.l, vol.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundSetVolume(ISound* sound,f32 vol)
{
    sound->setVolume(vol);
}


//Will stop the sound and free its resources.
/****f* IrrKlang/IrrKlangSoundStop
* NAME
*    IrrKlangSoundStop - Will stop the sound and free its resources.
* SYNOPSIS
*    IrrKlangSoundStop(*sound.l)
* INPUTS
*   *sound.l    - pointer to Sound that is started via IrrKlangPlay2D() or IrrKlangPlay3D()
* FUNCTION
*   Will stop the sound and free its resources.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSoundStop(*sound)
****
#PBIMPORT:IrrKlangSoundStop(*sound.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSoundStop(ISound* sound)
{
    sound->stop();
}

// Now wrappen the SoundSource


/****f* IrrKlang/IrrKlangSSForceReloadAtNextUse
* NAME
*    IrrKlangSSForceReloadAtNextUse - Forces the sound to be reloaded at next replay.
* SYNOPSIS
*    IrrKlangSSForceReloadAtNextUse(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   Forces the sound to be reloaded at next replay.
* RESULT
*   nothing
* EXAMPLE
*   IrrKlangSSForceReloadAtNextUse(*soundsource)
****
#PBIMPORT:IrrKlangSSForceReloadAtNextUse(*soundsource.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSSForceReloadAtNextUse(ISoundSource* ss)
{
    ss->forceReloadAtNextUse();
}

/****f* IrrKlang/IrrKlangSSGetDefaultMaxDistance
* NAME
*    IrrKlangSSGetDefaultMaxDistance -  returns the default maxmial distance
* SYNOPSIS
*    max.f = IrrKlangSSGetDefaultMaxDistance(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   returns the default maxmial distance for 3D sounds played from this source.
* RESULT
*    returns the default maxmial distance as float
* EXAMPLE
*   max.f = IrrKlangSSGetDefaultMaxDistance(*soundsource)
****
#PBIMPORT:IrrKlangSSGetDefaultMaxDistance.f(*soundsource.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSSGetDefaultMaxDistance(ISoundSource* ss)
{
    return ss->getDefaultMaxDistance();
}

/****f* IrrKlang/IrrKlangSSGetDefaultMinDistance
* NAME
*    IrrKlangSSGetDefaultMinDistance -  returns the default minmial distance
* SYNOPSIS
*    min.f = IrrKlangSSGetDefaultMinDistance(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   returns the default minmial distance for 3D sounds played from this source.
* RESULT
*    returns the default minmial distance as float
* EXAMPLE
*   min.f = IrrKlangSSGetDefaultMinDistance(*soundsource)
****
#PBIMPORT:IrrKlangSSGetDefaultMinDistance.f(*soundsource.l)
*/
STATIC_EXPORT f32 DLL_EXPORT IrrKlangSSGetDefaultMinDistance(ISoundSource* ss)
{
    return ss->getDefaultMinDistance();
}

/****f* IrrKlang/IrrKlangSSGetForcedStreamingForceThreshold
* NAME
*    IrrKlangSSGetForcedStreamingForceThreshold -  Returns the threshold size
* SYNOPSIS
*    treshold.l = IrrKlangSSGetForcedStreamingForceThreshold(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   Returns the threshold size where irrKlang decides to force streaming a file
*   independent of the user specified setting.
* RESULT
*    returns the default minmial distance as float
* EXAMPLE
*   treshold.l = IrrKlangSSGetForcedStreamingForceThreshold(*soundsource)
****
#PBIMPORT:IrrKlangSSGetForcedStreamingForceThreshold(*soundsource.l)
*/
STATIC_EXPORT s32 DLL_EXPORT IrrKlangSSGetForcedStreamingForceThreshold(ISoundSource* ss)
{
    return ss->getForcedStreamingForceThreshold();
}

/****f* IrrKlang/IrrKlangSSGetName
* NAME
*    IrrKlangSSGetName -  returns the name of the sound source (usually, this is the file name)
* SYNOPSIS
*    name.s = IrrKlangSSGetName(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   returns the name of the sound source (usually, this is the file name)
* RESULT
*    name of the sound source (usually, this is the file name)
* EXAMPLE
*   name.s = IrrKlangSSGetName(*soundsource)
* PBINLINE
*   Macro IrrKlangSSGetName(__SOUNDSOURCE__)
*       PeekS(IrrKlangSSGetName_byMacro(__SOUNDSOURCE__),-1,#PB_Ascii)
*   EndMacro
* NOTES
*   Please mention that this function is covered by a Macro to Hide the 'Peek'.
****
#PBIMPORT:IrrKlangSSGetName_byMacro(*soundsource.l)
*/
STATIC_EXPORT void * DLL_EXPORT IrrKlangSSGetName_byMacro(ISoundSource* ss)
{
    return (void *)ss->getName();
}

/****f* IrrKlang/IrrKlangSSGetPlayLength
* NAME
*    IrrKlangSSGetPlayLength -  returns the play length of the sound in milliseconds.
* SYNOPSIS
*    length.l = IrrKlangSSGetPlayLength(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   returns the play length of the sound in milliseconds.
* RESULT
*    play length of the sound
* EXAMPLE
*   length.l = IrrKlangSSGetPlayLength(*soundsource)
****
#PBIMPORT:IrrKlangSSGetPlayLength(*soundsource.l)
*/
STATIC_EXPORT u32 DLL_EXPORT IrrKlangSSGetPlayLength(ISoundSource* ss)
{
    return ss->getPlayLength();
}

/****f* IrrKlang/IrrKlangSSGetStreamMode
* NAME
*    IrrKlangSSGetStreamMode - returns the detected or set type of the sound
* SYNOPSIS
*    mode.l = IrrKlangSSGetStreamMode(*soundsource.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
* FUNCTION
*   returns the detected or set type of the sound with wich the sound will be played.
* RESULT
*    the detected or set type
* EXAMPLE
*   mode.l = IrrKlangSSGetStreamMode(*soundsource)
****
#PBIMPORT:IrrKlangSSGetStreamMode(*soundsource.l)
*/
STATIC_EXPORT E_STREAM_MODE DLL_EXPORT IrrKlangSSGetStreamMode(ISoundSource* ss)
{
    return ss->getStreamMode();
}

//sets the default maximal distance for 3D sounds played from this source.
/****f* IrrKlang/IrrKlangSSSetDefaultMaxDistance
* NAME
*    IrrKlangSSSetDefaultMaxDistance - sets the default maximal distance for 3D sounds
* SYNOPSIS
*    IrrKlangSSSetDefaultMaxDistance(*soundsource.l, maxDistance.f)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
*   maxDistance.f    - maximal distance for 3D sounds
* FUNCTION
*   sets the default maximal distance for 3D sounds played from this source.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangSSSetDefaultMaxDistance(*soundsource,40.0)
****
#PBIMPORT:IrrKlangSSSetDefaultMaxDistance(*soundsource.l, maxDistance.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSSSetDefaultMaxDistance(ISoundSource* ss,f32 maxDistance)
{
    ss->setDefaultMaxDistance(maxDistance);
}

/****f* IrrKlang/IrrKlangSSSetDefaultMinDistance
* NAME
*    IrrKlangSSSetDefaultMinDistance - sets the default minimal distance for 3D sounds
* SYNOPSIS
*    IrrKlangSSSetDefaultMinDistance(*soundsource.l, minDistance.f)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
*   minDistance.f    - minimal distance for 3D sounds
* FUNCTION
*   sets the default minimal distance for 3D sounds played from this source.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangSSSetDefaultMinDistance(*soundsource,20.0)
****
#PBIMPORT:IrrKlangSSSetDefaultMinDistance(*soundsource.l, minDistance.f)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSSSetDefaultMinDistance(ISoundSource* ss,f32 minDistance)
{
    ss->setDefaultMinDistance(minDistance);
}


/****f* IrrKlang/IrrKlangSSSetForcedStreamingThreshold
* NAME
*    IrrKlangSSSetForcedStreamingThreshold - Sets the threshold size
* SYNOPSIS
*    IrrKlangSSSetForcedStreamingThreshold(*soundsource.l, thresholdBytes.l)
* INPUTS
*   *soundsource.l    - pointer to SoundSource that was added via IrrKlangAddSound()
*   thresholdBytes.l   - threshold size in bytes
* FUNCTION
*   Sets the threshold size where irrKlang decides to force streaming a file independent of the user specified setting.
* RESULT
*    nothing
* EXAMPLE
*   IrrKlangSSSetForcedStreamingThreshold(*soundsource,16*1024)
****
#PBIMPORT:IrrKlangSSSetForcedStreamingThreshold(*soundsource.l, thresholdBytes.l)
*/
STATIC_EXPORT void DLL_EXPORT IrrKlangSSSetForcedStreamingThreshold(ISoundSource* ss,s32 thresholdBytes)
{
    ss->setForcedStreamingThreshold(thresholdBytes);
}


/*
* This is for creating the PB-Importfile, and avoiding to make everything manual
#PBIMPORT:IrrklangAddCallbackFileSystem(*ptrToFSCallback)
*/
STATIC_EXPORT bool DLL_EXPORT IrrklangAddCallbackFileSystem( FileSystemFFCallbackPtr callBack )
{

    CFileFactoryIW * fact = new CFileFactoryIW(callBack);
    if (fact)
    {
        audiodevice->addFileFactory(fact);
//        device->getFileSystem()->addExternFileSysten(fact);
        return true;
    }

    return false;

}





} // extern C

#endif
