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
(Initialization -> Initialization -> Bool)
-> (Initialization -> Initialization -> Bool) -> Eq Initialization
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Initialization -> Initialization -> Bool
== :: Initialization -> Initialization -> Bool
$c/= :: Initialization -> Initialization -> Bool
/= :: Initialization -> Initialization -> Bool
Eq, Int -> Initialization -> ShowS
[Initialization] -> ShowS
Initialization -> String
(Int -> Initialization -> ShowS)
-> (Initialization -> String)
-> ([Initialization] -> ShowS)
-> Show Initialization
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Initialization -> ShowS
showsPrec :: Int -> Initialization -> ShowS
$cshow :: Initialization -> String
show :: Initialization -> String
$cshowList :: [Initialization] -> ShowS
showList :: [Initialization] -> ShowS
Show)

instance Json.FromJSON Initialization where
  parseJSON :: Value -> Parser Initialization
parseJSON = String
-> (Object -> Parser Initialization)
-> Value
-> Parser Initialization
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"Initialization" ((Object -> Parser Initialization)
 -> Value -> Parser Initialization)
-> (Object -> Parser Initialization)
-> Value
-> Parser Initialization
forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    Maybe Vector
location <- Object -> String -> Parser (Maybe Vector)
forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"location"
    Maybe Int8Vector
rotation <- Object -> String -> Parser (Maybe Int8Vector)
forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"rotation"
    Initialization -> Parser Initialization
forall a. a -> Parser a
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
      [String -> Maybe Vector -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"location" (Maybe Vector -> (Key, Value)) -> Maybe Vector -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ Initialization -> Maybe Vector
location Initialization
x, String -> Maybe Int8Vector -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"rotation" (Maybe Int8Vector -> (Key, Value))
-> Maybe Int8Vector -> (Key, Value)
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" (Value -> Schema) -> Value -> Schema
forall a b. (a -> b) -> a -> b
$
    [((Key, Value), Bool)] -> Value
Schema.object
      [ (String -> Value -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"location" (Value -> (Key, Value))
-> (Schema -> Value) -> Schema -> (Key, Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Schema -> Value
Schema.json (Schema -> (Key, Value)) -> Schema -> (Key, Value)
forall a b. (a -> b) -> a -> b
$ Schema -> Schema
Schema.maybe Schema
Vector.schema, Bool
False),
        ( String -> Value -> (Key, Value)
forall value e p.
(ToJSON value, KeyValue e p) =>
String -> value -> p
Json.pair String
"rotation" (Value -> (Key, Value))
-> (Schema -> Value) -> Schema -> (Key, Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Schema -> Value
Schema.json (Schema -> (Key, Value)) -> Schema -> (Key, Value)
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 =
  (Vector -> BitPut) -> Maybe Vector -> BitPut
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Vector -> BitPut
Vector.bitPut (Initialization -> Maybe Vector
location Initialization
initialization)
    BitPut -> BitPut -> BitPut
forall a. Semigroup a => a -> a -> a
<> (Int8Vector -> BitPut) -> Maybe Int8Vector -> BitPut
forall m a. Monoid m => (a -> m) -> Maybe a -> m
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 = String -> BitGet Initialization -> BitGet Initialization
forall a. String -> BitGet a -> BitGet a
BitGet.label String
"Initialization" (BitGet Initialization -> BitGet Initialization)
-> BitGet Initialization -> BitGet Initialization
forall a b. (a -> b) -> a -> b
$ do
  Maybe Vector
location <-
    String -> BitGet (Maybe Vector) -> BitGet (Maybe Vector)
forall a. String -> BitGet a -> BitGet a
BitGet.label String
"location" (BitGet (Maybe Vector) -> BitGet (Maybe Vector))
-> BitGet (Maybe Vector) -> BitGet (Maybe Vector)
forall a b. (a -> b) -> a -> b
$
      Bool -> Get BitString Identity Vector -> BitGet (Maybe Vector)
forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe Bool
hasLocation (Version -> Get BitString Identity Vector
Vector.bitGet Version
version)
  Maybe Int8Vector
rotation <-
    String -> BitGet (Maybe Int8Vector) -> BitGet (Maybe Int8Vector)
forall a. String -> BitGet a -> BitGet a
BitGet.label String
"rotation" (BitGet (Maybe Int8Vector) -> BitGet (Maybe Int8Vector))
-> BitGet (Maybe Int8Vector) -> BitGet (Maybe Int8Vector)
forall a b. (a -> b) -> a -> b
$
      Bool
-> Get BitString Identity Int8Vector -> BitGet (Maybe Int8Vector)
forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe Bool
hasRotation Get BitString Identity Int8Vector
Int8Vector.bitGet
  Initialization -> BitGet Initialization
forall a. a -> Get BitString Identity a
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}