{-# LANGUAGE TemplateHaskell #-}

-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Terrain and Entities
module Swarm.Game.Land (
  TerrainEntityMaps (TerrainEntityMaps),
  terrainMap,
  entityMap,
  loadEntitiesAndTerrain,
) where

import Control.Algebra (Has)
import Control.Effect.Lift (Lift)
import Control.Effect.Throw (Throw)
import Control.Lens (makeLenses)
import GHC.Generics (Generic)
import Swarm.Failure (SystemFailure)
import Swarm.Game.Entity
import Swarm.Game.Terrain

data TerrainEntityMaps = TerrainEntityMaps
  { TerrainEntityMaps -> TerrainMap
_terrainMap :: TerrainMap
  , TerrainEntityMaps -> EntityMap
_entityMap :: EntityMap
  }
  deriving (Int -> TerrainEntityMaps -> ShowS
[TerrainEntityMaps] -> ShowS
TerrainEntityMaps -> String
(Int -> TerrainEntityMaps -> ShowS)
-> (TerrainEntityMaps -> String)
-> ([TerrainEntityMaps] -> ShowS)
-> Show TerrainEntityMaps
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TerrainEntityMaps -> ShowS
showsPrec :: Int -> TerrainEntityMaps -> ShowS
$cshow :: TerrainEntityMaps -> String
show :: TerrainEntityMaps -> String
$cshowList :: [TerrainEntityMaps] -> ShowS
showList :: [TerrainEntityMaps] -> ShowS
Show, (forall x. TerrainEntityMaps -> Rep TerrainEntityMaps x)
-> (forall x. Rep TerrainEntityMaps x -> TerrainEntityMaps)
-> Generic TerrainEntityMaps
forall x. Rep TerrainEntityMaps x -> TerrainEntityMaps
forall x. TerrainEntityMaps -> Rep TerrainEntityMaps x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. TerrainEntityMaps -> Rep TerrainEntityMaps x
from :: forall x. TerrainEntityMaps -> Rep TerrainEntityMaps x
$cto :: forall x. Rep TerrainEntityMaps x -> TerrainEntityMaps
to :: forall x. Rep TerrainEntityMaps x -> TerrainEntityMaps
Generic)

makeLenses ''TerrainEntityMaps

instance Semigroup TerrainEntityMaps where
  TerrainEntityMaps TerrainMap
tm1 EntityMap
em1 <> :: TerrainEntityMaps -> TerrainEntityMaps -> TerrainEntityMaps
<> TerrainEntityMaps TerrainMap
tm2 EntityMap
em2 =
    TerrainMap -> EntityMap -> TerrainEntityMaps
TerrainEntityMaps (TerrainMap
tm1 TerrainMap -> TerrainMap -> TerrainMap
forall a. Semigroup a => a -> a -> a
<> TerrainMap
tm2) (EntityMap
em1 EntityMap -> EntityMap -> EntityMap
forall a. Semigroup a => a -> a -> a
<> EntityMap
em2)

instance Monoid TerrainEntityMaps where
  mempty :: TerrainEntityMaps
mempty = TerrainMap -> EntityMap -> TerrainEntityMaps
TerrainEntityMaps TerrainMap
forall a. Monoid a => a
mempty EntityMap
forall a. Monoid a => a
mempty

loadEntitiesAndTerrain ::
  (Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
  m TerrainEntityMaps
loadEntitiesAndTerrain :: forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m TerrainEntityMaps
loadEntitiesAndTerrain =
  TerrainMap -> EntityMap -> TerrainEntityMaps
TerrainEntityMaps (TerrainMap -> EntityMap -> TerrainEntityMaps)
-> m TerrainMap -> m (EntityMap -> TerrainEntityMaps)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m TerrainMap
forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m TerrainMap
loadTerrain m (EntityMap -> TerrainEntityMaps)
-> m EntityMap -> m TerrainEntityMaps
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m EntityMap
forall (sig :: (* -> *) -> * -> *) (m :: * -> *).
(Has (Throw SystemFailure) sig m, Has (Lift IO) sig m) =>
m EntityMap
loadEntities