{-# LANGUAGE TemplateHaskell #-}
-- | The lowest level of chunks in Drasil. It all starts with an identifier and a term.
module Language.Drasil.Chunk.NamedIdea (
  -- * Type
  IdeaDict,
  -- * Classes
  NamedIdea(..), Idea(..),
  -- * Constructors
  idea, idea'
) where

import Control.Lens ((^.), makeLenses, Lens')

import Drasil.Database (UID, HasUID(..), declareHasChunkRefs, Generically(..),
  IsChunk)
import Language.Drasil.NaturalLanguage.English.NounPhrase.Core (NP)

-- | A NamedIdea is a 'term' that we've identified (has a 'UID') as being worthy
-- of naming.
class IsChunk c => NamedIdea c where
  -- | Lens to the term (an 'NP').
  term :: Lens' c NP

-- | An 'Idea' is the combination of a 'NamedIdea' and a 'CommonIdea'. In other
-- words, it /may/ have an acronym/abbreviation.
class NamedIdea c => Idea c where
  -- | Get the acronym/abbreviation.
  getA :: c -> Maybe String

-- Don't export the record accessors.
-- | 'IdeaDict' is the canonical dictionary associated to an 'Idea'.
-- Contains a 'UID' and a term that could have an abbreviation ('Maybe' 'String').
--
-- Ex. The project name "Double Pendulum" may have the abbreviation "DblPend".
data IdeaDict = IdeaDict {
  IdeaDict -> UID
_uu :: UID,
  IdeaDict -> NP
_np :: NP,
  IdeaDict -> Maybe String
mabbr :: Maybe String
}
declareHasChunkRefs ''IdeaDict
makeLenses ''IdeaDict

-- | Equal if 'UID's are equal.
instance Eq        IdeaDict where IdeaDict
a == :: IdeaDict -> IdeaDict -> Bool
== IdeaDict
b = IdeaDict
a IdeaDict -> Getting UID IdeaDict UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID IdeaDict UID
forall c. HasUID c => Getter c UID
Getter IdeaDict UID
uid UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== IdeaDict
b IdeaDict -> Getting UID IdeaDict UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID IdeaDict UID
forall c. HasUID c => Getter c UID
Getter IdeaDict UID
uid
-- | Finds the 'UID' of the 'IdeaDict' used to make the 'IdeaDict'.
instance HasUID    IdeaDict where uid :: Getter IdeaDict UID
uid = (UID -> f UID) -> IdeaDict -> f IdeaDict
Lens' IdeaDict UID
uu
-- | Finds the term ('NP') of the 'IdeaDict' used to make the 'IdeaDict'.
instance NamedIdea IdeaDict where term :: Lens' IdeaDict NP
term = (NP -> f NP) -> IdeaDict -> f IdeaDict
Lens' IdeaDict NP
np
-- | Finds the abbreviation of the 'IdeaDict'.
instance Idea      IdeaDict where getA :: IdeaDict -> Maybe String
getA = IdeaDict -> Maybe String
mabbr

-- | Construct an 'IdeaDict' (/with/ an acronym/abbreviation).
idea ::
  -- | The 'UID'.
  UID ->
  -- | The 'term' being declared.
  NP ->
  -- | The 'term's acronym/abbreviation.
  String -> IdeaDict
idea :: UID -> NP -> String -> IdeaDict
idea UID
u NP
t String
accAbbr = UID -> NP -> Maybe String -> IdeaDict
IdeaDict UID
u NP
t (String -> Maybe String
forall a. a -> Maybe a
Just String
accAbbr)

-- | Construct an 'IdeaDict' (/without/ an acronym/abbreviation).
idea' ::
  -- | The 'UID'.
  UID ->
  -- | The 'term' being declared.
  NP -> IdeaDict
idea' :: UID -> NP -> IdeaDict
idea' UID
u NP
t = UID -> NP -> Maybe String -> IdeaDict
IdeaDict UID
u NP
t Maybe String
forall a. Maybe a
Nothing