module UI.Settings (State, drawUI, handleEvent, theMap) where

import UI.Attributes
import Brick
import Brick.Focus
import Brick.Forms
import Brick.Widgets.Border
import Brick.Widgets.Border.Style
import Brick.Widgets.Center
import Control.Monad (unless)
import Control.Monad.IO.Class
import Lens.Micro.Platform
import States
import StateManagement
import Settings
import qualified Brick.Types as T
import qualified Graphics.Vty as V
import UI.BrickHelpers (scrollableViewportPercent, handleClickScroll)

drawUI :: SS -> [Widget Name]
drawUI :: SS -> [Widget Name]
drawUI = (Widget Name -> [Widget Name] -> [Widget Name]
forall a. a -> [a] -> [a]
:[]) (Widget Name -> [Widget Name])
-> (SS -> Widget Name) -> SS -> [Widget Name]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SS -> Widget Name
ui

ui :: SS -> Widget Name
ui :: SS -> Widget Name
ui SS
f =
  Widget Name -> Widget Name
forall n. Widget n -> Widget n
joinBorders (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  Widget Name -> Widget Name
forall n. Widget n -> Widget n
center (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  BorderStyle -> Widget Name -> Widget Name
forall n. BorderStyle -> Widget n -> Widget n
withBorderStyle BorderStyle
unicodeRounded (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  Widget Name -> Widget Name
forall n. Widget n -> Widget n
border (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  Int -> Widget Name -> Widget Name
forall n. Int -> Widget n -> Widget n
hLimitPercent Int
60 (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  Int -> Widget Name -> Widget Name
forall n. Int -> Widget n -> Widget n
hLimit Int
40 (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$
  Widget Name -> Widget Name
forall n. Widget n -> Widget n
hCenter (AttrName -> Widget Name -> Widget Name
forall n. AttrName -> Widget n -> Widget n
withAttr AttrName
titleAttr (String -> Widget Name
forall n. String -> Widget n
str String
"Settings")) Widget Name -> Widget Name -> Widget Name
forall n. Widget n -> Widget n -> Widget n
<=>
  Widget Name
forall n. Widget n
hBorder Widget Name -> Widget Name -> Widget Name
forall n. Widget n -> Widget n -> Widget n
<=> 
  Int -> Name -> Widget Name -> Widget Name
scrollableViewportPercent Int
60 Name
SettingsViewport 
  (Padding -> Widget Name -> Widget Name
forall n. Padding -> Widget n -> Widget n
padLeft (Int -> Padding
Pad Int
1) (Widget Name -> Widget Name) -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$ SS -> Widget Name
forall n s e. Eq n => Form s e n -> Widget n
renderForm SS
f)

scroll :: Int -> EventM Name s ()
scroll = ViewportScroll Name -> forall s. Int -> EventM Name s ()
forall n. ViewportScroll n -> forall s. Int -> EventM n s ()
vScrollBy (Name -> ViewportScroll Name
forall n. n -> ViewportScroll n
viewportScroll Name
SettingsViewport)

handleEvent :: BrickEvent Name Event -> EventM Name GlobalState ()
handleEvent :: BrickEvent Name () -> EventM Name GlobalState ()
handleEvent ev :: BrickEvent Name ()
ev@(VtyEvent Event
e) = do
  SS
form <- Getting SS GlobalState SS -> EventM Name GlobalState SS
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting SS GlobalState SS
Lens' GlobalState SS
ss
  let halt' :: EventM Name GlobalState ()
halt' = EventM Name GlobalState ()
forall (m :: * -> *). MonadState GlobalState m => m ()
popState EventM Name GlobalState ()
-> EventM Name GlobalState () -> EventM Name GlobalState ()
forall a b.
EventM Name GlobalState a
-> EventM Name GlobalState b -> EventM Name GlobalState a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* IO () -> EventM Name GlobalState ()
forall a. IO a -> EventM Name GlobalState a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Settings -> IO ()
setSettings (SS -> Settings
forall s e n. Form s e n -> s
formState SS
form))
      focus :: FocusRing Name
focus = SS -> FocusRing Name
forall s e n. Form s e n -> FocusRing n
formFocus SS
form
      (Just Name
n) = FocusRing Name -> Maybe Name
forall n. FocusRing n -> Maybe n
focusGetCurrent FocusRing Name
focus
      down :: EventM Name GlobalState ()
down = if Name
n Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
/= Name
MaxRecentsField then
               (SS -> Identity SS) -> GlobalState -> Identity GlobalState
Lens' GlobalState SS
ss ((SS -> Identity SS) -> GlobalState -> Identity GlobalState)
-> SS -> EventM Name GlobalState ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= SS
form { formFocus = focusNext focus }
             else Int -> EventM Name GlobalState ()
forall s. Int -> EventM Name s ()
scroll Int
1
      up :: EventM Name GlobalState ()
up = Bool -> EventM Name GlobalState () -> EventM Name GlobalState ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Name
n Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
HintsField) (EventM Name GlobalState () -> EventM Name GlobalState ())
-> EventM Name GlobalState () -> EventM Name GlobalState ()
forall a b. (a -> b) -> a -> b
$
             (SS -> Identity SS) -> GlobalState -> Identity GlobalState
Lens' GlobalState SS
ss ((SS -> Identity SS) -> GlobalState -> Identity GlobalState)
-> SS -> EventM Name GlobalState ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= SS
form { formFocus = focusPrev focus }


  case Event
e of
    V.EvKey Key
V.KEsc []         -> EventM Name GlobalState ()
halt'
    V.EvKey (V.KChar Char
'q') []  -> EventM Name GlobalState ()
halt'
    V.EvKey Key
V.KDown []        -> EventM Name GlobalState ()
down
    V.EvKey (V.KChar Char
'j') []  -> EventM Name GlobalState ()
down
    V.EvKey Key
V.KUp []          -> EventM Name GlobalState ()
up
    V.EvKey (V.KChar Char
'k') []  -> EventM Name GlobalState ()
up
    V.EvKey (V.KChar Char
'\t') [] -> () -> EventM Name GlobalState ()
forall a. a -> EventM Name GlobalState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    V.EvKey Key
V.KBackTab []     -> () -> EventM Name GlobalState ()
forall a. a -> EventM Name GlobalState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    Event
_ -> LensLike' (Zoomed (EventM Name SS) ()) GlobalState SS
-> EventM Name SS () -> EventM Name GlobalState ()
forall c.
LensLike' (Zoomed (EventM Name SS) c) GlobalState SS
-> EventM Name SS c -> EventM Name GlobalState c
forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom (SS -> Focusing (StateT (EventState Name) IO) () SS)
-> GlobalState
-> Focusing (StateT (EventState Name) IO) () GlobalState
LensLike' (Zoomed (EventM Name SS) ()) GlobalState SS
Lens' GlobalState SS
ss (EventM Name SS () -> EventM Name GlobalState ())
-> EventM Name SS () -> EventM Name GlobalState ()
forall a b. (a -> b) -> a -> b
$ BrickEvent Name () -> EventM Name SS ()
forall n e s. Eq n => BrickEvent n e -> EventM n (Form s e n) ()
handleFormEvent BrickEvent Name ()
ev

handleEvent (T.MouseDown (SBClick ClickableScrollbarElement
el Name
SettingsViewport) Button
_ [Modifier]
_ Location
_) = (Int -> EventM Name GlobalState ())
-> ClickableScrollbarElement -> EventM Name GlobalState ()
forall n s.
(Int -> EventM n s ())
-> ClickableScrollbarElement -> EventM n s ()
handleClickScroll Int -> EventM Name GlobalState ()
forall s. Int -> EventM Name s ()
scroll ClickableScrollbarElement
el
handleEvent BrickEvent Name ()
_ = () -> EventM Name GlobalState ()
forall a. a -> EventM Name GlobalState a
forall (m :: * -> *) a. Monad m => a -> m a
return ()