{-# LANGUAGE OverloadedStrings #-}

module Language.Lsd.AST.Type.DocumentContainer
    ( DocumentContainerFormat (..)
    , DocumentContainerType (..)
    , MainDocumentFormat (..)
    , HeaderFooterFormat (..)
    , HeaderFooterItemFormat (..)
    , HeaderFooterFormatAtom (..)
    )
where

import Data.Typography (FontSize, FontStyle)
import Language.Lsd.AST.Common (Fallback, NavTocHeading)
import Language.Lsd.AST.Format (FormatString, MainHeadingFormat)
import Language.Lsd.AST.SimpleRegex (Sequence (Sequence))
import Language.Lsd.AST.Type
    ( ChildrenOrder (SequenceOrder)
    , HasEditableHeader (HasEditableHeader)
    , NamedType
    , RawProperNodeKind (..)
    , TreeSyntax (TreeSyntax)
    )
import Language.Lsd.AST.Type.AppendixSection (AppendixSectionType)
import Language.Lsd.AST.Type.Document (DocumentType)

data DocumentContainerFormat
    = DocumentContainerFormat
        HeaderFooterFormat
        -- ^ header format
        HeaderFooterFormat
        -- ^ footer format
        MainDocumentFormat
    deriving (Int -> DocumentContainerFormat -> ShowS
[DocumentContainerFormat] -> ShowS
DocumentContainerFormat -> String
(Int -> DocumentContainerFormat -> ShowS)
-> (DocumentContainerFormat -> String)
-> ([DocumentContainerFormat] -> ShowS)
-> Show DocumentContainerFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DocumentContainerFormat -> ShowS
showsPrec :: Int -> DocumentContainerFormat -> ShowS
$cshow :: DocumentContainerFormat -> String
show :: DocumentContainerFormat -> String
$cshowList :: [DocumentContainerFormat] -> ShowS
showList :: [DocumentContainerFormat] -> ShowS
Show)

data DocumentContainerType
    = DocumentContainerType
        DocumentContainerFormat
        NavTocHeading
        (NamedType DocumentType)
        (Sequence (NamedType AppendixSectionType))

instance RawProperNodeKind DocumentContainerType where
    kindNameOfRaw :: Proxy DocumentContainerType -> KindName
kindNameOfRaw Proxy DocumentContainerType
_ = KindName
"document-container"

    treeSyntaxMapRaw :: forall a.
(forall t'. ProperNodeKind t' => t' -> a)
-> DocumentContainerType -> TreeSyntax a
treeSyntaxMapRaw
        forall t'. ProperNodeKind t' => t' -> a
f
        (DocumentContainerType DocumentContainerFormat
_ NavTocHeading
_ NamedType DocumentType
mainDocT (Sequence [NamedType AppendixSectionType]
appSecsT)) =
            HasEditableHeader -> ChildrenOrder a -> TreeSyntax a
forall a. HasEditableHeader -> ChildrenOrder a -> TreeSyntax a
TreeSyntax (Bool -> HasEditableHeader
HasEditableHeader Bool
True) (ChildrenOrder a -> TreeSyntax a)
-> ChildrenOrder a -> TreeSyntax a
forall a b. (a -> b) -> a -> b
$
                [Disjunction a] -> ChildrenOrder a
forall a. [Disjunction a] -> ChildrenOrder a
SequenceOrder ([Disjunction a] -> ChildrenOrder a)
-> [Disjunction a] -> ChildrenOrder a
forall a b. (a -> b) -> a -> b
$
                    a -> Disjunction a
forall a. a -> Disjunction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Disjunction a) -> [a] -> [Disjunction a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (NamedType DocumentType -> a
forall t'. ProperNodeKind t' => t' -> a
f NamedType DocumentType
mainDocT a -> [a] -> [a]
forall a. a -> [a] -> [a]
: (NamedType AppendixSectionType -> a)
-> [NamedType AppendixSectionType] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map NamedType AppendixSectionType -> a
forall t'. ProperNodeKind t' => t' -> a
f [NamedType AppendixSectionType]
appSecsT)

-- | Format of a main document.  To be used in addition to the respective
--   'Language.Lsd.AST.Document.DocumentFormat'.
data MainDocumentFormat
    = MainDocumentFormat
        (Fallback NavTocHeading)
        MainHeadingFormat
    deriving (Int -> MainDocumentFormat -> ShowS
[MainDocumentFormat] -> ShowS
MainDocumentFormat -> String
(Int -> MainDocumentFormat -> ShowS)
-> (MainDocumentFormat -> String)
-> ([MainDocumentFormat] -> ShowS)
-> Show MainDocumentFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MainDocumentFormat -> ShowS
showsPrec :: Int -> MainDocumentFormat -> ShowS
$cshow :: MainDocumentFormat -> String
show :: MainDocumentFormat -> String
$cshowList :: [MainDocumentFormat] -> ShowS
showList :: [MainDocumentFormat] -> ShowS
Show)

-- | The format of a printed header/footer.
data HeaderFooterFormat
    = -- | format
      HeaderFooterFormat
        [HeaderFooterItemFormat]
        -- ^ left
        [HeaderFooterItemFormat]
        -- ^ middle
        [HeaderFooterItemFormat]
        -- ^ right
    deriving (Int -> HeaderFooterFormat -> ShowS
[HeaderFooterFormat] -> ShowS
HeaderFooterFormat -> String
(Int -> HeaderFooterFormat -> ShowS)
-> (HeaderFooterFormat -> String)
-> ([HeaderFooterFormat] -> ShowS)
-> Show HeaderFooterFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HeaderFooterFormat -> ShowS
showsPrec :: Int -> HeaderFooterFormat -> ShowS
$cshow :: HeaderFooterFormat -> String
show :: HeaderFooterFormat -> String
$cshowList :: [HeaderFooterFormat] -> ShowS
showList :: [HeaderFooterFormat] -> ShowS
Show)

data HeaderFooterItemFormat
    = HeaderFooterItemFormat
        FontSize
        [FontStyle]
        (FormatString HeaderFooterFormatAtom)
    deriving (Int -> HeaderFooterItemFormat -> ShowS
[HeaderFooterItemFormat] -> ShowS
HeaderFooterItemFormat -> String
(Int -> HeaderFooterItemFormat -> ShowS)
-> (HeaderFooterItemFormat -> String)
-> ([HeaderFooterItemFormat] -> ShowS)
-> Show HeaderFooterItemFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HeaderFooterItemFormat -> ShowS
showsPrec :: Int -> HeaderFooterItemFormat -> ShowS
$cshow :: HeaderFooterItemFormat -> String
show :: HeaderFooterItemFormat -> String
$cshowList :: [HeaderFooterItemFormat] -> ShowS
showList :: [HeaderFooterItemFormat] -> ShowS
Show)

data HeaderFooterFormatAtom
    = HeaderFooterSuperTitleAtom
    | HeaderFooterTitleAtom
    | HeaderFooterDateAtom
    | HeaderFooterCurPageNumAtom
    | HeaderFooterLastPageNumAtom
    deriving (Int -> HeaderFooterFormatAtom -> ShowS
[HeaderFooterFormatAtom] -> ShowS
HeaderFooterFormatAtom -> String
(Int -> HeaderFooterFormatAtom -> ShowS)
-> (HeaderFooterFormatAtom -> String)
-> ([HeaderFooterFormatAtom] -> ShowS)
-> Show HeaderFooterFormatAtom
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> HeaderFooterFormatAtom -> ShowS
showsPrec :: Int -> HeaderFooterFormatAtom -> ShowS
$cshow :: HeaderFooterFormatAtom -> String
show :: HeaderFooterFormatAtom -> String
$cshowList :: [HeaderFooterFormatAtom] -> ShowS
showList :: [HeaderFooterFormatAtom] -> ShowS
Show)