-- Copyright 2023 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | Details in "Solkattu.Bol".
module Solkattu.Dsl.Bol (
    module Solkattu.Dsl.Bol
    , module Solkattu.Talas
    , module Solkattu.Dsl.Generic
    , module Solkattu.Dsl.Interactive
) where
import           Prelude hiding ((.), (^))
import qualified Data.String as String

import qualified Util.CallStack as CallStack
import qualified Solkattu.Bol as Bol
import           Solkattu.Talas (tintal, kehrwa, jhaptal, rupak)
import           Solkattu.Dsl.Interactive (diff, diffw)
import qualified Solkattu.Format.Terminal as Terminal
import qualified Solkattu.Korvai as Korvai
import qualified Solkattu.Realize as Realize
import qualified Solkattu.S as S
import qualified Solkattu.Solkattu as Solkattu
import qualified Solkattu.Talas as Talas

import           Global
import           Solkattu.Dsl.Generic


type Sequence = SequenceT (Realize.Stroke Bol.Bol)

type Section = Korvai.Section Sequence

instance String.IsString Sequence where
    -- Even with InstanceSigs, this doesn't actually work to add a call stack.
    -- fromString :: CallStack.Stack => String -> Sequence
    fromString :: String -> SequenceT (Stroke Bol)
fromString String
s = Stack => Text -> SequenceT (Stroke Bol)
strS (String -> Text
txt String
s)

-- | Parse a string to bols.  Look for syllables inside words.
strS :: CallStack.Stack => Text -> Sequence
strS :: Stack => Text -> SequenceT (Stroke Bol)
strS Text
str = forall b a. Monoid b => (a -> b) -> [a] -> b
mconcatMap (forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Rest a => a
__ Bols -> SequenceT (Stroke Bol)
make) forall a b. (a -> b) -> a -> b
$ forall a. Stack => Either Text a -> a
check forall a b. (a -> b) -> a -> b
$ Text -> Either Text [Maybe Bols]
Bol.parseBols Text
str
    where
    make :: Bols -> SequenceT (Stroke Bol)
make = \case
        Bol.S1 Bol
b1 -> Bol -> SequenceT (Stroke Bol)
_bol Bol
b1
        Bol.S2 Bol
b1 Bol
b2 -> forall g sollu. Sequence g sollu -> Sequence g sollu
su (Bol -> SequenceT (Stroke Bol)
_bol Bol
b1 forall a. Monoid a => a -> a -> a
. Bol -> SequenceT (Stroke Bol)
_bol Bol
b2)

-- * sollus

_bol :: Bol.Bol -> Sequence
_bol :: Bol -> SequenceT (Stroke Bol)
_bol Bol
s = forall g a. Note g a -> Sequence g a
S.singleton forall a b. (a -> b) -> a -> b
$ forall g a. a -> Note g a
S.Note (forall sollu. NoteT sollu -> Note sollu
Solkattu.Note (forall sollu. sollu -> NoteT sollu
Solkattu.note (forall stroke. stroke -> Stroke stroke
Realize.stroke Bol
s)))

dha :: SequenceT (Stroke Bol)
dha = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Dha
dhom :: SequenceT (Stroke Bol)
dhom= Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Dhom
ti :: SequenceT (Stroke Bol)
ti  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ti
ra :: SequenceT (Stroke Bol)
ra  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ra
ki :: SequenceT (Stroke Bol)
ki  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ki
ta :: SequenceT (Stroke Bol)
ta  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ta
ka :: SequenceT (Stroke Bol)
ka  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ka
taa :: SequenceT (Stroke Bol)
taa = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Taa
tu :: SequenceT (Stroke Bol)
tu  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Tu
na :: SequenceT (Stroke Bol)
na  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Na
tet :: SequenceT (Stroke Bol)
tet = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Tet
te :: SequenceT (Stroke Bol)
te  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Te
ga :: SequenceT (Stroke Bol)
ga  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ga
di :: SequenceT (Stroke Bol)
di  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Di
ge :: SequenceT (Stroke Bol)
ge  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ge
ne :: SequenceT (Stroke Bol)
ne  = Bol -> SequenceT (Stroke Bol)
_bol Bol
Bol.Ne

-- * fragments

tr, trkt, kt, kttk :: Sequence
tr :: SequenceT (Stroke Bol)
tr = SequenceT (Stroke Bol)
"tr"
trkt :: SequenceT (Stroke Bol)
trkt = SequenceT (Stroke Bol)
"trkt"
kt :: SequenceT (Stroke Bol)
kt = SequenceT (Stroke Bol)
"tk"
kttk :: SequenceT (Stroke Bol)
kttk = SequenceT (Stroke Bol)
"kttk"

tetekata :: Sequence
tetekata :: SequenceT (Stroke Bol)
tetekata = forall sollu.
GroupType -> Text -> SequenceT sollu -> SequenceT sollu
namedT GroupType
Solkattu.GPattern Text
"8n" forall a b. (a -> b) -> a -> b
$
    Tag
Solkattu.Standard forall sollu. Tag -> SequenceT sollu -> SequenceT sollu
^ SequenceT (Stroke Bol)
"tette kata gadi gene"

-- * realize

realize :: Korvai -> IO ()
realize :: Korvai -> IO ()
realize = Config -> Korvai -> IO ()
Terminal.printBol (Config -> Config
concrete Config
Terminal.bolConfig)

realize_ :: Int -> Korvai -> IO ()
realize_ :: Int -> Korvai -> IO ()
realize_ Int
width = Config -> Korvai -> IO ()
Terminal.printBol
    (Config -> Config
concrete forall a b. (a -> b) -> a -> b
$ Config
Terminal.bolConfig { _terminalWidth :: Int
Terminal._terminalWidth = Int
width })

{-
realizet :: Korvai.Korvai -> IO ()
realizet = _printInstrument Just Korvai.ITabla concrete

_printInstrument
    :: (Solkattu.Notation stroke1, Solkattu.Notation stroke2, Ord stroke1)
    => (Realize.Stroke stroke1 -> Maybe (Realize.Stroke stroke2))
    -> Korvai.Instrument stroke1
    -> (Terminal.Config -> Terminal.Config)
    -> Korvai -> IO ()
_printInstrument postproc inst setConfig =
    Interactive.printInstrument True True inst (_defaultStrokes inst)
        (setConfig Terminal.defaultConfig) postproc
-}

-- * korvai

korvai :: Talas.Tal -> [Section] -> Korvai
korvai :: Tal -> [Section] -> Korvai
korvai = Tal -> [Section] -> Korvai
Korvai.tablaKorvai

korvai1 :: Talas.Tal -> Section -> Korvai
korvai1 :: Tal -> Section -> Korvai
korvai1 Tal
tala Section
section = Tal -> [Section] -> Korvai
korvai Tal
tala [Section
section]

korvaiS :: Talas.Tal -> [Sequence] -> Korvai
korvaiS :: Tal -> [SequenceT (Stroke Bol)] -> Korvai
korvaiS Tal
tala = Tal -> [Section] -> Korvai
korvai Tal
tala forall b c a. (b -> c) -> (a -> b) -> a -> c
 forall sollu. [SequenceT sollu] -> [Section (SequenceT sollu)]
Korvai.inferSections

korvaiS1 :: Talas.Tal -> Sequence -> Korvai
korvaiS1 :: Tal -> SequenceT (Stroke Bol) -> Korvai
korvaiS1 Tal
tala SequenceT (Stroke Bol)
seq = Tal -> [SequenceT (Stroke Bol)] -> Korvai
korvaiS Tal
tala [SequenceT (Stroke Bol)
seq]

-- * metadata

akash :: Korvai -> Korvai
akash :: Korvai -> Korvai
akash = Text -> Korvai -> Korvai
source Text
"akash"

qaida :: Korvai -> Korvai
qaida :: Korvai -> Korvai
qaida = Text -> Korvai -> Korvai
withType Text
"qaida"

tukra :: Korvai -> Korvai
tukra :: Korvai -> Korvai
tukra = Text -> Korvai -> Korvai
withType Text
"tukra"