{-
    Safe/Context.hs - wraps UI functions
    Copyright (C) 2021 Johannes Waldmann and contributors

    Forked from:
    https://github.com/jwaldmann/safe-tidal-cli/

    This library is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this library.  If not, see <http://www.gnu.org/licenses/>.
-}

{-# language GeneralizedNewtypeDeriving #-}
{-# language NoMonomorphismRestriction #-}
{-# OPTIONS_GHC -Wno-missing-signatures #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}

module Sound.Tidal.Safe.Context
  ( Op () -- do not export constructor,
    -- so the user has no way of putting arbitraty IO stuff
    -- in "Op", and below "run"
  , exec
  , streamReplace
  , streamHush
  , streamList
  , streamMute
  , streamUnmute
  , streamSolo
  , streamUnsolo
  , streamOnce
  , streamFirst
  , streamNudgeAll
  , streamAll
  , streamResetCycles
  , streamSetI
  , streamSetF
  , streamSetS
  , streamSetR
  , streamSetB
  , transition
  , module C
  , Target(..)
  )
where

import Data.Ratio as C
import Sound.Tidal.Config as C
import Sound.Tidal.Control as C
import Sound.Tidal.Core as C
import Sound.Tidal.Params as C
import Sound.Tidal.ParseBP as C
import Sound.Tidal.Pattern as C
import Sound.Tidal.Scales as C
import Sound.Tidal.Simple as C
import Sound.Tidal.Stream
  (startTidal, superdirtTarget, Target(..))
-- import Sound.Tidal.Transition as C
import Sound.Tidal.UI as C
import Sound.Tidal.Version as C

import qualified Sound.Tidal.Context as C
import Sound.Tidal.Context (Stream)
import Control.Monad.Reader
import Control.Monad.Catch

newtype Op r = Op ( ReaderT Stream IO r )
  deriving (forall a b. a -> Op b -> Op a
forall a b. (a -> b) -> Op a -> Op b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Op b -> Op a
$c<$ :: forall a b. a -> Op b -> Op a
fmap :: forall a b. (a -> b) -> Op a -> Op b
$cfmap :: forall a b. (a -> b) -> Op a -> Op b
Functor, Functor Op
forall a. a -> Op a
forall a b. Op a -> Op b -> Op a
forall a b. Op a -> Op b -> Op b
forall a b. Op (a -> b) -> Op a -> Op b
forall a b c. (a -> b -> c) -> Op a -> Op b -> Op c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. Op a -> Op b -> Op a
$c<* :: forall a b. Op a -> Op b -> Op a
*> :: forall a b. Op a -> Op b -> Op b
$c*> :: forall a b. Op a -> Op b -> Op b
liftA2 :: forall a b c. (a -> b -> c) -> Op a -> Op b -> Op c
$cliftA2 :: forall a b c. (a -> b -> c) -> Op a -> Op b -> Op c
<*> :: forall a b. Op (a -> b) -> Op a -> Op b
$c<*> :: forall a b. Op (a -> b) -> Op a -> Op b
pure :: forall a. a -> Op a
$cpure :: forall a. a -> Op a
Applicative, Applicative Op
forall a. a -> Op a
forall a b. Op a -> Op b -> Op b
forall a b. Op a -> (a -> Op b) -> Op b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> Op a
$creturn :: forall a. a -> Op a
>> :: forall a b. Op a -> Op b -> Op b
$c>> :: forall a b. Op a -> Op b -> Op b
>>= :: forall a b. Op a -> (a -> Op b) -> Op b
$c>>= :: forall a b. Op a -> (a -> Op b) -> Op b
Monad, MonadThrow Op
forall e a. Exception e => Op a -> (e -> Op a) -> Op a
forall (m :: * -> *).
MonadThrow m
-> (forall e a. Exception e => m a -> (e -> m a) -> m a)
-> MonadCatch m
catch :: forall e a. Exception e => Op a -> (e -> Op a) -> Op a
$ccatch :: forall e a. Exception e => Op a -> (e -> Op a) -> Op a
MonadCatch,Monad Op
forall e a. Exception e => e -> Op a
forall (m :: * -> *).
Monad m -> (forall e a. Exception e => e -> m a) -> MonadThrow m
throwM :: forall e a. Exception e => e -> Op a
$cthrowM :: forall e a. Exception e => e -> Op a
MonadThrow)

exec :: Stream -> Op r -> IO r
exec :: forall r. Stream -> Op r -> IO r
exec Stream
stream (Op ReaderT Stream IO r
m) = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT Stream IO r
m Stream
stream

op1 :: (Stream -> IO r) -> Op r
op1 Stream -> IO r
f         = forall r. ReaderT Stream IO r -> Op r
Op forall a b. (a -> b) -> a -> b
$ do Stream
a <- forall r (m :: * -> *). MonadReader r m => m r
ask; forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Stream -> IO r
f Stream
a
op2 :: (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> t -> IO r
f t
b       = forall r. ReaderT Stream IO r -> Op r
Op forall a b. (a -> b) -> a -> b
$ do Stream
a <- forall r (m :: * -> *). MonadReader r m => m r
ask; forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Stream -> t -> IO r
f Stream
a t
b 
op3 :: (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> t -> t -> IO r
f t
b t
c     = forall r. ReaderT Stream IO r -> Op r
Op forall a b. (a -> b) -> a -> b
$ do Stream
a <- forall r (m :: * -> *). MonadReader r m => m r
ask; forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Stream -> t -> t -> IO r
f Stream
a t
b t
c
op4 :: (Stream -> t -> t -> t -> IO r) -> t -> t -> t -> Op r
op4 Stream -> t -> t -> t -> IO r
f t
b t
c t
d   = forall r. ReaderT Stream IO r -> Op r
Op forall a b. (a -> b) -> a -> b
$ do Stream
a <- forall r (m :: * -> *). MonadReader r m => m r
ask; forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Stream -> t -> t -> t -> IO r
f Stream
a t
b t
c t
d
op5 :: (Stream -> t -> t -> t -> t -> IO r) -> t -> t -> t -> t -> Op r
op5 Stream -> t -> t -> t -> t -> IO r
f t
b t
c t
d t
e = forall r. ReaderT Stream IO r -> Op r
Op forall a b. (a -> b) -> a -> b
$ do Stream
a <- forall r (m :: * -> *). MonadReader r m => m r
ask; forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ Stream -> t -> t -> t -> t -> IO r
f Stream
a t
b t
c t
d t
e

streamReplace :: ID -> ControlPattern -> Op ()
streamReplace = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> ID -> ControlPattern -> IO ()
C.streamReplace
streamHush :: Op ()
streamHush = forall {r}. (Stream -> IO r) -> Op r
op1 Stream -> IO ()
C.streamHush
streamList :: Op ()
streamList = forall {r}. (Stream -> IO r) -> Op r
op1 Stream -> IO ()
C.streamList
streamMute :: ID -> Op ()
streamMute = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ID -> IO ()
C.streamMute
streamUnmute :: ID -> Op ()
streamUnmute = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ID -> IO ()
C.streamUnmute
streamSolo :: ID -> Op ()
streamSolo = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ID -> IO ()
C.streamSolo
streamUnsolo :: ID -> Op ()
streamUnsolo = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ID -> IO ()
C.streamUnsolo
streamOnce :: ControlPattern -> Op ()
streamOnce = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ControlPattern -> IO ()
C.streamOnce
streamFirst :: ControlPattern -> Op ()
streamFirst = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> ControlPattern -> IO ()
C.streamFirst
streamNudgeAll :: Double -> Op ()
streamNudgeAll = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> Double -> IO ()
C.streamNudgeAll
streamAll :: (ControlPattern -> ControlPattern) -> Op ()
streamAll = forall {t} {r}. (Stream -> t -> IO r) -> t -> Op r
op2 Stream -> (ControlPattern -> ControlPattern) -> IO ()
C.streamAll
streamResetCycles :: Op ()
streamResetCycles = forall {r}. (Stream -> IO r) -> Op r
op1 Stream -> IO ()
C.streamResetCycles
transition :: Bool
-> (Time -> [ControlPattern] -> ControlPattern)
-> ID
-> ControlPattern
-> Op ()
transition = forall {t} {t} {t} {t} {r}.
(Stream -> t -> t -> t -> t -> IO r) -> t -> t -> t -> t -> Op r
op5 Stream
-> Bool
-> (Time -> [ControlPattern] -> ControlPattern)
-> ID
-> ControlPattern
-> IO ()
C.transition
streamSetI :: String -> Pattern Int -> Op ()
streamSetI = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> String -> Pattern Int -> IO ()
C.streamSetI
streamSetF :: String -> Pattern Double -> Op ()
streamSetF = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> String -> Pattern Double -> IO ()
C.streamSetF
streamSetS :: String -> Pattern String -> Op ()
streamSetS = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> String -> Pattern String -> IO ()
C.streamSetS
streamSetR :: String -> Pattern Time -> Op ()
streamSetR = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> String -> Pattern Time -> IO ()
C.streamSetR
streamSetB :: String -> Pattern Bool -> Op ()
streamSetB = forall {t} {t} {r}. (Stream -> t -> t -> IO r) -> t -> t -> Op r
op3 Stream -> String -> Pattern Bool -> IO ()
C.streamSetB