-- Copyright 2018 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

-- | Functions to deal with text score, as stored in 'UiConfig.config_tscore'.
module Cmd.Repl.LTScore where
import qualified App.ReplProtocol as ReplProtocol
import qualified Cmd.Cmd as Cmd
import qualified Cmd.Create as Create
import qualified Cmd.Repl.LState as LState

import qualified Derive.TScore.TScore as TScore
import qualified Ui.Ui as Ui
import qualified Ui.UiConfig as UiConfig

import           Global


-- | Edit both ky and tscore together.
both :: Ui.M m => m ReplProtocol.Result
both :: forall (m :: * -> *). M m => m Result
both = do
    Result
tscore <- forall (m :: * -> *). M m => m Result
edit
    Result
ky <- forall (m :: * -> *). M m => m Result
LState.ky
    case (Result
ky, Result
tscore) of
        (ReplProtocol.Edit NonEmpty Editor
ky, ReplProtocol.Edit NonEmpty Editor
tscore) ->
            forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ NonEmpty Editor -> Result
ReplProtocol.Edit (NonEmpty Editor
tscore forall a. Semigroup a => a -> a -> a
<> NonEmpty Editor
ky)
        (Result, Result)
_ -> forall (m :: * -> *) a. (Stack, M m) => Text -> m a
Ui.throw Text
"expected ReplProtocol.Edit"

edit :: Ui.M m => m ReplProtocol.Result
edit :: forall (m :: * -> *). M m => m Result
edit = do
    Text
tscore <- forall (m :: * -> *). M m => m Text
get
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ NonEmpty Editor -> Result
ReplProtocol.Edit forall a b. (a -> b) -> a -> b
$ (forall a. a -> [a] -> NonEmpty a
:| []) forall a b. (a -> b) -> a -> b
$ ReplProtocol.Editor
        { _file :: File
_file = FileType -> Text -> File
ReplProtocol.Text FileType
ReplProtocol.TScore Text
tscore
        , _line_number :: Int
_line_number = Int
0
        , _on_save :: Maybe Text
_on_save = Maybe Text
on_set
        , _on_send :: Maybe Text
_on_send = Maybe Text
on_set
        }
    where
    on_set :: Maybe Text
on_set = forall a. a -> Maybe a
Just Text
"LTScore.set %s"

get :: Ui.M m => m Text
get :: forall (m :: * -> *). M m => m Text
get = Lens State Config
Ui.configforall a b c. Lens a b -> Lens b c -> Lens a c
#Config :-> Text
UiConfig.tscore forall (f :: * -> *) a b. Functor f => Lens a b -> f a -> f b
<#> forall (m :: * -> *). M m => m State
Ui.get

set :: Cmd.M m => Text -> m ()
set :: forall (m :: * -> *). M m => Text -> m ()
set Text
tscore = do
    forall (m :: * -> *). M m => (Config -> Config) -> m ()
Ui.modify_config forall a b. (a -> b) -> a -> b
$ Config :-> Text
UiConfig.tscore forall f a. Lens f a -> a -> f -> f
#= Text
tscore
    forall (m :: * -> *). M m => m ()
integrate

integrate :: Cmd.M m => m ()
integrate :: forall (m :: * -> *). M m => m ()
integrate = do
    [BlockId]
new_blocks <- forall (m :: * -> *). M m => Text -> m [BlockId]
TScore.cmd_integrate forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *). M m => m Text
get
    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall (m :: * -> *). M m => BlockId -> m ViewId
Create.view [BlockId]
new_blocks