{-# LANGUAGE TypeFamilies #-}

-- | The logic to render Julia auxiliary files is contained in this module
module Language.Drasil.Code.Imperative.GOOL.LanguageRenderer.JuliaRenderer (
  JuliaProject(..)
) where

import Language.Drasil.Code.Imperative.GOOL.ClassInterface (PackageSym(..), AuxiliarySym(..))
import Language.Drasil.Code.Imperative.ReadMe.Import (ReadMeInfo(..))
import qualified 
  Language.Drasil.Code.Imperative.GOOL.LanguageRenderer.LanguagePolymorphic as
  G (sampleInput, readMe, makefile, noRunIfLib, docIfEnabled)
import Language.Drasil.Code.Imperative.GOOL.Data (AuxData(..), ad, PackData(..),
  packD)
import Language.Drasil.Code.Imperative.Build.AST (Runnable, DocConfig(..), interpMM)

import Drasil.GProc (onCodeList, jlName, jlVersion)

import Prelude hiding (break,print,(<>),sin,cos,tan,floor)
import Text.PrettyPrint.HughesPJ (Doc, empty)

-- | Holds a Julia project
newtype JuliaProject a = JLP {forall a. JuliaProject a -> a
unJLP :: a}

instance Functor JuliaProject where
  fmap :: forall a b. (a -> b) -> JuliaProject a -> JuliaProject b
fmap a -> b
f (JLP a
x) = b -> JuliaProject b
forall a. a -> JuliaProject a
JLP (a -> b
f a
x)

instance Applicative JuliaProject where
  pure :: forall a. a -> JuliaProject a
pure = a -> JuliaProject a
forall a. a -> JuliaProject a
JLP
  (JLP a -> b
f) <*> :: forall a b.
JuliaProject (a -> b) -> JuliaProject a -> JuliaProject b
<*> (JLP a
x) = b -> JuliaProject b
forall a. a -> JuliaProject a
JLP (a -> b
f a
x)

instance Monad JuliaProject where
  JLP a
x >>= :: forall a b.
JuliaProject a -> (a -> JuliaProject b) -> JuliaProject b
>>= a -> JuliaProject b
f = a -> JuliaProject b
f a
x

instance PackageSym JuliaProject where
  type Package JuliaProject = PackData
  package :: ProgData
-> [JuliaProject (Auxiliary JuliaProject)]
-> JuliaProject (Package JuliaProject)
package ProgData
p = ([AuxData] -> PackData)
-> [JuliaProject AuxData] -> JuliaProject PackData
forall (m :: * -> *) a b. Monad m => ([a] -> b) -> [m a] -> m b
onCodeList (ProgData -> [AuxData] -> PackData
packD ProgData
p)

instance AuxiliarySym JuliaProject where
  type Auxiliary JuliaProject = AuxData
  type AuxHelper JuliaProject = Doc
  doxConfig :: String
-> GOOLState -> Verbosity -> JuliaProject (Auxiliary JuliaProject)
doxConfig String
_ GOOLState
_ Verbosity
_ = String -> Doc -> JuliaProject (Auxiliary JuliaProject)
forall (r :: * -> *).
AuxiliarySym r =>
String -> Doc -> r (Auxiliary r)
auxFromData String
"" Doc
empty -- Doxygen does not support Julia
  readMe :: ReadMeInfo -> JuliaProject (Auxiliary JuliaProject)
readMe ReadMeInfo
rmi = ReadMeInfo -> JuliaProject (Auxiliary JuliaProject)
forall (r :: * -> *).
AuxiliarySym r =>
ReadMeInfo -> r (Auxiliary r)
G.readMe ReadMeInfo
rmi {
        langName = jlName,
        langVersion = jlVersion}
  sampleInput :: ChunkDB
-> DataDesc -> [Expr] -> JuliaProject (Auxiliary JuliaProject)
sampleInput = ChunkDB
-> DataDesc -> [Expr] -> JuliaProject (Auxiliary JuliaProject)
forall (r :: * -> *).
AuxiliarySym r =>
ChunkDB -> DataDesc -> [Expr] -> r (Auxiliary r)
G.sampleInput

  optimizeDox :: JuliaProject (AuxHelper JuliaProject)
optimizeDox = String -> JuliaProject Doc
forall a. HasCallStack => String -> a
error String
doxError

  makefile :: [String]
-> ImplementationType
-> [Comments]
-> GOOLState
-> ProgData
-> JuliaProject (Auxiliary JuliaProject)
makefile [String]
_ ImplementationType
it [Comments]
cms = Maybe BuildConfig
-> Maybe Runnable
-> Maybe DocConfig
-> GOOLState
-> ProgData
-> JuliaProject (Auxiliary JuliaProject)
forall (r :: * -> *).
AuxiliarySym r =>
Maybe BuildConfig
-> Maybe Runnable
-> Maybe DocConfig
-> GOOLState
-> ProgData
-> r (Auxiliary r)
G.makefile Maybe BuildConfig
forall a. Maybe a
Nothing (ImplementationType -> Maybe Runnable -> Maybe Runnable
G.noRunIfLib ImplementationType
it Maybe Runnable
jlRunnable)
                            ([Comments] -> DocConfig -> Maybe DocConfig
G.docIfEnabled [Comments]
cms (Dependencies -> [Command] -> DocConfig
DocConfig [] []))

  auxHelperDoc :: JuliaProject (AuxHelper JuliaProject) -> Doc
auxHelperDoc = JuliaProject Doc -> Doc
JuliaProject (AuxHelper JuliaProject) -> Doc
forall a. JuliaProject a -> a
unJLP
  auxFromData :: String -> Doc -> JuliaProject (Auxiliary JuliaProject)
auxFromData String
fp Doc
d = AuxData -> JuliaProject AuxData
forall a. a -> JuliaProject a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AuxData -> JuliaProject AuxData)
-> AuxData -> JuliaProject AuxData
forall a b. (a -> b) -> a -> b
$ String -> Doc -> AuxData
ad String
fp Doc
d

-- | Default runnable information for Julia files
jlRunnable :: Maybe Runnable
jlRunnable :: Maybe Runnable
jlRunnable = String -> Maybe Runnable
interpMM String
"julia"
  
-- | Julia is not compatible with Doxygen, so raise an error if trying to compile Doxygen documentation.
doxError :: String
doxError :: String
doxError = String
jlName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" is not compatible with Doxygen."