{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      : Docs.Renderable
-- Description : Obtaining Information Needed for Rendering
-- License     : AGPL-3
-- Maintainer  : stu235271@mail.uni-kiel.de
--               stu236925@mail.uni-kiel.de
--
-- This module provides a class to obtain information from text nodes needed to
-- render these text nodes as html, pdf or the like.
module Docs.Renderable
    ( Renderable (..)
    , DirectRenderable (..)
    , directRenderable
    ) where

import Data.Text (Text)
import qualified Data.Text as Text
import qualified Docs.TextElement as TextElement
import Docs.TextRevision (TextElementRevision)
import qualified Docs.TextRevision as TextRevision
import qualified Language.Lsd.AST.Common as LSD

-- | Class for all types renderable as a text element.
class Renderable r where
    -- | The kind of the text
    kindOf :: r -> LSD.KindName

    -- | The type of the text
    typeOf :: r -> LSD.TypeName

    -- | The content of the text; the text itself
    contentOf :: r -> Text

instance Renderable TextElementRevision where
    kindOf :: TextElementRevision -> KindName
kindOf =
        String -> KindName
LSD.KindName
            (String -> KindName)
-> (TextElementRevision -> String)
-> TextElementRevision
-> KindName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Text.unpack
            (Text -> String)
-> (TextElementRevision -> Text) -> TextElementRevision -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElement -> Text
TextElement.textElementKind
            (TextElement -> Text)
-> (TextElementRevision -> TextElement)
-> TextElementRevision
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRevision -> TextElement
TextRevision.textElement

    typeOf :: TextElementRevision -> TypeName
typeOf =
        String -> TypeName
LSD.TypeName
            (String -> TypeName)
-> (TextElementRevision -> String)
-> TextElementRevision
-> TypeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Text.unpack
            (Text -> String)
-> (TextElementRevision -> Text) -> TextElementRevision -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElement -> Text
TextElement.textElementType
            (TextElement -> Text)
-> (TextElementRevision -> TextElement)
-> TextElementRevision
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRevision -> TextElement
TextRevision.textElement

    contentOf :: TextElementRevision -> Text
contentOf =
        Text -> (TextRevision -> Text) -> Maybe TextRevision -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" TextRevision -> Text
TextRevision.content (Maybe TextRevision -> Text)
-> (TextElementRevision -> Maybe TextRevision)
-> TextElementRevision
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TextElementRevision -> Maybe TextRevision
TextRevision.revision

-- | Datatype only intended to be used as a @Renderable@.
-- Can be used to enrich not-@Renderable@ types such as @Text@ with informations
-- needed to be renderable
data DirectRenderable id
    = DirectRenderable
    { forall id. DirectRenderable id -> KindName
kind :: LSD.KindName
    , forall id. DirectRenderable id -> TypeName
type_ :: LSD.TypeName
    , forall id. DirectRenderable id -> Text
content :: Text
    , forall id. DirectRenderable id -> id
identifier :: id
    }

-- | Make a @DirectRenderable@ from any @Renderable@
directRenderable :: (Renderable r) => r -> id -> DirectRenderable id
directRenderable :: forall r id. Renderable r => r -> id -> DirectRenderable id
directRenderable r
element id
id_ =
    DirectRenderable
        { kind :: KindName
kind = r -> KindName
forall r. Renderable r => r -> KindName
kindOf r
element
        , type_ :: TypeName
type_ = r -> TypeName
forall r. Renderable r => r -> TypeName
typeOf r
element
        , content :: Text
content = r -> Text
forall r. Renderable r => r -> Text
contentOf r
element
        , identifier :: id
identifier = id
id_
        }

instance Renderable (DirectRenderable id) where
    kindOf :: DirectRenderable id -> KindName
kindOf = DirectRenderable id -> KindName
forall id. DirectRenderable id -> KindName
kind
    typeOf :: DirectRenderable id -> TypeName
typeOf = DirectRenderable id -> TypeName
forall id. DirectRenderable id -> TypeName
type_
    contentOf :: DirectRenderable id -> Text
contentOf = DirectRenderable id -> Text
forall id. DirectRenderable id -> Text
content