{-|
Module      : Game.Werewolf.Variant
Description : Simplistic variant data structure with lenses and instances.

Copyright   : (c) Henry J. Wylde, 2016
License     : BSD3
Maintainer  : public@hjwylde.com

Variants alter how a game plays out. Either by changing the messages returned, or by changing the
game logic.
-}

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE TemplateHaskell   #-}

module Game.Werewolf.Variant (
    -- * Variant
    Variant,
    tag, name, description,

    -- ** Instances
    allVariants,

    standardVariant, noRoleKnowledgeVariant, noRoleKnowledgeOrRevealVariant, noRoleRevealVariant,
    spitefulVillageVariant,

    -- ** Traversals
    standard, noRoleKnowledge, noRoleKnowledgeOrReveal, noRoleReveal, spitefulVillage,
) where

import Control.Lens

import Data.String.Humanise
import Data.String.Interpolate.Extra
import Data.Text                     as T

import Game.Werewolf.Role hiding (description, name, tag)

-- | Variant definitions require only a few pieces of information.
data Variant = Variant
    { _tag         :: Text
    , _name        :: Text
    , _description :: Text
    } deriving (Eq, Read, Show)

makeLenses ''Variant

instance Humanise Variant where
    humanise = view name

-- | A list containing all the variants defined in this file.
allVariants :: [Variant]
allVariants =
    [ standardVariant
    , noRoleKnowledgeVariant
    , noRoleKnowledgeOrRevealVariant
    , noRoleRevealVariant
    , spitefulVillageVariant
    ]

standardVariant :: Variant
standardVariant = Variant
    { _tag          = "standard"
    , _name         = T.strip [iFile|variant/standard/name.txt|]
    , _description  = T.strip [iFile|variant/standard/description.txt|]
    }

noRoleKnowledgeVariant :: Variant
noRoleKnowledgeVariant = Variant
    { _tag          = "no-role-knowledge"
    , _name         = T.strip [iFile|variant/no-role-knowledge/name.txt|]
    , _description  = T.strip [iFile|variant/no-role-knowledge/description.txt|]
    }

noRoleKnowledgeOrRevealVariant :: Variant
noRoleKnowledgeOrRevealVariant = Variant
    { _tag          = "no-role-knowledge-or-reveal"
    , _name         = T.strip [iFile|variant/no-role-knowledge-or-reveal/name.txt|]
    , _description  = T.strip [iFile|variant/no-role-knowledge-or-reveal/description.txt|]
    }

noRoleRevealVariant :: Variant
noRoleRevealVariant = Variant
    { _tag          = "no-role-reveal"
    , _name         = T.strip [iFile|variant/no-role-reveal/name.txt|]
    , _description  = T.strip [iFile|variant/no-role-reveal/description.txt|]
    }

spitefulVillageVariant :: Variant
spitefulVillageVariant = Variant
    { _tag          = "spiteful-village"
    , _name         = T.strip [iFile|variant/spiteful-village/name.txt|]
    , _description  = T.strip [iFile|variant/spiteful-village/description.txt|]
    }

-- | The traversal of 'standard' 'Variant's.
--
-- @
-- 'standard' = 'only' 'standardVariant'
-- @
standard :: Traversal' Variant ()
standard = only standardVariant

-- | The traversal of 'noRoleKnowledge' 'Variant's.
--
-- @
-- 'noRoleKnowledge' = 'only' 'noRoleKnowledgeVariant'
-- @
noRoleKnowledge :: Traversal' Variant ()
noRoleKnowledge = only noRoleKnowledgeVariant

-- | The traversal of 'noRoleKnowledgeOrReveal' 'Variant's.
--
-- @
-- 'noRoleKnowledgeOrReveal' = 'only' 'noRoleKnowledgeOrRevealVariant'
-- @
noRoleKnowledgeOrReveal :: Traversal' Variant ()
noRoleKnowledgeOrReveal = only noRoleKnowledgeOrRevealVariant

-- | The traversal of 'noRoleReveal' 'Variant's.
--
-- @
-- 'noRoleReveal' = 'only' 'noRoleRevealVariant'
-- @
noRoleReveal :: Traversal' Variant ()
noRoleReveal = only noRoleRevealVariant

-- | The traversal of 'spitefulVillage' 'Variant's.
--
-- @
-- 'spitefulVillage' = 'only' 'spitefulVillageVariant'
-- @
spitefulVillage :: Traversal' Variant ()
spitefulVillage = only spitefulVillageVariant