content: module PlaySound (playSound) where
  
  import System.Process
  import System.Exit
  import Control.Monad
  import Control.Exception
  import System.IO.Error
  import System.IO
  import System.Directory
  import System.FilePath
  import qualified Data.ByteString.Lazy as B
  import System.Environment.Executable
  
  
  players :: FilePath -> FilePath -> [(FilePath, [String])]
  players myDir fn =
      [ ("sox",                              ["-q", fn, "-d"])
      , (myDir </> "contrib" </> "playmus",  [fn])
      ]
  
  playSound :: B.ByteString -> IO ()
  playSound content = do
      dir <- getTemporaryDirectory
      (tmp, h) <- openTempFile dir "tttool-audio.tmp"
      B.hPutStr h content
      hClose h
  
      (myDir,_) <- splitExecutablePath
  
      tryPrograms (players myDir tmp) $ do
          putStrLn "Could not play audio file."
          putStrLn "Do you have \"sox\" installed?"
  
      removeFile tmp
  
  tryPrograms [] e = e
  tryPrograms ((c,args):es) e = do
      -- Missing programs cause exceptions on Windows, but error 127 on Linux.
      -- Try to handle both here.
      r <- tryJust (guard . isDoesNotExistError) $ do
          ph <- runProcess  c args Nothing Nothing Nothing Nothing Nothing
          ret <- waitForProcess ph
          if ret == ExitSuccess then return True
          else if ret == ExitFailure 127 then return False
          else do
              putStrLn $ "Failed to execute \"" ++ c ++ "\" (" ++ show ret ++ ")"
              exitFailure
      case r of
         Right True -> return ()
         _ -> tryPrograms es e
  