{-# LANGUAGE FlexibleContexts #-}
-- | Contains renderer-related functions specific to GOOL

module Drasil.GOOL.Renderers (
  renderType, renderParam, renderMethod, renderListDec, renderConstDecDef
) where

import Drasil.FileHandling.Legacy (indent)

import Drasil.Shared.InterfaceCommon (UnRepr(..), VariableSym(..),
  VariableElim(..), ValueSym(..), VisibilitySym(..), ParameterSym(..),
  BodySym(..))
import Drasil.GOOL.InterfaceGOOL (AttachmentSym(..))
import Drasil.Shared.RendererClassesCommon (CommonRenderSym, InternalVarElim(..),
  VisibilityElim(..), ValueElim(..))
import qualified Drasil.Shared.RendererClassesCommon as RC (BodyElim(..))
import Drasil.GOOL.RendererClassesOO (OORenderSym, PermElim(..))
import Drasil.Shared.LanguageRenderer (parameterList, new', constDec')
import Drasil.Shared.AST (TypeData(..))

import Prelude hiding ((<>))
import Text.PrettyPrint.HughesPJ (Doc, (<+>), (<>), vcat, text, lbrace, rbrace,
  parens, space, equals)

renderType :: (UnRepr r TypeData) => r TypeData -> Doc
renderType :: forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType = TypeData -> Doc
typeDoc (TypeData -> Doc) -> (r TypeData -> TypeData) -> r TypeData -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. r TypeData -> TypeData
forall (repr :: * -> *) contents.
UnRepr repr contents =>
repr contents -> contents
unRepr

renderParam :: (OORenderSym r, UnRepr r TypeData) => r (Variable r) -> Doc
renderParam :: forall (r :: * -> *).
(OORenderSym r, UnRepr r TypeData) =>
r (Variable r) -> Doc
renderParam r (Variable r)
v = r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r (Variable r) -> r TypeData
forall (r :: * -> *).
VariableElim r =>
r (Variable r) -> r TypeData
variableType r (Variable r)
v) Doc -> Doc -> Doc
<+> r (Variable r) -> Doc
forall (r :: * -> *). InternalVarElim r => r (Variable r) -> Doc
variable r (Variable r)
v

renderMethod :: (OORenderSym r, UnRepr r TypeData) => String ->
  r (Visibility r) -> r (Attachment r) -> r TypeData -> [r (Parameter r)] ->
  r (Body r) -> Doc
renderMethod :: forall (r :: * -> *).
(OORenderSym r, UnRepr r TypeData) =>
String
-> r (Visibility r)
-> r (Attachment r)
-> r TypeData
-> [r (Parameter r)]
-> r (Body r)
-> Doc
renderMethod String
n r (Visibility r)
s r (Attachment r)
p r TypeData
t [r (Parameter r)]
ps r (Body r)
b = [Doc] -> Doc
vcat [
  r (Visibility r) -> Doc
forall (r :: * -> *). VisibilityElim r => r (Visibility r) -> Doc
visibility r (Visibility r)
s Doc -> Doc -> Doc
<+> r (Attachment r) -> Doc
forall (r :: * -> *). PermElim r => r (Attachment r) -> Doc
perm r (Attachment r)
p Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType r TypeData
t Doc -> Doc -> Doc
<+> String -> Doc
text String
n Doc -> Doc -> Doc
<>
    (Doc -> Doc
parens ([r (Parameter r)] -> Doc
forall (r :: * -> *). CommonRenderSym r => [r (Parameter r)] -> Doc
parameterList [r (Parameter r)]
ps) Doc -> Doc -> Doc
<+> Doc
lbrace),
  Doc -> Doc
indent (r (Body r) -> Doc
forall (r :: * -> *). BodyElim r => r (Body r) -> Doc
RC.body r (Body r)
b),
  Doc
rbrace]

renderListDec :: (CommonRenderSym r, UnRepr r TypeData) => r (Variable r) ->
  r (Value r) -> Doc
renderListDec :: forall (r :: * -> *).
(CommonRenderSym r, UnRepr r TypeData) =>
r (Variable r) -> r (Value r) -> Doc
renderListDec r (Variable r)
v r (Value r)
n = Doc
space Doc -> Doc -> Doc
<> Doc
equals Doc -> Doc -> Doc
<+> Doc
new' Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r (Variable r) -> r TypeData
forall (r :: * -> *).
VariableElim r =>
r (Variable r) -> r TypeData
variableType r (Variable r)
v)
  Doc -> Doc -> Doc
<> Doc -> Doc
parens (r (Value r) -> Doc
forall (r :: * -> *). ValueElim r => r (Value r) -> Doc
value r (Value r)
n)

renderConstDecDef :: (CommonRenderSym r, UnRepr r TypeData) => r (Variable r) ->
  r (Value r) -> Doc
renderConstDecDef :: forall (r :: * -> *).
(CommonRenderSym r, UnRepr r TypeData) =>
r (Variable r) -> r (Value r) -> Doc
renderConstDecDef r (Variable r)
v r (Value r)
def = Doc
constDec' Doc -> Doc -> Doc
<+> r TypeData -> Doc
forall (r :: * -> *). UnRepr r TypeData => r TypeData -> Doc
renderType (r (Variable r) -> r TypeData
forall (r :: * -> *).
VariableElim r =>
r (Variable r) -> r TypeData
variableType r (Variable r)
v) Doc -> Doc -> Doc
<+>
  r (Variable r) -> Doc
forall (r :: * -> *). InternalVarElim r => r (Variable r) -> Doc
variable r (Variable r)
v Doc -> Doc -> Doc
<+> Doc
equals Doc -> Doc -> Doc
<+> r (Value r) -> Doc
forall (r :: * -> *). ValueElim r => r (Value r) -> Doc
value r (Value r)
def