-- | Defines a type for representing ODE-solving external libraries.
module Language.Drasil.Data.ODELibPckg (
  ODELibPckg(..), mkODELib, mkODELibNoPath
) where

import Language.Drasil.Code.ExternalLibrary (ExternalLibrary)
import Language.Drasil.Code.ExternalLibraryCall (ExternalLibraryCall)
import Language.Drasil.Code.Lang (Lang)
import Language.Drasil.Data.ODEInfo (ODEInfo)
import Language.Drasil.Mod (Name, Version)

-- | Holds an ODE library package.
data ODELibPckg = ODELib {
  -- | Library name.
  ODELibPckg -> Name
libName :: Name,
  -- | Version.
  ODELibPckg -> Name
libVers :: Version,
  -- | Library specifications.
  ODELibPckg -> ExternalLibrary
libSpec :: ExternalLibrary,
  -- | Library call.
  ODELibPckg -> ODEInfo -> ExternalLibraryCall
libCall :: ODEInfo -> ExternalLibraryCall,
  -- | Library path.
  ODELibPckg -> Maybe Name
libPath :: Maybe FilePath,
  -- It has been said that language information should be in language-related
  -- file, but this needs more thought. The language would need to declare
  -- which libraries it is compatible with, but how could it refer to a
  -- library? Give libraries UID?
  -- Also, this case seems different because ExternalLibraries are data. In
  -- future, if a user defines a new external library, we wouldn't expect them
  -- to update an internal Drasil file to add their library to a language's
  -- compatible libraries. So maybe declaring compatible languages at library
  -- definition time really is the right way to do this.
  -- | Compatible OO languages.
  ODELibPckg -> [Lang]
compatibleLangs :: [Lang]
}

-- | Makes an 'ODELibPckg' with the given name, 'ExternalLibrary' specification,
-- 'ExternalLibraryCall' specification parameterized by an 'ODEInfo', local file
-- path to the library, and list of compatible languages.
mkODELib :: Name -> Version -> ExternalLibrary -> (ODEInfo ->
  ExternalLibraryCall) -> FilePath -> [Lang] -> ODELibPckg
mkODELib :: Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Name
-> [Lang]
-> ODELibPckg
mkODELib Name
n Name
v ExternalLibrary
e ODEInfo -> ExternalLibraryCall
c Name
f = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Maybe Name
-> [Lang]
-> ODELibPckg
ODELib Name
n Name
v ExternalLibrary
e ODEInfo -> ExternalLibraryCall
c (Name -> Maybe Name
forall a. a -> Maybe a
Just Name
f)

-- | Makes an 'ODELibPckg' with the given name, 'ExternalLibrary' specification,
-- 'ExternalLibraryCall' specification parameterized by an 'ODEInfo', and list of
-- compatible languages.
mkODELibNoPath :: Name -> Version -> ExternalLibrary -> (ODEInfo ->
  ExternalLibraryCall) -> [Lang] -> ODELibPckg
mkODELibNoPath :: Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> [Lang]
-> ODELibPckg
mkODELibNoPath Name
n Name
v ExternalLibrary
e ODEInfo -> ExternalLibraryCall
c = Name
-> Name
-> ExternalLibrary
-> (ODEInfo -> ExternalLibraryCall)
-> Maybe Name
-> [Lang]
-> ODELibPckg
ODELib Name
n Name
v ExternalLibrary
e ODEInfo -> ExternalLibraryCall
c Maybe Name
forall a. Maybe a
Nothing