{- | Global Tile IDs

https://doc.mapeditor.org/en/latest/reference/global-tile-ids/

-}

module Data.Tiled.GID where

import Data.Aeson (FromJSON(..), ToJSON(..))
import Data.Bits (Bits(..), (.&.))
import Data.Bool (bool)
import Data.Word (Word32)
import Foreign (Storable(..))
import GHC.Generics (Generic)

newtype GID = GID { GID -> Word32
getGID :: Word32 }
  deriving (GID -> GID -> Bool
(GID -> GID -> Bool) -> (GID -> GID -> Bool) -> Eq GID
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GID -> GID -> Bool
$c/= :: GID -> GID -> Bool
== :: GID -> GID -> Bool
$c== :: GID -> GID -> Bool
Eq, Int -> GID -> ShowS
[GID] -> ShowS
GID -> String
(Int -> GID -> ShowS)
-> (GID -> String) -> ([GID] -> ShowS) -> Show GID
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GID] -> ShowS
$cshowList :: [GID] -> ShowS
show :: GID -> String
$cshow :: GID -> String
showsPrec :: Int -> GID -> ShowS
$cshowsPrec :: Int -> GID -> ShowS
Show, (forall x. GID -> Rep GID x)
-> (forall x. Rep GID x -> GID) -> Generic GID
forall x. Rep GID x -> GID
forall x. GID -> Rep GID x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GID x -> GID
$cfrom :: forall x. GID -> Rep GID x
Generic)
  deriving newtype (Value -> Parser [GID]
Value -> Parser GID
(Value -> Parser GID) -> (Value -> Parser [GID]) -> FromJSON GID
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [GID]
$cparseJSONList :: Value -> Parser [GID]
parseJSON :: Value -> Parser GID
$cparseJSON :: Value -> Parser GID
FromJSON, [GID] -> Encoding
[GID] -> Value
GID -> Encoding
GID -> Value
(GID -> Value)
-> (GID -> Encoding)
-> ([GID] -> Value)
-> ([GID] -> Encoding)
-> ToJSON GID
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [GID] -> Encoding
$ctoEncodingList :: [GID] -> Encoding
toJSONList :: [GID] -> Value
$ctoJSONList :: [GID] -> Value
toEncoding :: GID -> Encoding
$ctoEncoding :: GID -> Encoding
toJSON :: GID -> Value
$ctoJSON :: GID -> Value
ToJSON, Ptr b -> Int -> IO GID
Ptr b -> Int -> GID -> IO ()
Ptr GID -> IO GID
Ptr GID -> Int -> IO GID
Ptr GID -> Int -> GID -> IO ()
Ptr GID -> GID -> IO ()
GID -> Int
(GID -> Int)
-> (GID -> Int)
-> (Ptr GID -> Int -> IO GID)
-> (Ptr GID -> Int -> GID -> IO ())
-> (forall b. Ptr b -> Int -> IO GID)
-> (forall b. Ptr b -> Int -> GID -> IO ())
-> (Ptr GID -> IO GID)
-> (Ptr GID -> GID -> IO ())
-> Storable GID
forall b. Ptr b -> Int -> IO GID
forall b. Ptr b -> Int -> GID -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
poke :: Ptr GID -> GID -> IO ()
$cpoke :: Ptr GID -> GID -> IO ()
peek :: Ptr GID -> IO GID
$cpeek :: Ptr GID -> IO GID
pokeByteOff :: Ptr b -> Int -> GID -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> GID -> IO ()
peekByteOff :: Ptr b -> Int -> IO GID
$cpeekByteOff :: forall b. Ptr b -> Int -> IO GID
pokeElemOff :: Ptr GID -> Int -> GID -> IO ()
$cpokeElemOff :: Ptr GID -> Int -> GID -> IO ()
peekElemOff :: Ptr GID -> Int -> IO GID
$cpeekElemOff :: Ptr GID -> Int -> IO GID
alignment :: GID -> Int
$calignment :: GID -> Int
sizeOf :: GID -> Int
$csizeOf :: GID -> Int
Storable, Eq GID
GID
Eq GID
-> (GID -> GID -> GID)
-> (GID -> GID -> GID)
-> (GID -> GID -> GID)
-> (GID -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> GID
-> (Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> Bool)
-> (GID -> Maybe Int)
-> (GID -> Int)
-> (GID -> Bool)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int -> GID)
-> (GID -> Int)
-> Bits GID
Int -> GID
GID -> Bool
GID -> Int
GID -> Maybe Int
GID -> GID
GID -> Int -> Bool
GID -> Int -> GID
GID -> GID -> GID
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
popCount :: GID -> Int
$cpopCount :: GID -> Int
rotateR :: GID -> Int -> GID
$crotateR :: GID -> Int -> GID
rotateL :: GID -> Int -> GID
$crotateL :: GID -> Int -> GID
unsafeShiftR :: GID -> Int -> GID
$cunsafeShiftR :: GID -> Int -> GID
shiftR :: GID -> Int -> GID
$cshiftR :: GID -> Int -> GID
unsafeShiftL :: GID -> Int -> GID
$cunsafeShiftL :: GID -> Int -> GID
shiftL :: GID -> Int -> GID
$cshiftL :: GID -> Int -> GID
isSigned :: GID -> Bool
$cisSigned :: GID -> Bool
bitSize :: GID -> Int
$cbitSize :: GID -> Int
bitSizeMaybe :: GID -> Maybe Int
$cbitSizeMaybe :: GID -> Maybe Int
testBit :: GID -> Int -> Bool
$ctestBit :: GID -> Int -> Bool
complementBit :: GID -> Int -> GID
$ccomplementBit :: GID -> Int -> GID
clearBit :: GID -> Int -> GID
$cclearBit :: GID -> Int -> GID
setBit :: GID -> Int -> GID
$csetBit :: GID -> Int -> GID
bit :: Int -> GID
$cbit :: Int -> GID
zeroBits :: GID
$czeroBits :: GID
rotate :: GID -> Int -> GID
$crotate :: GID -> Int -> GID
shift :: GID -> Int -> GID
$cshift :: GID -> Int -> GID
complement :: GID -> GID
$ccomplement :: GID -> GID
xor :: GID -> GID -> GID
$cxor :: GID -> GID -> GID
.|. :: GID -> GID -> GID
$c.|. :: GID -> GID -> GID
.&. :: GID -> GID -> GID
$c.&. :: GID -> GID -> GID
$cp1Bits :: Eq GID
Bits)

pattern FLIPPED_HORIZONTALLY_BIT :: Int
pattern $bFLIPPED_HORIZONTALLY_BIT :: Int
$mFLIPPED_HORIZONTALLY_BIT :: forall r. Int -> (Void# -> r) -> (Void# -> r) -> r
FLIPPED_HORIZONTALLY_BIT = 32

pattern FLIPPED_VERTICALLY_BIT :: Int
pattern $bFLIPPED_VERTICALLY_BIT :: Int
$mFLIPPED_VERTICALLY_BIT :: forall r. Int -> (Void# -> r) -> (Void# -> r) -> r
FLIPPED_VERTICALLY_BIT = 31

pattern ROTATED_60_BIT :: Int
pattern $bROTATED_60_BIT :: Int
$mROTATED_60_BIT :: forall r. Int -> (Void# -> r) -> (Void# -> r) -> r
ROTATED_60_BIT = 30

pattern ROTATED_120_BIT :: Int
pattern $bROTATED_120_BIT :: Int
$mROTATED_120_BIT :: forall r. Int -> (Void# -> r) -> (Void# -> r) -> r
ROTATED_120_BIT = 29

data Flags = Flags
  { Flags -> Bool
flippedHorizontally :: Bool
  , Flags -> Bool
flippedVertically   :: Bool
  , Flags -> Bool
rotated60           :: Bool
  , Flags -> Bool
rotated120          :: Bool
  } deriving (Flags -> Flags -> Bool
(Flags -> Flags -> Bool) -> (Flags -> Flags -> Bool) -> Eq Flags
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Flags -> Flags -> Bool
$c/= :: Flags -> Flags -> Bool
== :: Flags -> Flags -> Bool
$c== :: Flags -> Flags -> Bool
Eq, Int -> Flags -> ShowS
[Flags] -> ShowS
Flags -> String
(Int -> Flags -> ShowS)
-> (Flags -> String) -> ([Flags] -> ShowS) -> Show Flags
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Flags] -> ShowS
$cshowList :: [Flags] -> ShowS
show :: Flags -> String
$cshow :: Flags -> String
showsPrec :: Int -> Flags -> ShowS
$cshowsPrec :: Int -> Flags -> ShowS
Show, (forall x. Flags -> Rep Flags x)
-> (forall x. Rep Flags x -> Flags) -> Generic Flags
forall x. Rep Flags x -> Flags
forall x. Flags -> Rep Flags x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Flags x -> Flags
$cfrom :: forall x. Flags -> Rep Flags x
Generic)

flags :: GID -> Flags
flags :: GID -> Flags
flags (GID Word32
bits) = Flags :: Bool -> Bool -> Bool -> Bool -> Flags
Flags
  { flippedHorizontally :: Bool
flippedHorizontally = Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
bits Int
FLIPPED_HORIZONTALLY_BIT
  , flippedVertically :: Bool
flippedVertically   = Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
bits Int
FLIPPED_VERTICALLY_BIT
  , rotated60 :: Bool
rotated60           = Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
bits Int
ROTATED_60_BIT
  , rotated120 :: Bool
rotated120          = Word32 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word32
bits Int
ROTATED_120_BIT
  }

flagBits :: Word32
flagBits :: Word32
flagBits =
  Int -> Word32
forall a. Bits a => Int -> a
bit Int
FLIPPED_HORIZONTALLY_BIT Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|.
  Int -> Word32
forall a. Bits a => Int -> a
bit Int
FLIPPED_VERTICALLY_BIT Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|.
  Int -> Word32
forall a. Bits a => Int -> a
bit Int
ROTATED_60_BIT Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|.
  Int -> Word32
forall a. Bits a => Int -> a
bit Int
ROTATED_120_BIT

toLocal :: GID -> Int
toLocal :: GID -> Int
toLocal (GID Word32
bits) = Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int) -> Word32 -> Int
forall a b. (a -> b) -> a -> b
$ Word32
bits Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32 -> Word32
forall a. Bits a => a -> a
complement Word32
flagBits

fromLocal :: Flags -> Int -> GID
fromLocal :: Flags -> Int -> GID
fromLocal Flags{Bool
rotated120 :: Bool
rotated60 :: Bool
flippedVertically :: Bool
flippedHorizontally :: Bool
rotated120 :: Flags -> Bool
rotated60 :: Flags -> Bool
flippedVertically :: Flags -> Bool
flippedHorizontally :: Flags -> Bool
..} Int
localId =
  Word32 -> GID
GID (Word32 -> GID) -> (Int -> Word32) -> Int -> GID
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> GID) -> Int -> GID
forall a b. (a -> b) -> a -> b
$
    Int
localId
    Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
0 Int
FLIPPED_HORIZONTALLY_BIT Bool
flippedHorizontally
    Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
0 Int
FLIPPED_VERTICALLY_BIT   Bool
flippedVertically
    Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
0 Int
ROTATED_60_BIT           Bool
rotated60
    Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int -> Int -> Bool -> Int
forall a. a -> a -> Bool -> a
bool Int
0 Int
ROTATED_120_BIT          Bool
rotated120