module Rattletrap.Type.Initialization where

import qualified Rattletrap.BitGet as BitGet
import qualified Rattletrap.BitPut as BitPut
import qualified Rattletrap.Schema as Schema
import qualified Rattletrap.Type.Int8Vector as Int8Vector
import qualified Rattletrap.Type.Vector as Vector
import qualified Rattletrap.Type.Version as Version
import qualified Rattletrap.Utility.Json as Json
import qualified Rattletrap.Utility.Monad as Monad

data Initialization = Initialization
  { -- | Not every class has an initial location. See
    -- 'Rattletrap.Data.classesWithLocation'.
    Initialization -> Maybe Vector
location :: Maybe Vector.Vector,
    -- | Only classes with location can have rotation, but not every one does.
    -- See 'Rattletrap.Data.classesWithRotation'.
    Initialization -> Maybe Int8Vector
rotation :: Maybe Int8Vector.Int8Vector
  }
  deriving (Initialization -> Initialization -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Initialization -> Initialization -> Bool
$c/= :: Initialization -> Initialization -> Bool
== :: Initialization -> Initialization -> Bool
$c== :: Initialization -> Initialization -> Bool
Eq, Int -> Initialization -> ShowS
[Initialization] -> ShowS
Initialization -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Initialization] -> ShowS
$cshowList :: [Initialization] -> ShowS
show :: Initialization -> String
$cshow :: Initialization -> String
showsPrec :: Int -> Initialization -> ShowS
$cshowsPrec :: Int -> Initialization -> ShowS
Show)

instance Json.FromJSON Initialization where
  parseJSON :: Value -> Parser Initialization
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"Initialization" forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    Maybe Vector
location <- forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"location"
    Maybe Int8Vector
rotation <- forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"rotation"
    forall (f :: * -> *) a. Applicative f => a -> f a
pure Initialization {Maybe Vector
location :: Maybe Vector
location :: Maybe Vector
location, Maybe Int8Vector
rotation :: Maybe Int8Vector
rotation :: Maybe Int8Vector
rotation}

instance Json.ToJSON Initialization where
  toJSON :: Initialization -> Value
toJSON Initialization
x =
    [(Key, Value)] -> Value
Json.object
      [forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"location" forall a b. (a -> b) -> a -> b
$ Initialization -> Maybe Vector
location Initialization
x, forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"rotation" forall a b. (a -> b) -> a -> b
$ Initialization -> Maybe Int8Vector
rotation Initialization
x]

schema :: Schema.Schema
schema :: Schema
schema =
  String -> Value -> Schema
Schema.named String
"initialization" forall a b. (a -> b) -> a -> b
$
    [((Key, Value), Bool)] -> Value
Schema.object
      [ (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"location" forall b c a. (b -> c) -> (a -> b) -> a -> c
. Schema -> Value
Schema.json forall a b. (a -> b) -> a -> b
$ Schema -> Schema
Schema.maybe Schema
Vector.schema, Bool
False),
        ( forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"rotation" forall b c a. (b -> c) -> (a -> b) -> a -> c
. Schema -> Value
Schema.json forall a b. (a -> b) -> a -> b
$ Schema -> Schema
Schema.maybe Schema
Int8Vector.schema,
          Bool
False
        )
      ]

bitPut :: Initialization -> BitPut.BitPut
bitPut :: Initialization -> BitPut
bitPut Initialization
initialization =
  forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Vector -> BitPut
Vector.bitPut (Initialization -> Maybe Vector
location Initialization
initialization)
    forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Int8Vector -> BitPut
Int8Vector.bitPut (Initialization -> Maybe Int8Vector
rotation Initialization
initialization)

bitGet :: Version.Version -> Bool -> Bool -> BitGet.BitGet Initialization
bitGet :: Version -> Bool -> Bool -> BitGet Initialization
bitGet Version
version Bool
hasLocation Bool
hasRotation = forall a. String -> BitGet a -> BitGet a
BitGet.label String
"Initialization" forall a b. (a -> b) -> a -> b
$ do
  Maybe Vector
location <-
    forall a. String -> BitGet a -> BitGet a
BitGet.label String
"location" forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe Bool
hasLocation (Version -> BitGet Vector
Vector.bitGet Version
version)
  Maybe Int8Vector
rotation <-
    forall a. String -> BitGet a -> BitGet a
BitGet.label String
"rotation" forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe Bool
hasRotation BitGet Int8Vector
Int8Vector.bitGet
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Initialization {Maybe Vector
location :: Maybe Vector
location :: Maybe Vector
location, Maybe Int8Vector
rotation :: Maybe Int8Vector
rotation :: Maybe Int8Vector
rotation}