module Rattletrap.Type.Attribute.Reservation where

import qualified Data.Word as Word
import qualified Rattletrap.BitGet as BitGet
import qualified Rattletrap.BitPut as BitPut
import qualified Rattletrap.Schema as Schema
import qualified Rattletrap.Type.Attribute.UniqueId as UniqueId
import qualified Rattletrap.Type.CompressedWord as CompressedWord
import qualified Rattletrap.Type.Str as Str
import qualified Rattletrap.Type.U8 as U8
import qualified Rattletrap.Type.Version as Version
import qualified Rattletrap.Utility.Json as Json
import qualified Rattletrap.Utility.Monad as Monad

data Reservation = Reservation
  { Reservation -> CompressedWord
number :: CompressedWord.CompressedWord,
    Reservation -> UniqueId
uniqueId :: UniqueId.UniqueId,
    Reservation -> Maybe Str
name :: Maybe Str.Str,
    Reservation -> Bool
unknown1 :: Bool,
    Reservation -> Bool
unknown2 :: Bool,
    Reservation -> Maybe Word8
unknown3 :: Maybe Word.Word8
  }
  deriving (Reservation -> Reservation -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Reservation -> Reservation -> Bool
$c/= :: Reservation -> Reservation -> Bool
== :: Reservation -> Reservation -> Bool
$c== :: Reservation -> Reservation -> Bool
Eq, Int -> Reservation -> ShowS
[Reservation] -> ShowS
Reservation -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Reservation] -> ShowS
$cshowList :: [Reservation] -> ShowS
show :: Reservation -> String
$cshow :: Reservation -> String
showsPrec :: Int -> Reservation -> ShowS
$cshowsPrec :: Int -> Reservation -> ShowS
Show)

instance Json.FromJSON Reservation where
  parseJSON :: Value -> Parser Reservation
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"Reservation" forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    CompressedWord
number <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"number"
    UniqueId
uniqueId <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"unique_id"
    Maybe Str
name <- forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"name"
    Bool
unknown1 <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"unknown1"
    Bool
unknown2 <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"unknown2"
    Maybe Word8
unknown3 <- forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"unknown3"
    forall (f :: * -> *) a. Applicative f => a -> f a
pure Reservation {CompressedWord
number :: CompressedWord
number :: CompressedWord
number, UniqueId
uniqueId :: UniqueId
uniqueId :: UniqueId
uniqueId, Maybe Str
name :: Maybe Str
name :: Maybe Str
name, Bool
unknown1 :: Bool
unknown1 :: Bool
unknown1, Bool
unknown2 :: Bool
unknown2 :: Bool
unknown2, Maybe Word8
unknown3 :: Maybe Word8
unknown3 :: Maybe Word8
unknown3}

instance Json.ToJSON Reservation where
  toJSON :: Reservation -> Value
toJSON Reservation
x =
    [(Key, Value)] -> Value
Json.object
      [ forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"number" forall a b. (a -> b) -> a -> b
$ Reservation -> CompressedWord
number Reservation
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unique_id" forall a b. (a -> b) -> a -> b
$ Reservation -> UniqueId
uniqueId Reservation
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"name" forall a b. (a -> b) -> a -> b
$ Reservation -> Maybe Str
name Reservation
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown1" forall a b. (a -> b) -> a -> b
$ Reservation -> Bool
unknown1 Reservation
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown2" forall a b. (a -> b) -> a -> b
$ Reservation -> Bool
unknown2 Reservation
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown3" forall a b. (a -> b) -> a -> b
$ Reservation -> Maybe Word8
unknown3 Reservation
x
      ]

schema :: Schema.Schema
schema :: Schema
schema =
  String -> Value -> Schema
Schema.named String
"attribute-reservation" 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
"number" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
CompressedWord.schema, Bool
True),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unique_id" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
UniqueId.schema, Bool
True),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"name" 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
Str.schema, Bool
False),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown1" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
Schema.boolean, Bool
True),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown2" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
Schema.boolean, Bool
True),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown3" 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
Schema.integer, Bool
False)
      ]

bitPut :: Reservation -> BitPut.BitPut
bitPut :: Reservation -> BitPut
bitPut Reservation
reservationAttribute =
  CompressedWord -> BitPut
CompressedWord.bitPut (Reservation -> CompressedWord
number Reservation
reservationAttribute)
    forall a. Semigroup a => a -> a -> a
<> UniqueId -> BitPut
UniqueId.bitPut (Reservation -> UniqueId
uniqueId Reservation
reservationAttribute)
    forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Str -> BitPut
Str.bitPut (Reservation -> Maybe Str
name Reservation
reservationAttribute)
    forall a. Semigroup a => a -> a -> a
<> Bool -> BitPut
BitPut.bool (Reservation -> Bool
unknown1 Reservation
reservationAttribute)
    forall a. Semigroup a => a -> a -> a
<> Bool -> BitPut
BitPut.bool (Reservation -> Bool
unknown2 Reservation
reservationAttribute)
    forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall a. Bits a => Int -> a -> BitPut
BitPut.bits Int
6) (Reservation -> Maybe Word8
unknown3 Reservation
reservationAttribute)

bitGet :: Version.Version -> BitGet.BitGet Reservation
bitGet :: Version -> BitGet Reservation
bitGet Version
version = forall a. String -> BitGet a -> BitGet a
BitGet.label String
"Reservation" forall a b. (a -> b) -> a -> b
$ do
  CompressedWord
number <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"number" forall a b. (a -> b) -> a -> b
$ Word -> BitGet CompressedWord
CompressedWord.bitGet Word
7
  UniqueId
uniqueId <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"uniqueId" forall a b. (a -> b) -> a -> b
$ Version -> BitGet UniqueId
UniqueId.bitGet Version
version
  Maybe Str
name <-
    forall a. String -> BitGet a -> BitGet a
BitGet.label String
"name" forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe
        (UniqueId -> U8
UniqueId.systemId UniqueId
uniqueId forall a. Eq a => a -> a -> Bool
/= Word8 -> U8
U8.fromWord8 Word8
0)
        BitGet Str
Str.bitGet
  Bool
unknown1 <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"unknown1" BitGet Bool
BitGet.bool
  Bool
unknown2 <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"unknown2" BitGet Bool
BitGet.bool
  Maybe Word8
unknown3 <-
    forall a. String -> BitGet a -> BitGet a
BitGet.label String
"unknown3"
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
Monad.whenMaybe (Int -> Int -> Int -> Version -> Bool
Version.atLeast Int
868 Int
12 Int
0 Version
version)
      forall a b. (a -> b) -> a -> b
$ forall a. Bits a => Int -> BitGet a
BitGet.bits Int
6
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Reservation {CompressedWord
number :: CompressedWord
number :: CompressedWord
number, UniqueId
uniqueId :: UniqueId
uniqueId :: UniqueId
uniqueId, Maybe Str
name :: Maybe Str
name :: Maybe Str
name, Bool
unknown1 :: Bool
unknown1 :: Bool
unknown1, Bool
unknown2 :: Bool
unknown2 :: Bool
unknown2, Maybe Word8
unknown3 :: Maybe Word8
unknown3 :: Maybe Word8
unknown3}