-- | 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, dcc, dccWDS, cc, cc', ccs, cw,
  -- ** From a common idea ('CI')
  CommonConcept, dcc', dccWDS',
  -- ** From a 'ConceptChunk'
  ConceptInstance, cic
  ) where

import Language.Drasil.Classes (Idea, Definition(defn), ConceptDomain(cdom), Concept)
import Language.Drasil.Chunk.CommonIdea (commonIdea)
import Language.Drasil.Chunk.Concept.Core (ConceptChunk(ConDict),
  ConceptInstance(ConInst), CommonConcept(ComConDict))
import Language.Drasil.Sentence (Sentence(S))
import Language.Drasil.Chunk.NamedIdea(mkIdea,nw, nc)
import Language.Drasil.NounPhrase (NP, pn)
import Language.Drasil.ShortName (shortname')
import Language.Drasil.UID (HasUID(uid))

import Control.Lens ((^.))

--FIXME: Temporary ConceptDomain tag hacking to not break everything. 
 
dcc :: String -> NP -> String -> ConceptChunk 
-- | Smart constructor for creating concept chunks given a 'UID', 
-- 'NounPhrase' ('NP') and definition (as a 'String').
dcc :: String -> NP -> String -> ConceptChunk
dcc i :: String
i ter :: NP
ter des :: String
des = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (String -> NP -> Maybe String -> IdeaDict
mkIdea String
i NP
ter Maybe String
forall a. Maybe a
Nothing) (String -> Sentence
S String
des) []
-- ^ Concept domain tagging is not yet implemented in this constructor.

-- | Identical to 'dcc', but takes an abbreviation ('String') and returns a 'CommonConcept' instead.
dcc' :: String -> NP -> String -> String -> CommonConcept
dcc' :: String -> NP -> String -> String -> CommonConcept
dcc' i :: String
i t :: NP
t d :: String
d a :: String
a = CI -> Sentence -> CommonConcept
ComConDict (String -> NP -> String -> [UID] -> CI
commonIdea String
i NP
t String
a []) (String -> Sentence
S String
d)

-- | Similar to 'dcc', except the definition takes a 'Sentence'.
dccWDS :: String -> NP -> Sentence -> ConceptChunk
dccWDS :: String -> NP -> Sentence -> ConceptChunk
dccWDS i :: String
i t :: NP
t d :: Sentence
d = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (String -> NP -> Maybe String -> IdeaDict
mkIdea String
i NP
t Maybe String
forall a. Maybe a
Nothing) Sentence
d []

-- | Similar to 'dcc', except the definition is a 'Sentence', takes
-- an abbreviation ('String') and returns a 'CommonConcept' instead.
dccWDS' :: String -> NP -> Sentence -> String -> CommonConcept
dccWDS' :: String -> NP -> Sentence -> String -> CommonConcept
dccWDS' i :: String
i t :: NP
t d :: Sentence
d a :: String
a = CI -> Sentence -> CommonConcept
ComConDict (String -> NP -> String -> [UID] -> CI
commonIdea String
i NP
t String
a []) Sentence
d

-- | Constructor for projecting an idea into a 'ConceptChunk'. Takes the definition of the 
-- 'ConceptChunk' as a 'String'. Does not allow concept domain tagging.
cc :: Idea c => c -> String -> ConceptChunk
cc :: c -> String -> ConceptChunk
cc n :: c
n d :: String
d = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (c -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw c
n) (String -> Sentence
S String
d) []

-- | Same as 'cc', except definition is a 'Sentence'.
cc' :: Idea c => c -> Sentence -> ConceptChunk
cc' :: c -> Sentence -> ConceptChunk
cc' n :: c
n d :: Sentence
d = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (c -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw c
n) Sentence
d []

-- | Similar to 'cc'', but allows explicit domain tagging.
ccs :: (Idea c, Concept d) => c -> Sentence -> [d] -> ConceptChunk --Explicit tagging
ccs :: c -> Sentence -> [d] -> ConceptChunk
ccs n :: c
n d :: Sentence
d l :: [d]
l = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (c -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw c
n) Sentence
d ([UID] -> ConceptChunk) -> [UID] -> ConceptChunk
forall a b. (a -> b) -> a -> b
$ (d -> UID) -> [d] -> [UID]
forall a b. (a -> b) -> [a] -> [b]
map (d -> Getting UID d UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID d UID
forall c. HasUID c => Lens' c UID
uid) [d]
l

-- | For projecting out to the 'ConceptChunk' data-type.
cw :: Concept c => c -> ConceptChunk
cw :: c -> ConceptChunk
cw c :: c
c = IdeaDict -> Sentence -> [UID] -> ConceptChunk
ConDict (c -> IdeaDict
forall c. Idea c => c -> IdeaDict
nw 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
defn) (c -> [UID]
forall c. ConceptDomain c => c -> [UID]
cdom c
c)

-- | Constructor for a 'ConceptInstance'. Takes in the 
-- Reference Address ('String'), a definition ('Sentence'), 
-- a short name ('String'), and a domain (for explicit tagging).
cic :: Concept c => String -> Sentence -> String -> c -> ConceptInstance
cic :: String -> Sentence -> String -> c -> ConceptInstance
cic u :: String
u d :: Sentence
d sn :: String
sn dom :: c
dom = ConceptChunk -> String -> ShortName -> ConceptInstance
ConInst (NamedChunk -> Sentence -> [c] -> ConceptChunk
forall c d.
(Idea c, Concept d) =>
c -> Sentence -> [d] -> ConceptChunk
ccs (String -> NP -> NamedChunk
nc String
u (NP -> NamedChunk) -> NP -> NamedChunk
forall a b. (a -> b) -> a -> b
$ String -> NP
pn String
sn) Sentence
d [c
dom]) String
u (ShortName -> ConceptInstance) -> ShortName -> ConceptInstance
forall a b. (a -> b) -> a -> b
$ Sentence -> ShortName
shortname' (String -> Sentence
S String
sn)