-- | Contains functions to create the concept related chunk types found in
-- "Language.Drasil.Chunk.Concept.Core".
module Language.Drasil.Chunk.Concept (
  -- * Concept Chunks
  -- ** From an idea ('IdeaDict')
  ConceptChunk, cncpt, cncpt', cncpt'', cncpt''', cw,
  ) where

import Control.Lens ((^.))

import Drasil.Database (HasUID(uid), UID)

import Language.Drasil.Classes (Concept)
import Language.Drasil.Chunk.Concept.Core (ConceptChunk(ConDict))
import Language.Drasil.Sentence (Sentence)
import Language.Drasil.Chunk.NamedIdea (NamedIdea (..), Idea (..))
import Language.Drasil.NaturalLanguage.English.NounPhrase (NP)
import qualified Language.Drasil.Classes as D (defn)

-- FIXME: There should only be two smart constructors ultimately for
-- `ConceptChunk`s. One with an abbreviation, the other without. In other words,
-- only `cncpt` and `cncpt'` should exist. The other ones should not. The
-- problem here is that dealing with the other ones requires domain analysis.

-- | Construct a 'ConceptChunk'.
cncpt :: Concept dom =>
  -- | The 'UID'.
  UID ->
  -- The 'term' being defined.
  NP ->
  -- | The definition of the 'term'
  Sentence ->
  -- | The term's abbreviation.
  String ->
  -- | The domain the 'term' belongs to.
  [dom] -> ConceptChunk
cncpt :: forall dom.
Concept dom =>
UID -> NP -> Sentence -> String -> [dom] -> ConceptChunk
cncpt UID
u NP
trm Sentence
defn String
accAbbr = UID -> NP -> Maybe String -> Sentence -> [UID] -> ConceptChunk
ConDict UID
u NP
trm (String -> Maybe String
forall a. a -> Maybe a
Just String
accAbbr) Sentence
defn ([UID] -> ConceptChunk)
-> ([dom] -> [UID]) -> [dom] -> ConceptChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (dom -> UID) -> [dom] -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (dom -> Getting UID dom UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID dom UID
forall c. HasUID c => Getter c UID
Getter dom UID
uid)

-- | Construct a 'ConceptChunk'.
cncpt' :: Concept dom =>
  -- | The 'UID'.
  UID ->
  -- | The 'term' being defined.
  NP ->
  -- | The definition of the 'term'
  Sentence ->
  -- | The domain the 'term' belongs to.
  [dom] -> ConceptChunk
cncpt' :: forall dom.
Concept dom =>
UID -> NP -> Sentence -> [dom] -> ConceptChunk
cncpt' UID
u NP
trm Sentence
defn = UID -> NP -> Maybe String -> Sentence -> [UID] -> ConceptChunk
ConDict UID
u NP
trm Maybe String
forall a. Maybe a
Nothing Sentence
defn ([UID] -> ConceptChunk)
-> ([dom] -> [UID]) -> [dom] -> ConceptChunk
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (dom -> UID) -> [dom] -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (dom -> Getting UID dom UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID dom UID
forall c. HasUID c => Getter c UID
Getter dom UID
uid)

-- | Construct a 'ConceptChunk'.
cncpt'' ::
  -- | The 'UID'.
  UID ->
  -- | The 'term' being defined.
  NP ->
  -- | The definition of the 'term'
  Sentence ->
  -- | The term's abbreviation.
  String -> ConceptChunk
cncpt'' :: UID -> NP -> Sentence -> String -> ConceptChunk
cncpt'' UID
u NP
trm Sentence
defn String
accAbbr = UID -> NP -> Sentence -> String -> [ConceptChunk] -> ConceptChunk
forall dom.
Concept dom =>
UID -> NP -> Sentence -> String -> [dom] -> ConceptChunk
cncpt UID
u NP
trm Sentence
defn String
accAbbr ([] :: [ConceptChunk])

-- | Construct a 'ConceptChunk'.
cncpt''' ::
  -- | The 'UID'.
  UID ->
  -- | The 'term' being defined.
  NP ->
  -- | The definition of the 'term'
  Sentence -> ConceptChunk
cncpt''' :: UID -> NP -> Sentence -> ConceptChunk
cncpt''' UID
u NP
trm Sentence
defn = UID -> NP -> Maybe String -> Sentence -> [UID] -> ConceptChunk
ConDict UID
u NP
trm Maybe String
forall a. Maybe a
Nothing Sentence
defn []

{-# DEPRECATED cw
  "Chunk down-casting is strongly discouraged. If you want to construct a `ConceptChunk`, use one of its normal constructors." #-}

-- | For projecting out to the 'ConceptChunk' data-type.
cw :: Concept c => c -> ConceptChunk
cw :: forall c. Concept c => c -> ConceptChunk
cw c
c = UID -> NP -> Maybe String -> Sentence -> [UID] -> ConceptChunk
ConDict (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid) (c
c c -> Getting NP c NP -> NP
forall s a. s -> Getting a s a -> a
^. Getting NP c NP
forall c. NamedIdea c => Lens' c NP
Lens' c NP
term) (c -> Maybe String
forall c. Idea c => c -> Maybe String
getA c
c) (c
c c -> Getting Sentence c Sentence -> Sentence
forall s a. s -> Getting a s a -> a
^. Getting Sentence c Sentence
forall c. Definition c => Lens' c Sentence
Lens' c Sentence
D.defn) []