segmentarrayRead :: SegmentArray -> UInt -> Segment
segmentarrayRead (SegmentArray mba#) (W# ix#) = unsafeState# $ \s# ->
    case readInt16Array# mba# (ix2Bytes# ix# 0##) s# of { (# s#, x# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 1##) s# of { (# s#, y# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 2##) s# of { (# s#, z# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 6##)  s# of { (# s#, x0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 7##)  s# of { (# s#, x1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 8##)  s# of { (# s#, x2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 9##)  s# of { (# s#, y0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 10##) s# of { (# s#, y1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 11##) s# of { (# s#, y2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 12##) s# of { (# s#, z0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 13##) s# of { (# s#, z1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 14##) s# of { (# s#, z2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 15##) s# of { (# s#, _ #) -> 
        (# s#, Segment (Node (I16# x#) (I16# y#) (I16# z#))
                       (Turn (I8# x0#) (I8# x1#) (I8# x2#)
                             (I8# y0#) (I8# y1#) (I8# y2#)
                             (I8# z0#) (I8# z1#) (I8# z2#)) #) }}}}}}}}}}}}}

    where
      ix2Bytes# ix# a# = 
          word2Int# ((8## `timesWord#` ix#) `plusWord#` a#)
      ix4Bytes# ix# a# =
          word2Int# ((16## `timesWord#` ix#) `plusWord#` a#)



{-
-- | we create a newtype so that we later can just store the direction if we want
--   (strip Segment for structure)
newtype StorableSegment =
    StorableSegment Segment 


wrapStorableSegment :: Segment -> StorableSegment
wrapStorableSegment seg =
    StorableSegment seg


instance Storable StorableSegment where
    sizeOf _    = 16
    alignment _ = 4   -- ^ 4 byte align on ARM (?)
    peek ptr = do
        -- node
        x <- peekByteOff ptr 0 :: IO Int16
        y <- peekByteOff ptr 2 :: IO Int16
        z <- peekByteOff ptr 4 :: IO Int16
        -- turn
        x0 <- peekByteOff ptr 6 :: IO Int8
        x1 <- peekByteOff ptr 7 :: IO Int8
        x2 <- peekByteOff ptr 8 :: IO Int8
        y0 <- peekByteOff ptr 9 :: IO Int8
        y1 <- peekByteOff ptr 10 :: IO Int8
        y2 <- peekByteOff ptr 11 :: IO Int8
        z0 <- peekByteOff ptr 12 :: IO Int8
        z1 <- peekByteOff ptr 13 :: IO Int8
        z2 <- peekByteOff ptr 14 :: IO Int8
        -- 15 is empty!
        return $ StorableSegment $ Segment (Node x y z) (Turn x0 x1 x2
                                                              y0 y1 y2
                                                              z0 z1 z2)

    poke ptr (StorableSegment (Segment (Node x y z) (Turn x0 x1 x2
                                                          y0 y1 y2
                                                          z0 z1 z2))) = do
        -- node
        pokeByteOff ptr 0  x
        pokeByteOff ptr 2  y
        pokeByteOff ptr 4  z
        -- turn
        pokeByteOff ptr 6  x0
        pokeByteOff ptr 7  x1
        pokeByteOff ptr 8  x2
        pokeByteOff ptr 9  y0
        pokeByteOff ptr 10 y1
        pokeByteOff ptr 11 y2
        pokeByteOff ptr 12 z0
        pokeByteOff ptr 13 z1
        pokeByteOff ptr 14 z2
        -- 15: empty!
-}
segmentarrayRead :: SegmentArray -> UInt -> Segment
segmentarrayRead (SegmentArray mba#) (W# ix#) = unsafeState# $ \s# ->
    case readInt16Array# mba# (ix2Bytes# ix# 0##) s# of { (# s#, x# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 1##) s# of { (# s#, y# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 2##) s# of { (# s#, z# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 6##)  s# of { (# s#, x0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 7##)  s# of { (# s#, x1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 8##)  s# of { (# s#, x2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 9##)  s# of { (# s#, y0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 10##) s# of { (# s#, y1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 11##) s# of { (# s#, y2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 12##) s# of { (# s#, z0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 13##) s# of { (# s#, z1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 14##) s# of { (# s#, z2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 15##) s# of { (# s#, _ #) -> 
        (# s#, Segment (Node (I16# x#) (I16# y#) (I16# z#))
                       (Turn (I8# x0#) (I8# x1#) (I8# x2#)
                             (I8# y0#) (I8# y1#) (I8# y2#)
                             (I8# z0#) (I8# z1#) (I8# z2#)) #) }}}}}}}}}}}}}

    where
      ix2Bytes# ix# a# = 
          word2Int# ((8## `timesWord#` ix#) `plusWord#` a#)
      ix4Bytes# ix# a# =
          word2Int# ((16## `timesWord#` ix#) `plusWord#` a#)



{-
-- | we create a newtype so that we later can just store the direction if we want
--   (strip Segment for structure)
newtype StorableSegment =
    StorableSegment Segment 


wrapStorableSegment :: Segment -> StorableSegment
wrapStorableSegment seg =
    StorableSegment seg


instance Storable StorableSegment where
    sizeOf _    = 16
    alignment _ = 4   -- ^ 4 byte align on ARM (?)
    peek ptr = do
        -- node
        x <- peekByteOff ptr 0 :: IO Int16
        y <- peekByteOff ptr 2 :: IO Int16
        z <- peekByteOff ptr 4 :: IO Int16
        -- turn
        x0 <- peekByteOff ptr 6 :: IO Int8
        x1 <- peekByteOff ptr 7 :: IO Int8
        x2 <- peekByteOff ptr 8 :: IO Int8
        y0 <- peekByteOff ptr 9 :: IO Int8
        y1 <- peekByteOff ptr 10 :: IO Int8
        y2 <- peekByteOff ptr 11 :: IO Int8
        z0 <- peekByteOff ptr 12 :: IO Int8
        z1 <- peekByteOff ptr 13 :: IO Int8
        z2 <- peekByteOff ptr 14 :: IO Int8
        -- 15 is empty!
        return $ StorableSegment $ Segment (Node x y z) (Turn x0 x1 x2
                                                              y0 y1 y2
                                                              z0 z1 z2)

    poke ptr (StorableSegment (Segment (Node x y z) (Turn x0 x1 x2
                                                          y0 y1 y2
                                                          z0 z1 z2))) = do
        -- node
        pokeByteOff ptr 0  x
        pokeByteOff ptr 2  y
        pokeByteOff ptr 4  z
        -- turn
        pokeByteOff ptr 6  x0
        pokeByteOff ptr 7  x1
        pokeByteOff ptr 8  x2
        pokeByteOff ptr 9  y0
        pokeByteOff ptr 10 y1
        pokeByteOff ptr 11 y2
        pokeByteOff ptr 12 z0
        pokeByteOff ptr 13 z1
        pokeByteOff ptr 14 z2
        -- 15: empty!
-}
segmentarrayRead (SegmentArray mba#) (W# ix#) = unsafeState# $ \s# ->
    case readInt16Array# mba# (ix2Bytes# ix# 0##) s# of { (# s#, x# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 1##) s# of { (# s#, y# #) -> 
    case readInt16Array# mba# (ix2Bytes# ix# 2##) s# of { (# s#, z# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 6##)  s# of { (# s#, x0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 7##)  s# of { (# s#, x1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 8##)  s# of { (# s#, x2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 9##)  s# of { (# s#, y0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 10##) s# of { (# s#, y1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 11##) s# of { (# s#, y2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 12##) s# of { (# s#, z0# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 13##) s# of { (# s#, z1# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 14##) s# of { (# s#, z2# #) -> 
    case readInt8Array# mba# (ix4Bytes# ix# 15##) s# of { (# s#, _ #) -> 
        (# s#, Segment (Node (I16# x#) (I16# y#) (I16# z#))
                       (Turn (I8# x0#) (I8# x1#) (I8# x2#)
                             (I8# y0#) (I8# y1#) (I8# y2#)
                             (I8# z0#) (I8# z1#) (I8# z2#)) #) }}}}}}}}}}}}}

    where
      ix2Bytes# ix# a# = 
          word2Int# ((8## `timesWord#` ix#) `plusWord#` a#)
      ix4Bytes# ix# a# =
          word2Int# ((16## `timesWord#` ix#) `plusWord#` a#)



{-
-- | we create a newtype so that we later can just store the direction if we want
--   (strip Segment for structure)
newtype StorableSegment =
    StorableSegment Segment 


wrapStorableSegment :: Segment -> StorableSegment
wrapStorableSegment seg =
    StorableSegment seg


instance Storable StorableSegment where
    sizeOf _    = 16
    alignment _ = 4   -- ^ 4 byte align on ARM (?)
    peek ptr = do
        -- node
        x <- peekByteOff ptr 0 :: IO Int16
        y <- peekByteOff ptr 2 :: IO Int16
        z <- peekByteOff ptr 4 :: IO Int16
        -- turn
        x0 <- peekByteOff ptr 6 :: IO Int8
        x1 <- peekByteOff ptr 7 :: IO Int8
        x2 <- peekByteOff ptr 8 :: IO Int8
        y0 <- peekByteOff ptr 9 :: IO Int8
        y1 <- peekByteOff ptr 10 :: IO Int8
        y2 <- peekByteOff ptr 11 :: IO Int8
        z0 <- peekByteOff ptr 12 :: IO Int8
        z1 <- peekByteOff ptr 13 :: IO Int8
        z2 <- peekByteOff ptr 14 :: IO Int8
        -- 15 is empty!
        return $ StorableSegment $ Segment (Node x y z) (Turn x0 x1 x2
                                                              y0 y1 y2
                                                              z0 z1 z2)

    poke ptr (StorableSegment (Segment (Node x y z) (Turn x0 x1 x2
                                                          y0 y1 y2
                                                          z0 z1 z2))) = do
        -- node
        pokeByteOff ptr 0  x
        pokeByteOff ptr 2  y
        pokeByteOff ptr 4  z
        -- turn
        pokeByteOff ptr 6  x0
        pokeByteOff ptr 7  x1
        pokeByteOff ptr 8  x2
        pokeByteOff ptr 9  y0
        pokeByteOff ptr 10 y1
        pokeByteOff ptr 11 y2
        pokeByteOff ptr 12 z0
        pokeByteOff ptr 13 z1
        pokeByteOff ptr 14 z2
        -- 15: empty!
-}