-- |

module Hum.Modes.ExMode where

import           Brick.Widgets.Edit      hiding ( decodeUtf8 )
import           Brick.Types
import           Brick.Main
import           Hum.Types
import           Hum.Views
import           Hum.Utils
import           Hum.Rebuild
import           Graphics.Vty.Input.Events
import qualified Data.Text.Zipper              as Z
                                         hiding ( textZipper )
import           Control.Lens hiding (uncons)
import qualified Network.MPD                   as MPD

exEnd :: HState -> EventM Name (Next HState)
exEnd :: HState -> EventM Name (Next HState)
exEnd HState
s =
    let searched :: Text
searched = (HState
s HState
-> Getting (TextZipper Text) HState (TextZipper Text)
-> TextZipper Text
forall s a. s -> Getting a s a -> a
^. (ExState -> Const (TextZipper Text) ExState)
-> HState -> Const (TextZipper Text) HState
Lens' HState ExState
exL ((ExState -> Const (TextZipper Text) ExState)
 -> HState -> Const (TextZipper Text) HState)
-> ((TextZipper Text -> Const (TextZipper Text) (TextZipper Text))
    -> ExState -> Const (TextZipper Text) ExState)
-> Getting (TextZipper Text) HState (TextZipper Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Editor Text Name -> Const (TextZipper Text) (Editor Text Name))
-> ExState -> Const (TextZipper Text) ExState
Lens' ExState (Editor Text Name)
exEditorL ((Editor Text Name -> Const (TextZipper Text) (Editor Text Name))
 -> ExState -> Const (TextZipper Text) ExState)
-> ((TextZipper Text -> Const (TextZipper Text) (TextZipper Text))
    -> Editor Text Name -> Const (TextZipper Text) (Editor Text Name))
-> (TextZipper Text -> Const (TextZipper Text) (TextZipper Text))
-> ExState
-> Const (TextZipper Text) ExState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TextZipper Text -> Const (TextZipper Text) (TextZipper Text))
-> Editor Text Name -> Const (TextZipper Text) (Editor Text Name)
forall t1 n t2.
Lens (Editor t1 n) (Editor t2 n) (TextZipper t1) (TextZipper t2)
editContentsL TextZipper Text -> (TextZipper Text -> Text) -> Text
forall a b. a -> (a -> b) -> b
& TextZipper Text -> Text
forall a. Monoid a => TextZipper a -> a
Z.currentLine)
        s' :: HState
s'= HState
s HState -> (HState -> HState) -> HState
forall a b. a -> (a -> b) -> b
& (ExState -> Identity ExState) -> HState -> Identity HState
Lens' HState ExState
exL ((ExState -> Identity ExState) -> HState -> Identity HState)
-> ((Editor Text Name -> Identity (Editor Text Name))
    -> ExState -> Identity ExState)
-> (Editor Text Name -> Identity (Editor Text Name))
-> HState
-> Identity HState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Editor Text Name -> Identity (Editor Text Name))
-> ExState -> Identity ExState
Lens' ExState (Editor Text Name)
exEditorL ((Editor Text Name -> Identity (Editor Text Name))
 -> HState -> Identity HState)
-> Editor Text Name -> HState -> HState
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Name -> Maybe Int -> Text -> Editor Text Name
forall n. n -> Maybe Int -> Text -> Editor Text n
editorText Name
ExEditor (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1) Text
""
              HState -> (HState -> HState) -> HState
forall a b. a -> (a -> b) -> b
& (Mode -> Identity Mode) -> HState -> Identity HState
Lens' HState Mode
modeL ((Mode -> Identity Mode) -> HState -> Identity HState)
-> Mode -> HState -> HState
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Mode
NormalMode
              HState -> (HState -> HState) -> HState
forall a b. a -> (a -> b) -> b
& (Focus -> Identity Focus) -> HState -> Identity HState
Lens' HState Focus
focusL ((Focus -> Identity Focus) -> HState -> Identity HState)
-> ((Bool -> Identity Bool) -> Focus -> Identity Focus)
-> (Bool -> Identity Bool)
-> HState
-> Identity HState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Identity Bool) -> Focus -> Identity Focus
Lens' Focus Bool
focExL ((Bool -> Identity Bool) -> HState -> Identity HState)
-> Bool -> HState -> HState
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Bool
False
    in
          case HState
s HState -> Getting ExSubMode HState ExSubMode -> ExSubMode
forall s a. s -> Getting a s a -> a
^. (ExState -> Const ExSubMode ExState)
-> HState -> Const ExSubMode HState
Lens' HState ExState
exL ((ExState -> Const ExSubMode ExState)
 -> HState -> Const ExSubMode HState)
-> ((ExSubMode -> Const ExSubMode ExSubMode)
    -> ExState -> Const ExSubMode ExState)
-> Getting ExSubMode HState ExSubMode
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ExSubMode -> Const ExSubMode ExSubMode)
-> ExState -> Const ExSubMode ExState
Lens' ExState ExSubMode
exPrefixL of
            ExSubMode
Cmd -> [Text] -> HState -> EventM Name (Next HState)
exCmdExecute (Text -> [Text]
forall t. IsText t "words" => t -> [t]
words Text
searched) (HState
s' HState -> (HState -> HState) -> HState
forall a b. a -> (a -> b) -> b
& (ExState -> Identity ExState) -> HState -> Identity HState
Lens' HState ExState
exL ((ExState -> Identity ExState) -> HState -> Identity HState)
-> (([Text] -> Identity [Text]) -> ExState -> Identity ExState)
-> ([Text] -> Identity [Text])
-> HState
-> Identity HState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> Identity [Text]) -> ExState -> Identity ExState
Lens' ExState [Text]
cmdHistoryL (([Text] -> Identity [Text]) -> HState -> Identity HState)
-> ([Text] -> [Text]) -> HState -> HState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Text
searched Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:) )
            ExSubMode
srch -> case HState -> View
hview HState
s' of
                View
QueueView     -> HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue (HState -> EventM Name (Next HState))
-> EventM Name HState -> EventM Name (Next HState)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Bool -> HState -> EventM Name HState
queueSearch (ExSubMode
srch ExSubMode -> ExSubMode -> Bool
forall a. Eq a => a -> a -> Bool
== ExSubMode
FSearch) HState
s''
                View
LibraryView   -> HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue (HState -> EventM Name (Next HState))
-> EventM Name HState -> EventM Name (Next HState)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Bool -> HState -> EventM Name HState
librarySearch (ExSubMode
srch ExSubMode -> ExSubMode -> Bool
forall a. Eq a => a -> a -> Bool
== ExSubMode
FSearch) HState
s''
                View
PlaylistsView -> HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue (HState -> EventM Name (Next HState))
-> EventM Name HState -> EventM Name (Next HState)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Bool -> HState -> EventM Name HState
playlistsSearch (ExSubMode
srch ExSubMode -> ExSubMode -> Bool
forall a. Eq a => a -> a -> Bool
== ExSubMode
FSearch) HState
s''
                View
HelpView      -> HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue HState
s'
                where s'' :: HState
s''= HState
s' HState -> (HState -> HState) -> HState
forall a b. a -> (a -> b) -> b
& (ExState -> Identity ExState) -> HState -> Identity HState
Lens' HState ExState
exL ((ExState -> Identity ExState) -> HState -> Identity HState)
-> (([Text] -> Identity [Text]) -> ExState -> Identity ExState)
-> ([Text] -> Identity [Text])
-> HState
-> Identity HState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> Identity [Text]) -> ExState -> Identity ExState
Lens' ExState [Text]
searchHistoryL (([Text] -> Identity [Text]) -> HState -> Identity HState)
-> ([Text] -> [Text]) -> HState -> HState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Text
searched Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:)
handleExEvent
    :: HState -> BrickEvent Name HumEvent -> EventM Name (Next HState)
handleExEvent :: HState -> BrickEvent Name HumEvent -> EventM Name (Next HState)
handleExEvent HState
s BrickEvent Name HumEvent
e = case BrickEvent Name HumEvent
e of
    VtyEvent (EvKey Key
KEnter []) -> HState -> EventM Name (Next HState)
exEnd HState
s
    VtyEvent Event
vtye ->
        HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue (HState -> EventM Name (Next HState))
-> EventM Name HState -> EventM Name (Next HState)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< HState
-> Lens' HState (Editor Text Name)
-> (Event -> Editor Text Name -> EventM Name (Editor Text Name))
-> Event
-> EventM Name HState
forall a b e n.
a -> Lens' a b -> (e -> b -> EventM n b) -> e -> EventM n a
handleEventLensed HState
s ((ExState -> f ExState) -> HState -> f HState
Lens' HState ExState
exL ((ExState -> f ExState) -> HState -> f HState)
-> ((Editor Text Name -> f (Editor Text Name))
    -> ExState -> f ExState)
-> (Editor Text Name -> f (Editor Text Name))
-> HState
-> f HState
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Editor Text Name -> f (Editor Text Name)) -> ExState -> f ExState
Lens' ExState (Editor Text Name)
exEditorL) Event -> Editor Text Name -> EventM Name (Editor Text Name)
forall t n.
(DecodeUtf8 t, Eq t, Monoid t) =>
Event -> Editor t n -> EventM n (Editor t n)
handleEditorEvent Event
vtye
    BrickEvent Name HumEvent
_ -> HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue HState
s

exPrefixTxt :: ExSubMode -> Text
exPrefixTxt :: ExSubMode -> Text
exPrefixTxt ExSubMode
Cmd = Text
":"
exPrefixTxt ExSubMode
FSearch= Text
"/"
exPrefixTxt ExSubMode
BSearch = Text
"?"

exCmdExecute :: [Text] -> HState -> EventM Name (Next HState)
exCmdExecute :: [Text] -> HState -> EventM Name (Next HState)
exCmdExecute (Text
"help":[Text]
_) HState
s = HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue HState
s { hview :: View
hview = View
HelpView }
exCmdExecute (Text
"q":[Text]
_) HState
s = HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
halt HState
s
exCmdExecute (Text
"save":[Text]
name) HState
s = do
  let songs :: SongList
songs = HState -> SongList
queue HState
s
  let name' :: Text
name' = Text -> ((Text, [Text]) -> Text) -> Maybe (Text, [Text]) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"unnamed" (Text, [Text]) -> Text
forall a b. (a, b) -> a
fst ([Text] -> Maybe (Text, [Text])
forall a. [a] -> Maybe (a, [a])
uncons [Text]
name)
  Response ()
_ <- IO (Response ()) -> EventM Name (Response ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Response ()) -> EventM Name (Response ()))
-> IO (Response ()) -> EventM Name (Response ())
forall a b. (a -> b) -> a -> b
$ MPD () -> IO (Response ())
forall a. MPD a -> IO (Response a)
MPD.withMPD (MPD () -> IO (Response ())) -> MPD () -> IO (Response ())
forall a b. (a -> b) -> a -> b
$ SongList -> Text -> MPD ()
forall (m :: * -> *). MonadMPD m => SongList -> Text -> m ()
saveListToPl SongList
songs Text
name'
  HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue (HState -> EventM Name (Next HState))
-> EventM Name HState -> EventM Name (Next HState)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< HState -> EventM Name HState
forall (m :: * -> *). MonadIO m => HState -> m HState
rebuildPl HState
s
exCmdExecute [Text]
_ HState
s = HState -> EventM Name (Next HState)
forall s n. s -> EventM n (Next s)
continue HState
s