content: module Card where 
  import Display
  import Text.Printf(printf)
  import Data.List(nub, intercalate)
  import StatTracker
  data CardTracker = CardTracker {ctEF :: Float, ctN :: Int, ctTimeQuizzed :: Int, ctLastResponseQuality :: Maybe Int} deriving (Show, Read, Eq)
  
  data Card = Card {cardQuestion :: String, cardAnswer :: String, cardDeck :: String, cardTracker :: CardTracker, cardStatTracker :: StatTracker} deriving (Show, Read, Eq)
  
  newCard :: String -> String -> String -> Card
  newCard question answer deckName = Card {cardQuestion = question, cardAnswer = answer, cardDeck = deckName, cardTracker = newCardTracker, cardStatTracker = newStatTracker}
  
  newCardTracker :: CardTracker
  newCardTracker = CardTracker {ctEF = 2.5, ctN = 0, ctTimeQuizzed = 0, ctLastResponseQuality = Nothing}
  
  instance Display Card where
      display card = "Q : " ++ cardQuestion card ++ "\n" ++ "A : " ++ cardAnswer card
  
  printCard :: Card -> IO ()
  printCard card = printf $ "Q : " ++ cardQuestion card ++ "\n" ++ "A : " ++ cardAnswer card
  
  allDeckNames :: [Card] -> [String]
  allDeckNames cards = nub . map cardDeck $ cards
  
  cardsInDeck :: String -> [Card] -> [Card]
  cardsInDeck deckName = filter ((== deckName) . cardDeck)
  
  replaceCardsInDeck :: String -> [Card] -> [Card] -> [Card]
  replaceCardsInDeck deckName newCards allCards = do
      let cardsOldDeckRemoved = filter (\card -> cardDeck card /= deckName) allCards
      cardsOldDeckRemoved ++ newCards
  
  displayCardsInDeck :: String -> [Card] -> String
  displayCardsInDeck deckName cards = 
      prependDeckName . appendNewLine . displayListCards $ deckCards
      where
          prependDeckName = (deckName ++) . ("\n" ++)
          appendNewLine = (++ "\n")
          deckCards = filter (\card -> cardDeck card == deckName) cards
  
  displayListCards :: [Card] -> String
  displayListCards cards = intercalate "\n" . map display $ cards
  
  displayAllDecks :: [Card] -> IO ()
  displayAllDecks cards = do
      let deckNames = allDeckNames cards
      let cardsDisplayed = intercalate "\n" $ map (\dName -> displayCardsInDeck dName cards) deckNames
      printf $ cardsDisplayed ++ "\n"
  
  hasDeckNamed :: String -> [Card] -> Bool
  hasDeckNamed deckName cards = not . null $ filter (\card -> cardDeck card == deckName) cards
  