{- |
This module provides a basic 'Language' type and functions for using it
as well as to this 'Language' specified versions of the generic report
and output.
-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
module Control.OutputCapable.Blocks.Report (
  module GenericReport,
  GenericOut (..),
  Out,
  ReportT,
  Report,
  Language (..),
  alignOutput,
  combineReports,
  combineTwoReports,
  english,
  german,
  getAllOuts,
  localise,
  toAbort,
  translations,
  ) where

import qualified Control.OutputCapable.Blocks.Report.Generic as GenericReport (
  alignOutput,
  combineReports,
  combineTwoReports,
  getAllOuts,
  toAbort,
  )
import Control.OutputCapable.Blocks.Report.Generic as GenericReport (
  GenericOut (..),
  getOutsWithResult,
  toOutput,
  )
import Control.OutputCapable.Blocks.Report.Generic (GenericReportT (..))

import qualified Data.Map               as M

import Autolib.Hash                     (Hashable)
import Autolib.Reader                   (Reader)
import Autolib.ToDoc                    (ToDoc)
import Control.Monad.Identity           (Identity)
import Control.Monad.State              (State, execState, modify)
import Data.Data                        (Data)
import Data.Map                         (Map)
import Data.Maybe                       (fromMaybe)
import GHC.Generics                     (Generic)

data Language = English | German
  deriving (Language
Language -> Language -> Bounded Language
forall a. a -> a -> Bounded a
$cminBound :: Language
minBound :: Language
$cmaxBound :: Language
maxBound :: Language
Bounded, Typeable Language
Typeable Language =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Language -> c Language)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Language)
-> (Language -> Constr)
-> (Language -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Language))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language))
-> ((forall b. Data b => b -> b) -> Language -> Language)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Language -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Language -> r)
-> (forall u. (forall d. Data d => d -> u) -> Language -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Language -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Language -> m Language)
-> Data Language
Language -> Constr
Language -> DataType
(forall b. Data b => b -> b) -> Language -> Language
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
forall u. (forall d. Data d => d -> u) -> Language -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Language -> c Language
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Language
$ctoConstr :: Language -> Constr
toConstr :: Language -> Constr
$cdataTypeOf :: Language -> DataType
dataTypeOf :: Language -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Language)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Language)
$cgmapT :: (forall b. Data b => b -> b) -> Language -> Language
gmapT :: (forall b. Data b => b -> b) -> Language -> Language
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Language -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Language -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Language -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Language -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Language -> m Language
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Language -> m Language
Data, Int -> Language
Language -> Int
Language -> [Language]
Language -> Language
Language -> Language -> [Language]
Language -> Language -> Language -> [Language]
(Language -> Language)
-> (Language -> Language)
-> (Int -> Language)
-> (Language -> Int)
-> (Language -> [Language])
-> (Language -> Language -> [Language])
-> (Language -> Language -> [Language])
-> (Language -> Language -> Language -> [Language])
-> Enum Language
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Language -> Language
succ :: Language -> Language
$cpred :: Language -> Language
pred :: Language -> Language
$ctoEnum :: Int -> Language
toEnum :: Int -> Language
$cfromEnum :: Language -> Int
fromEnum :: Language -> Int
$cenumFrom :: Language -> [Language]
enumFrom :: Language -> [Language]
$cenumFromThen :: Language -> Language -> [Language]
enumFromThen :: Language -> Language -> [Language]
$cenumFromTo :: Language -> Language -> [Language]
enumFromTo :: Language -> Language -> [Language]
$cenumFromThenTo :: Language -> Language -> Language -> [Language]
enumFromThenTo :: Language -> Language -> Language -> [Language]
Enum, Language -> Language -> Bool
(Language -> Language -> Bool)
-> (Language -> Language -> Bool) -> Eq Language
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Language -> Language -> Bool
== :: Language -> Language -> Bool
$c/= :: Language -> Language -> Bool
/= :: Language -> Language -> Bool
Eq, (forall x. Language -> Rep Language x)
-> (forall x. Rep Language x -> Language) -> Generic Language
forall x. Rep Language x -> Language
forall x. Language -> Rep Language x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Language -> Rep Language x
from :: forall x. Language -> Rep Language x
$cto :: forall x. Rep Language x -> Language
to :: forall x. Rep Language x -> Language
Generic, Eq Language
Eq Language =>
(Int -> Language -> Int) -> (Language -> Int) -> Hashable Language
Int -> Language -> Int
Language -> Int
forall a. Eq a => (Int -> a -> Int) -> (a -> Int) -> Hashable a
$chashWithSalt :: Int -> Language -> Int
hashWithSalt :: Int -> Language -> Int
$chash :: Language -> Int
hash :: Language -> Int
Hashable, Eq Language
Eq Language =>
(Language -> Language -> Ordering)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Bool)
-> (Language -> Language -> Language)
-> (Language -> Language -> Language)
-> Ord Language
Language -> Language -> Bool
Language -> Language -> Ordering
Language -> Language -> Language
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Language -> Language -> Ordering
compare :: Language -> Language -> Ordering
$c< :: Language -> Language -> Bool
< :: Language -> Language -> Bool
$c<= :: Language -> Language -> Bool
<= :: Language -> Language -> Bool
$c> :: Language -> Language -> Bool
> :: Language -> Language -> Bool
$c>= :: Language -> Language -> Bool
>= :: Language -> Language -> Bool
$cmax :: Language -> Language -> Language
max :: Language -> Language -> Language
$cmin :: Language -> Language -> Language
min :: Language -> Language -> Language
Ord, ReadPrec [Language]
ReadPrec Language
Int -> ReadS Language
ReadS [Language]
(Int -> ReadS Language)
-> ReadS [Language]
-> ReadPrec Language
-> ReadPrec [Language]
-> Read Language
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Language
readsPrec :: Int -> ReadS Language
$creadList :: ReadS [Language]
readList :: ReadS [Language]
$creadPrec :: ReadPrec Language
readPrec :: ReadPrec Language
$creadListPrec :: ReadPrec [Language]
readListPrec :: ReadPrec [Language]
Read, Parser [Language]
Parser Language
Int -> Parser Language
Parser Language
-> (Int -> Parser Language)
-> Parser Language
-> (Int -> Parser Language)
-> Parser [Language]
-> Reader Language
forall a.
Parser a
-> (Int -> Parser a)
-> Parser a
-> (Int -> Parser a)
-> Parser [a]
-> Reader a
$catomic_reader :: Parser Language
atomic_reader :: Parser Language
$catomic_readerPrec :: Int -> Parser Language
atomic_readerPrec :: Int -> Parser Language
$creader :: Parser Language
reader :: Parser Language
$creaderPrec :: Int -> Parser Language
readerPrec :: Int -> Parser Language
$creaderList :: Parser [Language]
readerList :: Parser [Language]
Reader, Int -> Language -> ShowS
[Language] -> ShowS
Language -> String
(Int -> Language -> ShowS)
-> (Language -> String) -> ([Language] -> ShowS) -> Show Language
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Language -> ShowS
showsPrec :: Int -> Language -> ShowS
$cshow :: Language -> String
show :: Language -> String
$cshowList :: [Language] -> ShowS
showList :: [Language] -> ShowS
Show, Int -> Language -> Doc
[Language] -> Doc
(Int -> Language -> Doc) -> ([Language] -> Doc) -> ToDoc Language
forall a. (Int -> a -> Doc) -> ([a] -> Doc) -> ToDoc a
$ctoDocPrec :: Int -> Language -> Doc
toDocPrec :: Int -> Language -> Doc
$ctoDocList :: [Language] -> Doc
toDocList :: [Language] -> Doc
ToDoc)

type ReportT = GenericReportT Language
type Out = GenericOut Language

type Report o r = ReportT o Identity r

translations :: State (Map k a1) a2 -> Map k a1
translations :: forall k a1 a2. State (Map k a1) a2 -> Map k a1
translations = (State (Map k a1) a2 -> Map k a1 -> Map k a1)
-> Map k a1 -> State (Map k a1) a2 -> Map k a1
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (Map k a1) a2 -> Map k a1 -> Map k a1
forall s a. State s a -> s -> s
execState Map k a1
forall k a. Map k a
M.empty

english :: String -> State (Map Language String) ()
english :: String -> State (Map Language String) ()
english = (Map Language String -> Map Language String)
-> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Language String -> Map Language String)
 -> State (Map Language String) ())
-> (String -> Map Language String -> Map Language String)
-> String
-> State (Map Language String) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ShowS)
-> Language -> String -> Map Language String -> Map Language String
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith ((String -> ShowS) -> String -> ShowS
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
forall a. [a] -> [a] -> [a]
(++)) Language
English

german :: String -> State (Map Language String) ()
german :: String -> State (Map Language String) ()
german = (Map Language String -> Map Language String)
-> State (Map Language String) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Language String -> Map Language String)
 -> State (Map Language String) ())
-> (String -> Map Language String -> Map Language String)
-> String
-> State (Map Language String) ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> ShowS)
-> Language -> String -> Map Language String -> Map Language String
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith ((String -> ShowS) -> String -> ShowS
forall a b c. (a -> b -> c) -> b -> a -> c
flip String -> ShowS
forall a. [a] -> [a] -> [a]
(++)) Language
German

localise :: Language -> Map Language String -> String
localise :: Language -> Map Language String -> String
localise Language
l Map Language String
lm = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
nonExistent (Maybe String -> String) -> Maybe String -> String
forall a b. (a -> b) -> a -> b
$ Language -> Map Language String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Language
l Map Language String
lm
  where
    nonExistent :: String
nonExistent
      | Map Language String -> Bool
forall a. Map Language a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Map Language String
lm   = ShowS
forall a. HasCallStack => String -> a
error String
"missing translation"
      | Bool
otherwise = (Language, String) -> String
forall a b. (a, b) -> b
snd ((Language, String) -> String) -> (Language, String) -> String
forall a b. (a -> b) -> a -> b
$ Map Language String -> (Language, String)
forall k a. Map k a -> (k, a)
M.findMin Map Language String
lm

{-|
This is a more specific version of 'GenericReport.getAllOuts'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
getAllOuts :: Monad m => GenericReportT l o m () -> m [GenericOut l o]
getAllOuts :: forall (m :: * -> *) l o.
Monad m =>
GenericReportT l o m () -> m [GenericOut l o]
getAllOuts = GenericReportT l o m () -> m [GenericOut l o]
forall (m :: * -> *) l o a.
Monad m =>
GenericReportT l o m a -> m [GenericOut l o]
GenericReport.getAllOuts

{-|
This is a more specific version of 'GenericReport.combineReports'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
combineReports
  :: Monad m
  => ([[o]] -> o)
  -> [GenericReportT l o m ()]
  -> GenericReportT l o m ()
combineReports :: forall (m :: * -> *) o l.
Monad m =>
([[o]] -> o)
-> [GenericReportT l o m ()] -> GenericReportT l o m ()
combineReports = ([[o]] -> o)
-> [GenericReportT l o m ()] -> GenericReportT l o m ()
forall (m :: * -> *) o l a.
Monad m =>
([[o]] -> o) -> [GenericReportT l o m a] -> GenericReportT l o m ()
GenericReport.combineReports

{-|
This is a more specific version of 'GenericReport.alignOutput'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
alignOutput
  :: Monad m
  => ([o] -> o)
  -> GenericReportT l o m ()
  -> GenericReportT l o m ()
alignOutput :: forall (m :: * -> *) o l.
Monad m =>
([o] -> o) -> GenericReportT l o m () -> GenericReportT l o m ()
alignOutput = ([o] -> o) -> GenericReportT l o m () -> GenericReportT l o m ()
forall (m :: * -> *) o l a.
Monad m =>
([o] -> o) -> GenericReportT l o m a -> GenericReportT l o m a
GenericReport.alignOutput

{-|
This is a more specific version of 'GenericReport.combineTwoReports'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
combineTwoReports
  :: Monad m
  => ([o] -> [o] -> o)
  -> GenericReportT l o m ()
  -> GenericReportT l o m ()
  -> GenericReportT l o m ()
combineTwoReports :: forall (m :: * -> *) o l.
Monad m =>
([o] -> [o] -> o)
-> GenericReportT l o m ()
-> GenericReportT l o m ()
-> GenericReportT l o m ()
combineTwoReports = ([o] -> [o] -> o)
-> GenericReportT l o m ()
-> GenericReportT l o m ()
-> GenericReportT l o m ()
forall (m :: * -> *) o l a b.
Monad m =>
([o] -> [o] -> o)
-> GenericReportT l o m a
-> GenericReportT l o m b
-> GenericReportT l o m ()
GenericReport.combineTwoReports

{-|
This is a more specific version of 'GenericReport.toAbort'
which enforces the usage pattern.
You should always prefer this version over the generic.
-}
toAbort
  :: Monad m
  => GenericReportT l o m ()
  -> GenericReportT l o m ()
toAbort :: forall (m :: * -> *) l o.
Monad m =>
GenericReportT l o m () -> GenericReportT l o m ()
toAbort = GenericReportT l o m () -> GenericReportT l o m ()
forall (m :: * -> *) l o a b.
Monad m =>
GenericReportT l o m a -> GenericReportT l o m b
GenericReport.toAbort