-- High level api for playing sounds (and background music)

module Sound.SFML (
    PolySound,
    newPolySound,
    freePolySound,
    triggerPolySound,
  ) where


import Data.IORef

import Control.Monad

import Foreign.Ptr

import Sound.SFML.LowLevel

-- * Sounds

-- | A PolySound allows you to trigger one sound multiple times (the sounds overlap)

data PolySound = PolySound FilePath (Ptr SoundBuffer) [Ptr Sound] (IORef Int)

instance Show PolySound where
    show (PolySound file _ _ _) = "PolySound " ++ show file

newPolySound :: FilePath -> Int -> IO PolySound
newPolySound path numberOfVoices = do
    buffer <- sfSoundBuffer_CreateFromFile path
    sounds <- forM [1 .. numberOfVoices] $ \ _ -> do
        sound <- sfSound_Create
        sfSound_SetBuffer sound buffer
        return sound
    ref <- newIORef 0
    return $ PolySound path buffer sounds ref

freePolySound :: PolySound -> IO ()
freePolySound (PolySound _ buffer sounds _) = do
    sfSoundBuffer_Destroy buffer
    mapM_ sfSound_Destroy sounds

triggerPolySound :: PolySound -> IO ()
triggerPolySound (PolySound _ _ sounds ref) = do
    i <- readIORef ref
    let i' = (i + 1) `mod` length sounds
    writeIORef ref i'
    sfSound_Play (sounds !! i)


-- * Music

-- There is always only one music lpaying at a single time.

-- | Loads and plays a music file once.
-- playMusic :: FilePath -> IO ()
-- playMusic = error "playMusic"

-- | Loads and plays a music file in a loop.
-- Stops if the program ends or 'stopMusic' is called.
-- playMusicLooped :: FilePath -> IO ()
-- playMusicLooped = error "playMusicLooped"

-- | Stops any background music that is playing.
-- stopMusic :: IO ()
-- stopMusic = error "stopMusic"