module FortyTwo.Utils where
import System.Console.ANSI (cursorUpLine, clearFromCursorToScreenEnd)
import System.IO (hSetBuffering, hFlush, hSetEcho, hReady, stdin, stdout, BufferMode(..))
import Data.List (findIndex, findIndices, elemIndex, intercalate)
import Control.Monad (when)
import Control.Applicative ((<$>))
import Data.Maybe (fromJust)
import FortyTwo.Types(Option(..), Options)
import FortyTwo.Constants (emptyString)
noBuffering :: IO()
noBuffering = do
hSetBuffering stdin NoBuffering
hSetBuffering stdout NoBuffering
restoreBuffering :: IO()
restoreBuffering = do
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering
noEcho :: IO ()
noEcho = hSetEcho stdin False
restoreEcho :: IO ()
restoreEcho = hSetEcho stdin True
clearLines :: Int -> IO()
clearLines lines' = do
cursorUpLine lines'
clearFromCursorToScreenEnd
map' :: (Int -> a -> b) -> [a] -> [b]
map' f = zipWith f [0..]
filter' :: Eq a => (Int -> a -> Bool) -> [a] -> [a]
filter' f xs = [x | x <- xs, f (fromJust (elemIndex x xs)) x]
getKey :: IO String
getKey = reverse <$> getKey' emptyString
where
getKey' chars = do
char <- getChar
more <- hReady stdin
(if more then getKey' else return) (char:chars)
flush :: IO()
flush = hFlush stdout
getOptionsMeta :: Options -> (Int, Int, Maybe Int)
getOptionsMeta options = (0, length options 1, getFocusedOptionIndex options)
stringsToOptions :: [String] -> Options
stringsToOptions options = [
Option { value = o, isFocused = False, isSelected = False } | o <- options
]
focusOption :: Int -> Options -> Options
focusOption focusedIndex = map' $ \ i o ->
Option {
value = getOptionValue o,
isSelected = getOptionIsSelected o,
isFocused = focusedIndex == i
}
toggleFocusedOption :: Int -> Options -> Options
toggleFocusedOption focusedIndex = map' $ \ i o ->
Option {
value = getOptionValue o,
isFocused = focusedIndex == i,
isSelected = if focusedIndex == i then
not $ getOptionIsSelected o
else getOptionIsSelected o
}
toCommaSeparatedString :: [String] -> String
toCommaSeparatedString = intercalate ", "
getOptionValue :: Option -> String
getOptionValue Option { value } = value
getOptionIsFocused :: Option -> Bool
getOptionIsFocused Option { isFocused } = isFocused
getOptionIsSelected :: Option -> Bool
getOptionIsSelected Option { isSelected } = isSelected
getFocusedOptionIndex :: Options -> Maybe Int
getFocusedOptionIndex = findIndex getOptionIsFocused
getSelecteOptionsIndexes :: Options -> [Int]
getSelecteOptionsIndexes = findIndices getOptionIsSelected