-- |
-- SPDX-License-Identifier: BSD-3-Clause
module Swarm.Game.Scenario.Topography.Structure.Named where

import Data.Set (Set)
import Data.Text (Text)
import Data.Yaml
import GHC.Generics (Generic)
import Swarm.Language.Syntax.Direction (AbsoluteDir)

newtype StructureName = StructureName Text
  deriving (StructureName -> StructureName -> Bool
(StructureName -> StructureName -> Bool)
-> (StructureName -> StructureName -> Bool) -> Eq StructureName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StructureName -> StructureName -> Bool
== :: StructureName -> StructureName -> Bool
$c/= :: StructureName -> StructureName -> Bool
/= :: StructureName -> StructureName -> Bool
Eq, Eq StructureName
Eq StructureName =>
(StructureName -> StructureName -> Ordering)
-> (StructureName -> StructureName -> Bool)
-> (StructureName -> StructureName -> Bool)
-> (StructureName -> StructureName -> Bool)
-> (StructureName -> StructureName -> Bool)
-> (StructureName -> StructureName -> StructureName)
-> (StructureName -> StructureName -> StructureName)
-> Ord StructureName
StructureName -> StructureName -> Bool
StructureName -> StructureName -> Ordering
StructureName -> StructureName -> StructureName
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StructureName -> StructureName -> Ordering
compare :: StructureName -> StructureName -> Ordering
$c< :: StructureName -> StructureName -> Bool
< :: StructureName -> StructureName -> Bool
$c<= :: StructureName -> StructureName -> Bool
<= :: StructureName -> StructureName -> Bool
$c> :: StructureName -> StructureName -> Bool
> :: StructureName -> StructureName -> Bool
$c>= :: StructureName -> StructureName -> Bool
>= :: StructureName -> StructureName -> Bool
$cmax :: StructureName -> StructureName -> StructureName
max :: StructureName -> StructureName -> StructureName
$cmin :: StructureName -> StructureName -> StructureName
min :: StructureName -> StructureName -> StructureName
Ord, Int -> StructureName -> ShowS
[StructureName] -> ShowS
StructureName -> String
(Int -> StructureName -> ShowS)
-> (StructureName -> String)
-> ([StructureName] -> ShowS)
-> Show StructureName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StructureName -> ShowS
showsPrec :: Int -> StructureName -> ShowS
$cshow :: StructureName -> String
show :: StructureName -> String
$cshowList :: [StructureName] -> ShowS
showList :: [StructureName] -> ShowS
Show, (forall x. StructureName -> Rep StructureName x)
-> (forall x. Rep StructureName x -> StructureName)
-> Generic StructureName
forall x. Rep StructureName x -> StructureName
forall x. StructureName -> Rep StructureName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. StructureName -> Rep StructureName x
from :: forall x. StructureName -> Rep StructureName x
$cto :: forall x. Rep StructureName x -> StructureName
to :: forall x. Rep StructureName x -> StructureName
Generic, Maybe StructureName
Value -> Parser [StructureName]
Value -> Parser StructureName
(Value -> Parser StructureName)
-> (Value -> Parser [StructureName])
-> Maybe StructureName
-> FromJSON StructureName
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser StructureName
parseJSON :: Value -> Parser StructureName
$cparseJSONList :: Value -> Parser [StructureName]
parseJSONList :: Value -> Parser [StructureName]
$comittedField :: Maybe StructureName
omittedField :: Maybe StructureName
FromJSON, [StructureName] -> Value
[StructureName] -> Encoding
StructureName -> Bool
StructureName -> Value
StructureName -> Encoding
(StructureName -> Value)
-> (StructureName -> Encoding)
-> ([StructureName] -> Value)
-> ([StructureName] -> Encoding)
-> (StructureName -> Bool)
-> ToJSON StructureName
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: StructureName -> Value
toJSON :: StructureName -> Value
$ctoEncoding :: StructureName -> Encoding
toEncoding :: StructureName -> Encoding
$ctoJSONList :: [StructureName] -> Value
toJSONList :: [StructureName] -> Value
$ctoEncodingList :: [StructureName] -> Encoding
toEncodingList :: [StructureName] -> Encoding
$comitField :: StructureName -> Bool
omitField :: StructureName -> Bool
ToJSON)

getStructureName :: StructureName -> Text
getStructureName :: StructureName -> Text
getStructureName (StructureName Text
sn) = Text
sn

data NamedArea a = NamedArea
  { forall a. NamedArea a -> StructureName
name :: StructureName
  , forall a. NamedArea a -> Set AbsoluteDir
recognize :: Set AbsoluteDir
  -- ^ whether this structure should be registered for automatic recognition
  -- and which orientations shall be recognized.
  -- The supplied direction indicates which cardinal direction the
  -- original map's "North" has been re-oriented to.
  -- E.g., 'DWest' represents a rotation of 90 degrees counter-clockwise.
  , forall a. NamedArea a -> Maybe Text
description :: Maybe Text
  -- ^ will be UI-facing only if this is a recognizable structure
  , forall a. NamedArea a -> a
structure :: a
  }
  deriving (NamedArea a -> NamedArea a -> Bool
(NamedArea a -> NamedArea a -> Bool)
-> (NamedArea a -> NamedArea a -> Bool) -> Eq (NamedArea a)
forall a. Eq a => NamedArea a -> NamedArea a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => NamedArea a -> NamedArea a -> Bool
== :: NamedArea a -> NamedArea a -> Bool
$c/= :: forall a. Eq a => NamedArea a -> NamedArea a -> Bool
/= :: NamedArea a -> NamedArea a -> Bool
Eq, Int -> NamedArea a -> ShowS
[NamedArea a] -> ShowS
NamedArea a -> String
(Int -> NamedArea a -> ShowS)
-> (NamedArea a -> String)
-> ([NamedArea a] -> ShowS)
-> Show (NamedArea a)
forall a. Show a => Int -> NamedArea a -> ShowS
forall a. Show a => [NamedArea a] -> ShowS
forall a. Show a => NamedArea a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> NamedArea a -> ShowS
showsPrec :: Int -> NamedArea a -> ShowS
$cshow :: forall a. Show a => NamedArea a -> String
show :: NamedArea a -> String
$cshowList :: forall a. Show a => [NamedArea a] -> ShowS
showList :: [NamedArea a] -> ShowS
Show, (forall a b. (a -> b) -> NamedArea a -> NamedArea b)
-> (forall a b. a -> NamedArea b -> NamedArea a)
-> Functor NamedArea
forall a b. a -> NamedArea b -> NamedArea a
forall a b. (a -> b) -> NamedArea a -> NamedArea b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> NamedArea a -> NamedArea b
fmap :: forall a b. (a -> b) -> NamedArea a -> NamedArea b
$c<$ :: forall a b. a -> NamedArea b -> NamedArea a
<$ :: forall a b. a -> NamedArea b -> NamedArea a
Functor, (forall m. Monoid m => NamedArea m -> m)
-> (forall m a. Monoid m => (a -> m) -> NamedArea a -> m)
-> (forall m a. Monoid m => (a -> m) -> NamedArea a -> m)
-> (forall a b. (a -> b -> b) -> b -> NamedArea a -> b)
-> (forall a b. (a -> b -> b) -> b -> NamedArea a -> b)
-> (forall b a. (b -> a -> b) -> b -> NamedArea a -> b)
-> (forall b a. (b -> a -> b) -> b -> NamedArea a -> b)
-> (forall a. (a -> a -> a) -> NamedArea a -> a)
-> (forall a. (a -> a -> a) -> NamedArea a -> a)
-> (forall a. NamedArea a -> [a])
-> (forall a. NamedArea a -> Bool)
-> (forall a. NamedArea a -> Int)
-> (forall a. Eq a => a -> NamedArea a -> Bool)
-> (forall a. Ord a => NamedArea a -> a)
-> (forall a. Ord a => NamedArea a -> a)
-> (forall a. Num a => NamedArea a -> a)
-> (forall a. Num a => NamedArea a -> a)
-> Foldable NamedArea
forall a. Eq a => a -> NamedArea a -> Bool
forall a. Num a => NamedArea a -> a
forall a. Ord a => NamedArea a -> a
forall m. Monoid m => NamedArea m -> m
forall a. NamedArea a -> Bool
forall a. NamedArea a -> Int
forall a. NamedArea a -> [a]
forall a. (a -> a -> a) -> NamedArea a -> a
forall m a. Monoid m => (a -> m) -> NamedArea a -> m
forall b a. (b -> a -> b) -> b -> NamedArea a -> b
forall a b. (a -> b -> b) -> b -> NamedArea a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => NamedArea m -> m
fold :: forall m. Monoid m => NamedArea m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> NamedArea a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> NamedArea a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> NamedArea a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> NamedArea a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> NamedArea a -> b
foldr :: forall a b. (a -> b -> b) -> b -> NamedArea a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> NamedArea a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> NamedArea a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> NamedArea a -> b
foldl :: forall b a. (b -> a -> b) -> b -> NamedArea a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> NamedArea a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> NamedArea a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> NamedArea a -> a
foldr1 :: forall a. (a -> a -> a) -> NamedArea a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> NamedArea a -> a
foldl1 :: forall a. (a -> a -> a) -> NamedArea a -> a
$ctoList :: forall a. NamedArea a -> [a]
toList :: forall a. NamedArea a -> [a]
$cnull :: forall a. NamedArea a -> Bool
null :: forall a. NamedArea a -> Bool
$clength :: forall a. NamedArea a -> Int
length :: forall a. NamedArea a -> Int
$celem :: forall a. Eq a => a -> NamedArea a -> Bool
elem :: forall a. Eq a => a -> NamedArea a -> Bool
$cmaximum :: forall a. Ord a => NamedArea a -> a
maximum :: forall a. Ord a => NamedArea a -> a
$cminimum :: forall a. Ord a => NamedArea a -> a
minimum :: forall a. Ord a => NamedArea a -> a
$csum :: forall a. Num a => NamedArea a -> a
sum :: forall a. Num a => NamedArea a -> a
$cproduct :: forall a. Num a => NamedArea a -> a
product :: forall a. Num a => NamedArea a -> a
Foldable, Functor NamedArea
Foldable NamedArea
(Functor NamedArea, Foldable NamedArea) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> NamedArea a -> f (NamedArea b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    NamedArea (f a) -> f (NamedArea a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> NamedArea a -> m (NamedArea b))
-> (forall (m :: * -> *) a.
    Monad m =>
    NamedArea (m a) -> m (NamedArea a))
-> Traversable NamedArea
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a.
Monad m =>
NamedArea (m a) -> m (NamedArea a)
forall (f :: * -> *) a.
Applicative f =>
NamedArea (f a) -> f (NamedArea a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NamedArea a -> m (NamedArea b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NamedArea a -> f (NamedArea b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NamedArea a -> f (NamedArea b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NamedArea a -> f (NamedArea b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
NamedArea (f a) -> f (NamedArea a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
NamedArea (f a) -> f (NamedArea a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NamedArea a -> m (NamedArea b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> NamedArea a -> m (NamedArea b)
$csequence :: forall (m :: * -> *) a.
Monad m =>
NamedArea (m a) -> m (NamedArea a)
sequence :: forall (m :: * -> *) a.
Monad m =>
NamedArea (m a) -> m (NamedArea a)
Traversable)

isRecognizable :: NamedArea a -> Bool
isRecognizable :: forall a. NamedArea a -> Bool
isRecognizable = Bool -> Bool
not (Bool -> Bool) -> (NamedArea a -> Bool) -> NamedArea a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set AbsoluteDir -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Set AbsoluteDir -> Bool)
-> (NamedArea a -> Set AbsoluteDir) -> NamedArea a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NamedArea a -> Set AbsoluteDir
forall a. NamedArea a -> Set AbsoluteDir
recognize