{-# Language OverloadedStrings #-}
{-|
Module      : Client.View.KeyMap
Description : List of the current key map
Copyright   : (c) Eric Mertens, 2017
License     : ISC
Maintainer  : emertens@gmail.com

This module provides a view of the key bindings map

-}
module Client.View.KeyMap (keyMapLines) where

import           Client.Configuration
import           Client.EventLoop.Actions
import           Client.Image.PackedImage
import           Client.State
import           Control.Lens
import           Data.List
import           Data.Ord
import           Graphics.Vty.Attributes
import           Graphics.Vty.Input

-- | Show the client keybindings
keyMapLines ::
  ClientState {- ^ client state -} ->
  [Image']    {- ^ output lines -}
keyMapLines :: ClientState -> [Image']
keyMapLines ClientState
st
  = ClientState -> (Image' -> Text) -> [Image'] -> [Image']
forall a. ClientState -> (a -> Text) -> [a] -> [a]
clientFilter ClientState
st Image' -> Text
imageText
  ([Image'] -> [Image']) -> [Image'] -> [Image']
forall a b. (a -> b) -> a -> b
$ [([Modifier], Key, Action)] -> [Image']
renderEntries
  ([([Modifier], Key, Action)] -> [Image'])
-> [([Modifier], Key, Action)] -> [Image']
forall a b. (a -> b) -> a -> b
$ KeyMap -> [([Modifier], Key, Action)]
keyMapEntries
  (KeyMap -> [([Modifier], Key, Action)])
-> KeyMap -> [([Modifier], Key, Action)]
forall a b. (a -> b) -> a -> b
$ Getting KeyMap ClientState KeyMap -> ClientState -> KeyMap
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view ((Configuration -> Const KeyMap Configuration)
-> ClientState -> Const KeyMap ClientState
Lens' ClientState Configuration
clientConfig ((Configuration -> Const KeyMap Configuration)
 -> ClientState -> Const KeyMap ClientState)
-> ((KeyMap -> Const KeyMap KeyMap)
    -> Configuration -> Const KeyMap Configuration)
-> Getting KeyMap ClientState KeyMap
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (KeyMap -> Const KeyMap KeyMap)
-> Configuration -> Const KeyMap Configuration
Lens' Configuration KeyMap
configKeyMap) ClientState
st

renderEntries :: [([Modifier], Key, Action)] -> [Image']
renderEntries :: [([Modifier], Key, Action)] -> [Image']
renderEntries [([Modifier], Key, Action)]
entries =
  [ Int -> Image' -> Image'
resizeImage Int
keyColWidth Image'
key Image' -> Image' -> Image'
forall a. Semigroup a => a -> a -> a
<> Image'
act | (Image'
key,Image'
act) <- [(Image', Image')]
images ]

  where
    third :: (a, b, c) -> c
third (a
_,b
_,c
x) = c
x

    images :: [(Image', Image')]
images =
      [ ( Attr -> String -> Image'
string Attr
defAttr ([Modifier] -> Key -> String
prettyModifierKey [Modifier]
mods Key
key)
        , Attr -> Text -> Image'
text'  Attr
defAttr (Action -> Text
actionName Action
act            )
        )
      | ([Modifier]
mods,Key
key,Action
act) <- (([Modifier], Key, Action)
 -> ([Modifier], Key, Action) -> Ordering)
-> [([Modifier], Key, Action)] -> [([Modifier], Key, Action)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((([Modifier], Key, Action) -> Action)
-> ([Modifier], Key, Action)
-> ([Modifier], Key, Action)
-> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ([Modifier], Key, Action) -> Action
forall a b c. (a, b, c) -> c
third) [([Modifier], Key, Action)]
entries
      ]

    keyColWidth :: Int
keyColWidth = Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (Int
0 Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
: ((Image', Image') -> Int) -> [(Image', Image')] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Image' -> Int
imageWidth (Image' -> Int)
-> ((Image', Image') -> Image') -> (Image', Image') -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Image', Image') -> Image'
forall a b. (a, b) -> a
fst) [(Image', Image')]
images)