    -- #hide
    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Sound.ALUT.Config
    -- Copyright   :  (c) Sven Panne 2006
    -- License     :  BSD-style (see the file libraries/ALUT/LICENSE)
    --
    -- Maintainer  :  sven.panne@aedion.de
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- This purely internal module defines the platform-specific stuff which has
    -- been figured out by configure.
    --
    --------------------------------------------------------------------------------

    module Sound.ALUT.Config (
       alut_Init,
       alut_InitWithoutContext,
       alut_Exit,

       alut_GetError,
       alut_GetErrorString,

       alut_CreateBufferFromFile,
       alut_CreateBufferFromFileImage,
       alut_CreateBufferHelloWorld,
       alut_CreateBufferWaveform,

       alut_LoadMemoryFromFile,
       alut_LoadMemoryFromFileImage,
       alut_LoadMemoryHelloWorld,
       alut_LoadMemoryWaveform,

       alut_GetMIMETypes,

       alut_GetMajorVersion,
       alut_GetMinorVersion,

       alut_Sleep
    ) where

    --------------------------------------------------------------------------------

    #include "HsALUTConfig.h"

    --------------------------------------------------------------------------------

    import Foreign.C
    import Foreign.Ptr
    import Sound.OpenAL.AL.BasicTypes

    #if ALUTINIT_VOID || !HAVE_ALUTINITWITHOUTCONTEXT || ALUTEXIT_VOID || !HAVE_ALUTSLEEP
    import Sound.OpenAL.AL.ALboolean
    #endif

    #if !HAVE_ALUTCREATEBUFFERFROMFILE || !HAVE_ALUTCREATEBUFFERFROMFILEIMAGE || !HAVE_ALUTCREATEBUFFERHELLOWORLD || !HAVE_ALUTCREATEBUFFERWAVEFORM
    import Sound.OpenAL.AL.BufferInternal
    #endif

    #if !HAVE_ALUTSLEEP && defined(__GLASGOW_HASKELL__)
    import Control.Concurrent
    #endif

    --------------------------------------------------------------------------------

    #if ALUTINIT_VOID

    alut_Init :: Ptr CInt -> Ptr CString -> IO ALboolean
    alut_Init argc argv = alutInit argc argv >> return (marshalALboolean True)

    foreign import CALLCONV unsafe "alutInit"
       alutInit :: Ptr CInt -> Ptr CString -> IO ()

    #else

    foreign import CALLCONV unsafe "alutInit"
       alut_Init :: Ptr CInt -> Ptr CString -> IO ALboolean

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTINITWITHOUTCONTEXT

    foreign import CALLCONV unsafe "alutInitWithoutContext"
       alut_InitWithoutContext :: Ptr CInt -> Ptr CString -> IO ALboolean

    #else

    alut_InitWithoutContext :: Ptr CInt -> Ptr CString -> IO ALboolean
    alut_InitWithoutContext _ _ = return (marshalALboolean True)

    #endif

    --------------------------------------------------------------------------------

    #if ALUTEXIT_VOID

    alut_Exit :: IO ALboolean
    alut_Exit = alutExit >> return (marshalALboolean True)

    foreign import CALLCONV unsafe "alutExit"
       alutExit :: IO ()

    #else

    foreign import CALLCONV unsafe "alutExit"
       alut_Exit :: IO ALboolean

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTGETERROR

    foreign import CALLCONV unsafe "alutGetError"
       alut_GetError :: IO ALenum

    #else

    alut_GetError :: IO ALenum
    alut_GetError = return 0

    #endif

    --------------------------------------------------------------------------------

    alut_GetErrorString :: ALenum -> IO String

    #if HAVE_ALUTGETERRORSTRING

    alut_GetErrorString e = peekCString =<< alutGetErrorString e

    foreign import CALLCONV unsafe "alutGetErrorString"
       alutGetErrorString :: ALenum -> IO CString

    #else

    alut_GetErrorString _ = return "<unknown ALUT error>"

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTCREATEBUFFERFROMFILE

    foreign import CALLCONV unsafe "alutCreateBufferFromFile"
       alut_CreateBufferFromFile :: CString -> IO ALuint

    #else

    alut_CreateBufferFromFile :: CString -> IO ALuint
    alut_CreateBufferFromFile _ = return (marshalBuffer Nothing)

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTCREATEBUFFERFROMFILEIMAGE

    foreign import CALLCONV unsafe "alutCreateBufferFromFileImage"
       alut_CreateBufferFromFileImage :: Ptr a -> ALsizei -> IO ALuint

    #else

    alut_CreateBufferFromFileImage :: Ptr a -> ALsizei -> IO ALuint
    alut_CreateBufferFromFileImage _ _ =  return (marshalBuffer Nothing)

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTCREATEBUFFERHELLOWORLD

    foreign import CALLCONV unsafe "alutCreateBufferHelloWorld"
       alut_CreateBufferHelloWorld :: IO ALuint

    #else

    alut_CreateBufferHelloWorld :: IO ALuint
    alut_CreateBufferHelloWorld =  return (marshalBuffer Nothing)

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTCREATEBUFFERWAVEFORM

    foreign import CALLCONV unsafe "alutCreateBufferWaveform"
       alut_CreateBufferWaveform :: ALenum -> ALfloat -> ALfloat -> ALfloat -> IO ALuint

    #else

    alut_CreateBufferWaveform :: ALenum -> ALfloat -> ALfloat -> ALfloat -> IO ALuint
    alut_CreateBufferWaveform _ _ _ _ =  return (marshalBuffer Nothing)

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTLOADMEMORYFROMFILE

    foreign import CALLCONV unsafe "alutLoadMemoryFromFile"
       alut_LoadMemoryFromFile :: CString -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)

    #else

    alut_LoadMemoryFromFile :: CString -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)
    alut_LoadMemoryFromFile _ _ _ _ = return nullPtr

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTLOADMEMORYFROMFILEIMAGE

    foreign import CALLCONV unsafe "alutLoadMemoryFromFileImage"
       alut_LoadMemoryFromFileImage :: Ptr a -> ALsizei -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)

    #else

    alut_LoadMemoryFromFileImage :: Ptr a -> ALsizei -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)
    alut_LoadMemoryFromFileImage _ _ _ _ _ = return nullPtr

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTLOADMEMORYHELLOWORLD

    foreign import CALLCONV unsafe "alutLoadMemoryHelloWorld"
       alut_LoadMemoryHelloWorld :: Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)

    #else

    alut_LoadMemoryHelloWorld :: Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)
    alut_LoadMemoryHelloWorld _ _ _ = return nullPtr

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTLOADMEMORYWAVEFORM

    foreign import CALLCONV unsafe "alutLoadMemoryWaveform"
       alut_LoadMemoryWaveform :: ALenum -> ALfloat -> ALfloat -> ALfloat -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)

    #else

    alut_LoadMemoryWaveform :: ALenum -> ALfloat -> ALfloat -> ALfloat -> Ptr ALenum -> Ptr ALsizei -> Ptr ALfloat -> IO (Ptr b)
    alut_LoadMemoryWaveform _ _ _ _ _ _ _ = return nullPtr

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTGETMIMETYPES

    foreign import CALLCONV unsafe "alutGetMIMETypes"
       alut_GetMIMETypes :: ALenum -> IO CString

    #else

    alut_GetMIMETypes :: ALenum -> IO CString
    alut_GetMIMETypes _ = return nullPtr

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTGETMAJORVERSION

    foreign import CALLCONV unsafe "alutGetMajorVersion"
       alut_GetMajorVersion :: IO ALint

    #else

    alut_GetMajorVersion :: IO ALint
    alut_GetMajorVersion = return 0

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTGETMINORVERSION

    foreign import CALLCONV unsafe "alutGetMinorVersion"
       alut_GetMinorVersion :: IO ALint

    #else

    alut_GetMinorVersion :: IO ALint
    alut_GetMinorVersion = return 0

    #endif

    --------------------------------------------------------------------------------

    #if HAVE_ALUTSLEEP

    foreign import CALLCONV unsafe "alutSleep"
       alut_Sleep :: ALfloat -> IO ALboolean

    #else

    alut_Sleep :: ALfloat -> IO ALboolean
    alut_Sleep d = mySleep d  >> return (marshalALboolean True)

    mySleep :: ALfloat -> IO ()

    #if defined(__GLASGOW_HASKELL__)

    mySleep = threadDelay . round .  (* 1.0E6)

    #else

    mySleep = return ()

    #endif

    #endif