module Rattletrap.Type.Attribute.Product where

import qualified Data.Map as Map
import qualified Rattletrap.BitGet as BitGet
import qualified Rattletrap.BitPut as BitPut
import qualified Rattletrap.Schema as Schema
import qualified Rattletrap.Type.Attribute.ProductValue as ProductValue
import qualified Rattletrap.Type.List as List
import qualified Rattletrap.Type.Str as Str
import qualified Rattletrap.Type.U32 as U32
import qualified Rattletrap.Type.U8 as U8
import qualified Rattletrap.Type.Version as Version
import qualified Rattletrap.Utility.Json as Json

data Product = Product
  { Product -> Bool
unknown :: Bool,
    Product -> U32
objectId :: U32.U32,
    -- | read-only
    Product -> Maybe Str
objectName :: Maybe Str.Str,
    Product -> ProductValue
value :: ProductValue.ProductValue
  }
  deriving (Product -> Product -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Product -> Product -> Bool
$c/= :: Product -> Product -> Bool
== :: Product -> Product -> Bool
$c== :: Product -> Product -> Bool
Eq, Int -> Product -> ShowS
[Product] -> ShowS
Product -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Product] -> ShowS
$cshowList :: [Product] -> ShowS
show :: Product -> String
$cshow :: Product -> String
showsPrec :: Int -> Product -> ShowS
$cshowsPrec :: Int -> Product -> ShowS
Show)

instance Json.FromJSON Product where
  parseJSON :: Value -> Parser Product
parseJSON = forall a. String -> (Object -> Parser a) -> Value -> Parser a
Json.withObject String
"Product" forall a b. (a -> b) -> a -> b
$ \Object
object -> do
    Bool
unknown <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"unknown"
    U32
objectId <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"object_id"
    Maybe Str
objectName <- forall value.
FromJSON value =>
Object -> String -> Parser (Maybe value)
Json.optional Object
object String
"object_name"
    ProductValue
value <- forall value. FromJSON value => Object -> String -> Parser value
Json.required Object
object String
"value"
    forall (f :: * -> *) a. Applicative f => a -> f a
pure Product {Bool
unknown :: Bool
unknown :: Bool
unknown, U32
objectId :: U32
objectId :: U32
objectId, Maybe Str
objectName :: Maybe Str
objectName :: Maybe Str
objectName, ProductValue
value :: ProductValue
value :: ProductValue
value}

instance Json.ToJSON Product where
  toJSON :: Product -> Value
toJSON Product
x =
    [(Key, Value)] -> Value
Json.object
      [ forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"unknown" forall a b. (a -> b) -> a -> b
$ Product -> Bool
unknown Product
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"object_id" forall a b. (a -> b) -> a -> b
$ Product -> U32
objectId Product
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"object_name" forall a b. (a -> b) -> a -> b
$ Product -> Maybe Str
objectName Product
x,
        forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"value" forall a b. (a -> b) -> a -> b
$ Product -> ProductValue
value Product
x
      ]

schema :: Schema.Schema
schema :: Schema
schema =
  String -> Value -> Schema
Schema.named String
"attribute-product" 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
"unknown" 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
"object_id" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
U32.schema, Bool
True),
        (forall value pair.
(ToJSON value, KeyValue pair) =>
String -> value -> pair
Json.pair String
"object_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
"value" forall a b. (a -> b) -> a -> b
$ Schema -> Value
Schema.ref Schema
ProductValue.schema, Bool
True)
      ]

putProductAttributes :: List.List Product -> BitPut.BitPut
putProductAttributes :: List Product -> BitPut
putProductAttributes List Product
attributes =
  let v :: [Product]
v = forall a. List a -> [a]
List.toList List Product
attributes
   in (U8 -> BitPut
U8.bitPut forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> U8
U8.fromWord8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length [Product]
v) forall a. Semigroup a => a -> a -> a
<> forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Product -> BitPut
bitPut [Product]
v

bitPut :: Product -> BitPut.BitPut
bitPut :: Product -> BitPut
bitPut Product
attribute =
  Bool -> BitPut
BitPut.bool (Product -> Bool
unknown Product
attribute)
    forall a. Semigroup a => a -> a -> a
<> U32 -> BitPut
U32.bitPut (Product -> U32
objectId Product
attribute)
    forall a. Semigroup a => a -> a -> a
<> ProductValue -> BitPut
ProductValue.bitPut (Product -> ProductValue
value Product
attribute)

decodeProductAttributesBits ::
  Version.Version ->
  Map.Map U32.U32 Str.Str ->
  BitGet.BitGet (List.List Product)
decodeProductAttributesBits :: Version -> Map U32 Str -> BitGet (List Product)
decodeProductAttributesBits Version
version Map U32 Str
objectMap = do
  U8
size <- BitGet U8
U8.bitGet
  forall (m :: * -> *) a. Monad m => Int -> m a -> m (List a)
List.replicateM (forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ U8 -> Word8
U8.toWord8 U8
size) forall a b. (a -> b) -> a -> b
$ Version -> Map U32 Str -> BitGet Product
bitGet Version
version Map U32 Str
objectMap

bitGet :: Version.Version -> Map.Map U32.U32 Str.Str -> BitGet.BitGet Product
bitGet :: Version -> Map U32 Str -> BitGet Product
bitGet Version
version Map U32 Str
objectMap = forall a. String -> BitGet a -> BitGet a
BitGet.label String
"Product" forall a b. (a -> b) -> a -> b
$ do
  Bool
unknown <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"unknown" BitGet Bool
BitGet.bool
  U32
objectId <- forall a. String -> BitGet a -> BitGet a
BitGet.label String
"objectId" BitGet U32
U32.bitGet
  let objectName :: Maybe Str
objectName = forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup U32
objectId Map U32 Str
objectMap
  ProductValue
value <-
    forall a. String -> BitGet a -> BitGet a
BitGet.label String
"value" forall a b. (a -> b) -> a -> b
$
      Version -> U32 -> Maybe Str -> BitGet ProductValue
ProductValue.bitGet Version
version U32
objectId Maybe Str
objectName
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Product {Bool
unknown :: Bool
unknown :: Bool
unknown, U32
objectId :: U32
objectId :: U32
objectId, Maybe Str
objectName :: Maybe Str
objectName :: Maybe Str
objectName, ProductValue
value :: ProductValue
value :: ProductValue
value}