packages feed

gotta-go-fast-0.1.3.0: src/Main.hs

{-# LANGUAGE DeriveDataTypeable #-}

module Main where

import Data.Word (Word8)
import Control.Monad (filterM)
import System.Console.CmdArgs
  (Data, Typeable, args, cmdArgs, def, help, program, summary, typ, (&=))
import System.Directory (doesFileExist)
import System.Random (randomRIO)

import UI (run)
import FormatCode (toAscii, trimEmptyLines, wordWrap)

data Config = Config
  { height :: Int
  , width :: Int
  , tab :: Int
  , files :: [FilePath]
  , fg_empty :: Word8
  , fg_error :: Word8
  } deriving (Show, Data, Typeable)

config :: Config
config = Config
  { height = 20 &= typ "LINES" &=
    help "The maximum number of lines to sample (default: 20)"
  , width = 80 &= typ "CHARS" &=
    help "The width at which to wrap lines (default: 80)"
  , tab = 4 &= typ "SIZE" &=
    help "The size of a tab in spaces (default: 4)"
  , fg_empty = 8 &= typ "COLOUR" &=
    help "The ISO colour code for empty (not yet typed) characters (default: 8)"
  , fg_error = 1 &= typ "COLOUR" &=
    help "The ISO colour code for errors (default: 1)"
  , files = def &= args &= typ "FILES"
  }
  &= summary "Gotta Go Fast 0.1.3.0"
  &= help "Practice typing and measure your WPM and accuracy"
  &= program "gotta-go-fast"

sample :: Config -> String -> IO String
sample c file = do
  r <- randomRIO (0, max 0 $ length (lines ascii) - height c)
  return $ trimEmptyLines $ chop $ wrap $ chop $ unlines $ drop r $ lines ascii
    where
      ascii = toAscii (tab c) file
      chop = unlines . take (height c) . lines
      wrap = wordWrap (width c)

main :: IO ()
main = do
  c <- cmdArgs config
  fs <- filterM doesFileExist $ files c
  case fs of
    [] -> putStrLn "Requires at least one file path"
    _ -> do
      r <- randomRIO (0, length fs - 1)
      file <- readFile $ fs !! r
      sampled <- sample c file
      run (fg_empty c) (fg_error c) sampled