clanki-1.2.7: src/Main.hs
module Main where
import Add
import Input
import Remove
import Quiz
import Card
import Tracker
import Text.Printf(printf)
import Display
import System.Environment(getArgs)
import System.Directory(doesFileExist)
import Data.Maybe(isJust)
import Safe(readMay)
import Control.Monad(filterM)
import qualified System.IO.Strict as SIO
data Action = Quiz | Add | Remove | Show | Quit deriving (Show, Eq, Ord, Enum)
instance Display Action where
display = show
allActions :: [Action]
allActions = [Quiz ..]
getAction :: IO (Maybe Action)
getAction = Input.getUserChoice allActions
runAction :: Maybe Action -> [Card] -> IO ()
runAction (Just Quit) cards = do
saveData cards
return ()
runAction (Just Add) cards = addLoop cards >>= mainLoop
runAction (Just Quiz) cards = quizLoop cards >>= mainLoop
runAction (Just Remove) cards = removeLoop cards >>= mainLoop
runAction (Just Show) cards = do
displayAllDecks cards
mainLoop cards
runAction Nothing cards = do
printf $ "Invalid input" ++ "\n"
mainLoop cards
fileName :: String
fileName = "data.clanki"
mainLoop :: [Card] -> IO ()
mainLoop decks = do
action <- getAction
runAction action decks
loadData :: IO [Card]
loadData = do
fileExists <- doesFileExist fileName
if fileExists
then do
x <- SIO.readFile fileName
return $ read x
else return []
saveData :: [Card] -> IO ()
saveData decks = writeFile fileName (show decks)
startWithArgs :: [String] -> [Card] -> IO [Card]
startWithArgs args cards
| null args = return cards
| "--help" `elem` args || "-h" `elem` args =
do
displayHelp
return cards
| "--list" `elem` args || "-l" `elem` args =
do
displayAllDecks cards
return cards
{- | "--stats" `elem` args || "-s" `elem` args = -}
{-do-}
{-displayList decks-}
{-return decks-}
| firstOptionIsNum = do
let numOfCardsToQuiz = read (head args) :: Int
quizSomeCards (take numOfCardsToQuiz cards) cards
| firstOptionIsDeck =
if secondOptionIsNum
then do
let numOfCardsToQuiz = read $ args !! 1
let deckCards = cardsInDeck (head args) cards
cardsToQuiz <- filterM shouldQuizCard (take numOfCardsToQuiz deckCards)
quizSomeCards cardsToQuiz cards
else do
cardsToQuiz <- filterM shouldQuizCard (cardsInDeck (head args) cards)
quizSomeCards cardsToQuiz cards
| head args == "-add" = do
let deckName = args !! 1
let question = args !! 2
let answer = args !! 3
if length args >= 5 && args !! 4 == "-2"
then return $ cards ++ [newCard question answer deckName] ++ [newCard answer question deckName]
else return $ cards ++ [newCard question answer deckName]
| otherwise = return cards
where
isDeckName str = hasDeckNamed str cards
firstOptionIsNum = isJust (readMay (head args) :: Maybe Int)
firstOptionIsDeck = isDeckName (head args)
secondOptionIsNum = length args > 1 && isJust (readMay (args !! 1) :: Maybe Int)
displayHelp :: IO ()
displayHelp = do
printf $ "OPTIONS:" ++ "\n"
printf $ "--list -l List available decks in default directory" ++ "\n"
printf $ "--stats -s Show some stats about the decks" ++ "\n"
printf $ "--help -h Show this help" ++ "\n"
main :: IO ()
main = do
cards <- loadData
args <- getArgs
newCards <- startWithArgs args cards
mainLoop newCards