{-# LANGUAGE TemplateHaskell #-}
module Lamdu.Sugar.Types.Tag
    ( Tag(..), tagName, tagVal, tagInstance
    , TagOption(..), toInfo, toPick
    , TagChoice(..), tcOptions, tcNewTag
    , TagRef(..), tagRefTag, tagRefReplace, tagRefJumpTo
    , OptionalTag(..), oTag, oPickAnon
    ) where

import qualified Control.Lens as Lens
import qualified Lamdu.Calc.Type as T
import           Lamdu.Sugar.Internal.EntityId (EntityId)

import           Lamdu.Prelude

data Tag name = Tag
    { _tagName :: name
    , _tagInstance :: EntityId -- Unique across different uses of a tag
    , _tagVal :: T.Tag
    } deriving (Eq, Ord, Show, Generic)

data TagOption name o = TagOption
    { _toInfo :: Tag name
    , _toPick :: o ()
    } deriving Generic

data TagChoice name o = TagChoice
    { _tcOptions :: [TagOption name o]
    , _tcNewTag :: TagOption name o
    } deriving Generic

-- | A mutable tag (that can be replaced with a different tag)
data TagRef name i o = TagRef
    { _tagRefTag :: Tag name
    , _tagRefReplace :: i (TagChoice name o)
    , _tagRefJumpTo :: Maybe (o EntityId)
    } deriving Generic

data OptionalTag name i o = OptionalTag
    { _oTag :: TagRef name i o
    , _oPickAnon :: o EntityId
    } deriving Generic

traverse Lens.makeLenses [''Tag, ''TagOption, ''TagRef, ''TagChoice, ''OptionalTag] <&> concat
