module Sound.Tidal.Config where

import Control.Monad (when)
import Data.Int (Int64)
import Foreign.C (CDouble)
import qualified Sound.Tidal.Clock as Clock

{-
    Config.hs - For default Tidal configuration values.
    Copyright (C) 2020, Alex McLean and contributors

    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/>.
-}

data Config = Config
  { Config -> Bool
cCtrlListen :: Bool,
    Config -> String
cCtrlAddr :: String,
    Config -> Int
cCtrlPort :: Int,
    Config -> Bool
cCtrlBroadcast :: Bool,
    Config -> Bool
cVerbose :: Bool,
    Config -> CDouble
cQuantum :: CDouble,
    Config -> CDouble
cBeatsPerCycle :: CDouble,
    Config -> Double
cFrameTimespan :: Double,
    Config -> Bool
cEnableLink :: Bool,
    Config -> Int64
cSkipTicks :: Int64,
    Config -> Double
cProcessAhead :: Double
  }

defaultConfig :: Config
defaultConfig :: Config
defaultConfig =
  Config
    { cCtrlListen :: Bool
cCtrlListen = Bool
True,
      cCtrlAddr :: String
cCtrlAddr = String
"127.0.0.1",
      cCtrlPort :: Int
cCtrlPort = Int
6010,
      cCtrlBroadcast :: Bool
cCtrlBroadcast = Bool
False,
      cVerbose :: Bool
cVerbose = Bool
True,
      cFrameTimespan :: Double
cFrameTimespan = ClockConfig -> Double
Clock.clockFrameTimespan ClockConfig
Clock.defaultConfig,
      cEnableLink :: Bool
cEnableLink = ClockConfig -> Bool
Clock.clockEnableLink ClockConfig
Clock.defaultConfig,
      cProcessAhead :: Double
cProcessAhead = ClockConfig -> Double
Clock.clockProcessAhead ClockConfig
Clock.defaultConfig,
      cSkipTicks :: Int64
cSkipTicks = ClockConfig -> Int64
Clock.clockSkipTicks ClockConfig
Clock.defaultConfig,
      cQuantum :: CDouble
cQuantum = ClockConfig -> CDouble
Clock.clockQuantum ClockConfig
Clock.defaultConfig,
      cBeatsPerCycle :: CDouble
cBeatsPerCycle = ClockConfig -> CDouble
Clock.clockBeatsPerCycle ClockConfig
Clock.defaultConfig
    }

toClockConfig :: Config -> Clock.ClockConfig
toClockConfig :: Config -> ClockConfig
toClockConfig Config
conf =
  Clock.ClockConfig
    { clockFrameTimespan :: Double
Clock.clockFrameTimespan = Config -> Double
cFrameTimespan Config
conf,
      clockEnableLink :: Bool
Clock.clockEnableLink = Config -> Bool
cEnableLink Config
conf,
      clockProcessAhead :: Double
Clock.clockProcessAhead = Config -> Double
cProcessAhead Config
conf,
      clockSkipTicks :: Int64
Clock.clockSkipTicks = Config -> Int64
cSkipTicks Config
conf,
      clockQuantum :: CDouble
Clock.clockQuantum = Config -> CDouble
cQuantum Config
conf,
      clockBeatsPerCycle :: CDouble
Clock.clockBeatsPerCycle = Config -> CDouble
cBeatsPerCycle Config
conf
    }

verbose :: Config -> String -> IO ()
verbose :: Config -> String -> IO ()
verbose Config
c String
s = Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Config -> Bool
cVerbose Config
c) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn String
s

setFrameTimespan :: Double -> Config -> Config
setFrameTimespan :: Double -> Config -> Config
setFrameTimespan Double
n Config
c =
  Config
c {cFrameTimespan = n}

setProcessAhead :: Double -> Config -> Config
setProcessAhead :: Double -> Config -> Config
setProcessAhead Double
n Config
c =
  Config
c
    { cProcessAhead = n
    }