module Sound.ALSA.Sequencer.Query (
  C,
  init,
  next,
  first,
  loop_,
  loop,
  ) where

import qualified Sound.ALSA.Sequencer.Marshal.Sequencer as Seq
import qualified Sound.ALSA.Sequencer.Area as Area

import Control.Monad (liftM2, when, )

import Prelude hiding (init, )


class Area.C info => C info where
  init :: info -> IO ()
  next :: Seq.T mode -> info -> IO Bool

first :: (C info) => Seq.T mode -> IO info
first :: forall info mode. C info => T mode -> IO info
first T mode
h = do
  info
i <- forall area. C area => IO area
Area.malloc
  forall info. C info => info -> IO ()
init info
i
  Bool
_b <- forall info mode. C info => T mode -> info -> IO Bool
next T mode
h info
i
  forall (m :: * -> *) a. Monad m => a -> m a
return info
i

loop_ :: (C info) => Seq.T mode -> (info -> IO ()) -> (info -> IO ()) -> IO ()
loop_ :: forall info mode.
C info =>
T mode -> (info -> IO ()) -> (info -> IO ()) -> IO ()
loop_ T mode
h info -> IO ()
start info -> IO ()
f = do
  info
i <- forall area. C area => IO area
Area.malloc
  info -> IO ()
start info
i
  forall info. C info => info -> IO ()
init info
i
  let go :: IO ()
go = do
         Bool
b <- forall info mode. C info => T mode -> info -> IO Bool
next T mode
h info
i
         forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b forall a b. (a -> b) -> a -> b
$ info -> IO ()
f info
i forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
go
  IO ()
go

loop :: (C info) => Seq.T mode -> (info -> IO ()) -> (info -> IO a) -> IO [a]
loop :: forall info mode a.
C info =>
T mode -> (info -> IO ()) -> (info -> IO a) -> IO [a]
loop T mode
h info -> IO ()
start info -> IO a
f = do
  info
i <- forall area. C area => IO area
Area.malloc
  info -> IO ()
start info
i
  forall info. C info => info -> IO ()
init info
i
  let go :: IO [a]
go = do
         Bool
b <- forall info mode. C info => T mode -> info -> IO Bool
next T mode
h info
i
         if Bool
b then forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) (info -> IO a
f info
i) IO [a]
go else forall (m :: * -> *) a. Monad m => a -> m a
return []
  IO [a]
go