-- | This module provides mappings for keyboard characters and modification keys to VTY event values

module Graphics.Vty.Platform.Windows.Input.Terminfo
  ( classifyMapForTerm
  , universalTable
  , commonVisibleChars
  , specialSupportKeys
  )
where

import Data.Maybe (mapMaybe)
import Graphics.Vty.Input.Events
import qualified Graphics.Vty.Platform.Windows.Input.Terminfo.ANSIVT as ANSIVT

-- | Builds input sequences for all VT sequences available on Windows

classifyMapForTerm :: ClassifyMap
classifyMapForTerm :: ClassifyMap
classifyMapForTerm =
    [ClassifyMap] -> ClassifyMap
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([ClassifyMap] -> ClassifyMap) -> [ClassifyMap] -> ClassifyMap
forall a b. (a -> b) -> a -> b
$ ClassifyMap
universalTable
           ClassifyMap -> [ClassifyMap] -> [ClassifyMap]
forall a. a -> [a] -> [a]
: [ClassifyMap]
ANSIVT.classifyTable

-- | Combined tables.

universalTable :: ClassifyMap
universalTable :: ClassifyMap
universalTable = [ClassifyMap] -> ClassifyMap
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ ClassifyMap
commonVisibleChars
    , ClassifyMap
metaChars
    , ClassifyMap
otherVisibleChars
    , ClassifyMap
ctrlChars
    , ClassifyMap
ctrlMetaChars
    , ClassifyMap
specialSupportKeys
    ]

-- | Visible characters in the ISO-8859-1 and UTF-8 common set up to

-- but not including those in the range 0xA1 to 0xC1

commonVisibleChars :: ClassifyMap
commonVisibleChars :: ClassifyMap
commonVisibleChars =
    [ ([Char
x], Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
x) [])
    | Char
x <- [Char
' ' .. Int -> Char
forall a. Enum a => Int -> a
toEnum Int
0x7F]
    ]

metaChars :: ClassifyMap
metaChars :: ClassifyMap
metaChars = (([Char], Event) -> Maybe ([Char], Event))
-> ClassifyMap -> ClassifyMap
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ([Char], Event) -> Maybe ([Char], Event)
forall {b}. ([Char], b) -> Maybe ([Char], Event)
f ClassifyMap
commonVisibleChars
  where
    f :: ([Char], b) -> Maybe ([Char], Event)
f ([Char
c], b
_) = ([Char], Event) -> Maybe ([Char], Event)
forall a. a -> Maybe a
Just (Char
'\ESC'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char
c], Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
c) [Modifier
MMeta])
    f ([Char], b)
_ = Maybe ([Char], Event)
forall a. Maybe a
Nothing

otherVisibleChars :: ClassifyMap
otherVisibleChars :: ClassifyMap
otherVisibleChars =
    [ ([Char
x], Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
x) [])
    | Char
x <- [Int -> Char
forall a. Enum a => Int -> a
toEnum Int
0x8A .. Int -> Char
forall a. Enum a => Int -> a
toEnum Int
0xC1]
    ]

-- | Non-printable characters in the ISO-8859-1 and UTF-8 common set

-- translated to ctrl + char.

--

-- This treats CTRL-i the same as tab.

ctrlChars :: ClassifyMap
ctrlChars :: ClassifyMap
ctrlChars =
    [ ([Int -> Char
forall a. Enum a => Int -> a
toEnum Int
x], Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
y) [Modifier
MCtrl])
    | (Int
x,Char
y) <- [Int] -> [Char] -> [(Int, Char)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0..Int
31] (Char
'@'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char
'a'..Char
'z'][Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++[Char
'['..Char
'_'])
    , Char
y Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'i'  -- Resolve issue #3 where CTRL-i hides TAB.

    , Char
y Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'h'  -- CTRL-h should not hide BS

    ]

-- | Ctrl+Meta+Char

ctrlMetaChars :: ClassifyMap
ctrlMetaChars :: ClassifyMap
ctrlMetaChars = (([Char], Event) -> Maybe ([Char], Event))
-> ClassifyMap -> ClassifyMap
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ([Char], Event) -> Maybe ([Char], Event)
f ClassifyMap
ctrlChars
  where
    f :: ([Char], Event) -> Maybe ([Char], Event)
f ([Char]
s, EvKey Key
c [Modifier]
m) = ([Char], Event) -> Maybe ([Char], Event)
forall a. a -> Maybe a
Just (Char
'\ESC'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
s, Key -> [Modifier] -> Event
EvKey Key
c (Modifier
MMetaModifier -> [Modifier] -> [Modifier]
forall a. a -> [a] -> [a]
:[Modifier]
m))
    f ([Char], Event)
_ = Maybe ([Char], Event)
forall a. Maybe a
Nothing

-- | Escape, backspace, enter, tab.

specialSupportKeys :: ClassifyMap
specialSupportKeys :: ClassifyMap
specialSupportKeys =
    -- special support for ESC

    [ ([Char]
"\ESC",Key -> [Modifier] -> Event
EvKey Key
KEsc []), ([Char]
"\ESC\ESC",Key -> [Modifier] -> Event
EvKey Key
KEsc [Modifier
MMeta])
    -- Special support for backspace

    , ([Char]
"\DEL", Key -> [Modifier] -> Event
EvKey Key
KBS []), ([Char]
"\ESC\DEL", Key -> [Modifier] -> Event
EvKey Key
KBS [Modifier
MMeta]), ([Char]
"\b", Key -> [Modifier] -> Event
EvKey Key
KBS [Modifier
MCtrl])
    -- Special support for Enter

    , ([Char]
"\r",Key -> [Modifier] -> Event
EvKey Key
KEnter []), ([Char]
"\ESC\^J",Key -> [Modifier] -> Event
EvKey Key
KEnter [Modifier
MMeta]), ([Char]
"\n", Key -> [Modifier] -> Event
EvKey Key
KEnter [Modifier
MCtrl])
    -- explicit support for tab

    , ([Char]
"\t", Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
'\t') []), ([Char]
"\ESC[Z", Key -> [Modifier] -> Event
EvKey (Char -> Key
KChar Char
'\t') [Modifier
MShift])
    ]