{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DuplicateRecordFields #-}
module Core where

import System.Random (StdGen)
import Language.Lojban.Core (Dictionary)
import qualified Data.Text as T
import qualified Text.Pandoc as P
import qualified Data.Map as M

-- * Dictionary
type WordGenerator = StdGen -> (T.Text, StdGen)

-- * Courses
data CourseStore = CourseStore
    { CourseStore -> Map Text CourseCollection
courseStoreCollections :: M.Map T.Text CourseCollection
    , CourseStore -> Map Text Course
courseStoreCourses :: M.Map T.Text Course
    }

data CourseCollection = CourseCollection
    { CourseCollection -> Text
courseCollectionId :: T.Text
    , CourseCollection -> [Course]
courseCollectionCourses :: [Course]
    }

data Course = Course
    { Course -> Text
courseId :: T.Text
    , Course -> Text
courseTitle :: T.Text
    , Course -> Text
courseShortDescription :: T.Text
    , Course -> Maybe Pandoc
courseLongDescription :: Maybe P.Pandoc
    , Course -> Maybe Pandoc
courseCredits :: Maybe P.Pandoc
    , Course -> CourseStyle
courseStyle :: CourseStyle
    , Course -> Dictionary
courseDictionary :: Dictionary
    , Course -> [Lesson]
courseLessons :: [Lesson]
    } deriving (Int -> Course -> ShowS
[Course] -> ShowS
Course -> String
(Int -> Course -> ShowS)
-> (Course -> String) -> ([Course] -> ShowS) -> Show Course
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Course -> ShowS
showsPrec :: Int -> Course -> ShowS
$cshow :: Course -> String
show :: Course -> String
$cshowList :: [Course] -> ShowS
showList :: [Course] -> ShowS
Show)

data CourseStyle = CourseStyle
    { CourseStyle -> Maybe String
courseStyleColor1 :: Maybe String
    , CourseStyle -> Maybe String
courseStyleIconUrl :: Maybe String
    } deriving (Int -> CourseStyle -> ShowS
[CourseStyle] -> ShowS
CourseStyle -> String
(Int -> CourseStyle -> ShowS)
-> (CourseStyle -> String)
-> ([CourseStyle] -> ShowS)
-> Show CourseStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CourseStyle -> ShowS
showsPrec :: Int -> CourseStyle -> ShowS
$cshow :: CourseStyle -> String
show :: CourseStyle -> String
$cshowList :: [CourseStyle] -> ShowS
showList :: [CourseStyle] -> ShowS
Show)

data Lesson = Lesson
    { Lesson -> Text
lessonTitle :: T.Text
    , Lesson -> ExerciseGenerator
lessonExercises :: ExerciseGenerator
    , Lesson -> Maybe Pandoc
lessonLecture :: Maybe P.Pandoc
    , Lesson -> Maybe Pandoc
lessonPlan :: Maybe P.Pandoc
    , Lesson -> Maybe Vocabulary
lessonVocabulary :: Maybe Vocabulary
    }

data Vocabulary = Vocabulary
    { Vocabulary -> [Text]
vocabularyBrivlaList :: [T.Text]
    , Vocabulary -> [Text]
vocabularyCmavoList :: [T.Text]
    , Vocabulary -> [Text]
vocabularyCmevlaList :: [T.Text]
    } deriving (Int -> Vocabulary -> ShowS
[Vocabulary] -> ShowS
Vocabulary -> String
(Int -> Vocabulary -> ShowS)
-> (Vocabulary -> String)
-> ([Vocabulary] -> ShowS)
-> Show Vocabulary
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Vocabulary -> ShowS
showsPrec :: Int -> Vocabulary -> ShowS
$cshow :: Vocabulary -> String
show :: Vocabulary -> String
$cshowList :: [Vocabulary] -> ShowS
showList :: [Vocabulary] -> ShowS
Show)

instance Semigroup Vocabulary where
    <> :: Vocabulary -> Vocabulary -> Vocabulary
(<>) Vocabulary
vocabulary1 Vocabulary
vocabulary2 = [Text] -> [Text] -> [Text] -> Vocabulary
Vocabulary [Text]
brivla [Text]
cmavo [Text]
cmevla where
        brivla :: [Text]
brivla = (Vocabulary -> [Text]
vocabularyBrivlaList Vocabulary
vocabulary1) [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Vocabulary -> [Text]
vocabularyBrivlaList Vocabulary
vocabulary2)
        cmavo :: [Text]
cmavo = (Vocabulary -> [Text]
vocabularyCmavoList Vocabulary
vocabulary1) [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Vocabulary -> [Text]
vocabularyCmavoList Vocabulary
vocabulary2)
        cmevla :: [Text]
cmevla = (Vocabulary -> [Text]
vocabularyCmevlaList Vocabulary
vocabulary1) [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (Vocabulary -> [Text]
vocabularyCmevlaList Vocabulary
vocabulary2)

instance Show Lesson where
    show :: Lesson -> String
show Lesson
lesson = String
"Lesson { title = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show (Lesson -> Text
lessonTitle Lesson
lesson) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" }"

-- * Decks
data DeckStore = DeckStore
    { DeckStore -> Map Text Deck
deckStoreDecks :: M.Map T.Text Deck
    }

data Deck = Deck
    { Deck -> Text
deckId :: T.Text
    , Deck -> Text
deckTitle :: T.Text
    , Deck -> Text
deckShortDescription :: T.Text
    , Deck -> Maybe Pandoc
deckLongDescription :: Maybe P.Pandoc
    , Deck -> Maybe Pandoc
deckCredits :: Maybe P.Pandoc
    , Deck -> Dictionary
deckDictionary :: Dictionary
    , Deck -> [Card]
deckCards :: [Card]
    }

data Card = Card
    { Card -> Text
cardTitle :: T.Text
    , Card -> Text
cardShortDescription :: T.Text
    , Card -> ExerciseGenerator
cardExercises :: ExerciseGenerator
    }

-- * Translations
type Translation = ([LojbanSentence], [EnglishSentence])
type TranslationGenerator = StdGen -> (Translation, StdGen)
type EnglishSentence = T.Text
type LojbanSentence = T.Text

type TranslationsByExpression = [(T.Text, [Translation])]
type TranslationGeneratorByExpression = [(T.Text, TranslationGenerator)]

type SentenceComparer = LojbanSentence -> LojbanSentence -> Bool

-- * Exercises
data PersonalizedExercise =
    PersonalizedExercise
        { PersonalizedExercise -> Exercise
peExercise :: Exercise
        , PersonalizedExercise -> Bool
peShouldDisplayHint :: Bool
        }

data Exercise =
    MultipleChoiceExercise
        { Exercise -> Text
mceTitle :: T.Text
        , Exercise -> [ExerciseSentence]
mceSentences :: [ExerciseSentence]
        , Exercise -> [Text]
mceCorrectAlternatives :: [T.Text]
        , Exercise -> [Text]
mceIncorrectAlternatives :: [T.Text]
        , Exercise -> Bool
mceFixedOrdering :: Bool
        } |
    SingleChoiceExercise
        { Exercise -> Text
sceTitle :: T.Text
        , Exercise -> [ExerciseSentence]
sceSentences :: [ExerciseSentence]
        , Exercise -> Text
sceCorrectAlternative :: T.Text
        , Exercise -> [Text]
sceIncorrectAlternatives :: [T.Text]
        , Exercise -> Bool
sceFixedOrdering :: Bool
        } |
    MatchingExercise
        { Exercise -> Text
mteTitle :: T.Text
        , Exercise -> [ExerciseSentence]
mteSentences :: [ExerciseSentence]
        , Exercise -> [(Text, Text)]
mteItems :: [(T.Text, T.Text)]
        } |
    TypingExercise
        { Exercise -> Text
tpeTitle :: T.Text
        , Exercise -> [ExerciseSentence]
tpeSentences :: [ExerciseSentence]
        , Exercise -> Text -> Bool
tpeValidate :: T.Text -> Bool
        , Exercise -> Text
tpeCanonicalAnswer :: T.Text
        }

type ExerciseGenerator = StdGen -> Exercise
type MaybeExerciseGenerator = StdGen -> (Maybe Exercise, StdGen)

instance Show Exercise where
    show :: Exercise -> String
show (MultipleChoiceExercise Text
title [ExerciseSentence]
sentences [Text]
correctAlternatives [Text]
incorrectAlternatives Bool
fixedOrdering) = String
"MultipleChoiceExercise { mceTitle = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
title) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", mceSentences = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([ExerciseSentence] -> String
forall a. Show a => a -> String
show [ExerciseSentence]
sentences) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", mceCorrectAlternatives = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([Text] -> String
forall a. Show a => a -> String
show [Text]
correctAlternatives) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", mceIncorrectAlternatives = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([Text] -> String
forall a. Show a => a -> String
show [Text]
incorrectAlternatives) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", fixedOrdering = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Bool -> String
forall a. Show a => a -> String
show Bool
fixedOrdering) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"
    show (SingleChoiceExercise Text
title [ExerciseSentence]
sentences Text
correctAlternative [Text]
incorrectAlternatives Bool
fixedOrdering) = String
"SingleChoiceExercise { sceTitle = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
title) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", sceSentences = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([ExerciseSentence] -> String
forall a. Show a => a -> String
show [ExerciseSentence]
sentences) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", sceCorrectAlternatives = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
correctAlternative) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", sceIncorrectAlternatives = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([Text] -> String
forall a. Show a => a -> String
show [Text]
incorrectAlternatives) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", fixedOrdering = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Bool -> String
forall a. Show a => a -> String
show Bool
fixedOrdering) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"
    show (MatchingExercise Text
title [ExerciseSentence]
sentences [(Text, Text)]
items) = String
"MatchingExercise { mteTitle = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
title) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", mteSentences = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([ExerciseSentence] -> String
forall a. Show a => a -> String
show [ExerciseSentence]
sentences) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", mteItems = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([(Text, Text)] -> String
forall a. Show a => a -> String
show [(Text, Text)]
items) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"
    show (TypingExercise Text
title [ExerciseSentence]
sentences Text -> Bool
_ Text
canonicalAnswer) = String
"TypingExercise {tpeTitle = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
title) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", tpeSentences = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ([ExerciseSentence] -> String
forall a. Show a => a -> String
show [ExerciseSentence]
sentences) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
", canonicalAnswer = " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Text -> String
forall a. Show a => a -> String
show Text
canonicalAnswer) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"}"

data ExerciseSentence = ExerciseSentence
    { ExerciseSentence -> Bool
esLojbanic :: Bool
    , ExerciseSentence -> Text
esText :: T.Text
    } deriving (Int -> ExerciseSentence -> ShowS
[ExerciseSentence] -> ShowS
ExerciseSentence -> String
(Int -> ExerciseSentence -> ShowS)
-> (ExerciseSentence -> String)
-> ([ExerciseSentence] -> ShowS)
-> Show ExerciseSentence
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ExerciseSentence -> ShowS
showsPrec :: Int -> ExerciseSentence -> ShowS
$cshow :: ExerciseSentence -> String
show :: ExerciseSentence -> String
$cshowList :: [ExerciseSentence] -> ShowS
showList :: [ExerciseSentence] -> ShowS
Show)