{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

{-# OPTIONS_HADDOCK hide #-}

-- This file has been generated, if you wish to
-- modify it in a permanent way, please refer
-- to the script file : gen/generator_haskell.rb

module CApi where

import Data.List (foldl')
import Foreign
import Foreign.C.Types

import Foreign.Marshal.Array

#include "interface_c.hh"
type CBool = CChar

class ApiStorable a where
  type ApiStorableType a
  toStorable :: a -> (ApiStorableType a -> IO b) -> IO b
  unStorable :: ApiStorableType a -> IO a
  type ApiStorableBaseType a
  toStorableBase :: a -> (ApiStorableBaseType a -> IO b) -> IO b
  unStorableBase :: ApiStorableBaseType a -> IO a

instance ApiStorable () where
  type ApiStorableType () = ()
  toStorable () f = f ()
  {-# INLINE toStorable #-}
  unStorable _ = return ()
  {-# INLINE unStorable #-}
  type ApiStorableBaseType () = ()
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
instance ApiStorable Int where
  type ApiStorableType Int = CInt
  toStorable x f = f (fromIntegral x)
  {-# INLINE toStorable #-}
  unStorable = return . fromIntegral
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Int = ApiStorableType Int
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
instance ApiStorable Bool where
  type ApiStorableType Bool = CBool
  toStorable x f = f ((\bx -> if bx then 1 else 0) x)
  {-# INLINE toStorable #-}
  unStorable = return . (/= 0)
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Bool = ApiStorableType Bool
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
instance ApiStorable Double where
  type ApiStorableType Double = CDouble
  toStorable x f = f (CDouble x)
  {-# INLINE toStorable #-}
  unStorable = return . (\(CDouble x) -> x)
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Double = ApiStorableType Double
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
-- | Types de cases
data Case_type =
    Vide -- ^ Case vide 
  | Plomb -- ^ Plomb ; transmutable en or 
  | Fer -- ^ Fer ; transmutable en or 
  | Cuivre -- ^ Cuivre ; transmutable en or 
  | Soufre -- ^ Soufre ; transmutable en catalyseur 
  | Mercure -- ^ Mercure ; transmutable en catalyseur 
  deriving(Show, Eq, Enum)
type CCase_type = CInt

instance ApiStorable Case_type where
  type ApiStorableType Case_type = CInt
  toStorable x f = f (fromIntegral (fromEnum x))
  {-# INLINE toStorable #-}
  unStorable = return . toEnum . fromIntegral
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Case_type = ApiStorableType Case_type
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
-- | Types de propriétés des éléments
data Element_propriete =
    Aucune -- ^ Les cases vides ne contiennent pas d’élément, et n’ont donc aucune propriété 
  | Transmutable_or -- ^ Élement transmutable en or 
  | Transmutable_catalyseur -- ^ Élément transmutable en catalyseur 
  deriving(Show, Eq, Enum)
type CElement_propriete = CInt

instance ApiStorable Element_propriete where
  type ApiStorableType Element_propriete = CInt
  toStorable x f = f (fromIntegral (fromEnum x))
  {-# INLINE toStorable #-}
  unStorable = return . toEnum . fromIntegral
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Element_propriete = ApiStorableType Element_propriete
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
-- | Erreurs possibles
data Erreur =
    Ok -- ^ L’action a été exécutée avec succès 
  | Position_invalide -- ^ La position spécifiée n’est pas sur l’établi 
  | Placement_invalide -- ^ Les deux positions ne correspondent pas à des cases adjacentes 
  | Placement_impossible -- ^ Les cases ciblées ne sont pas vides 
  | Placement_incorrect -- ^ Un des deux éléments de l'échantillon doit être placé adjacent à un élément du même type déjà présent sur l'établi 
  | Case_vide -- ^ La case ciblée est vide 
  | Echantillon_incomplet -- ^ L’échantillon doit contenir deux éléments. 
  | Echantillon_invalide -- ^ L’échantillon doit contenir au moins un des éléments de l’échantillon reçu auparavant 
  | Aucun_catalyseur -- ^ Aucun catalyseur disponible 
  | Catalyse_invalide -- ^ L'élément de destination ne peut pas être vide. 
  | Deja_pose -- ^ L’échantillon a déjà été posé ce tour-ci 
  | Deja_donne -- ^ L’échantillon a déjà été donné ce tour-ci 
  deriving(Show, Eq, Enum)
type CErreur = CInt

instance ApiStorable Erreur where
  type ApiStorableType Erreur = CInt
  toStorable x f = f (fromIntegral (fromEnum x))
  {-# INLINE toStorable #-}
  unStorable = return . toEnum . fromIntegral
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Erreur = ApiStorableType Erreur
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
-- | Types d’actions
data Action_type =
    Action_placer -- ^ Action ``placer_echantillon`` 
  | Action_transmuter -- ^ Action ``transmuter`` 
  | Action_catalyser -- ^ Action ``catalyser`` 
  | Action_donner_echantillon -- ^ Action ``donner_echantillon`` 
  deriving(Show, Eq, Enum)
type CAction_type = CInt

instance ApiStorable Action_type where
  type ApiStorableType Action_type = CInt
  toStorable x f = f (fromIntegral (fromEnum x))
  {-# INLINE toStorable #-}
  unStorable = return . toEnum . fromIntegral
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Action_type = ApiStorableType Action_type
  toStorableBase = toStorable
  {-# INLINE toStorableBase #-}
  unStorableBase = unStorable
  {-# INLINE unStorableBase #-}
-- | Position sur la carte, donnée par deux coordonnées
data Position = Position Int Int
  deriving(Show, Eq)
data CPosition = CPosition CInt CInt
instance Storable CPosition where
  sizeOf    _ = (#size position)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    aligne <- (#peek position, ligne) ptr
    acolonne <- (#peek position, colonne) ptr
    return $ CPosition aligne acolonne
  {-# INLINE peek #-}
  poke ptr (CPosition aligne acolonne) = do
    (#poke position, ligne) ptr aligne
    (#poke position, colonne) ptr acolonne
  {-# INLINE poke #-}
instance ApiStorable Position where
  type ApiStorableType Position = Ptr CPosition
  toStorable (Position aligne acolonne) f = toStorableBase aligne $ \aligne' ->  toStorableBase acolonne $ \acolonne' ->  do
    alloca $ \ptr -> do
      poke ptr $ CPosition aligne' acolonne'
      f ptr
  {-# INLINE toStorable #-}
  unStorable ptr = do
    (CPosition aligne' acolonne') <- peek ptr
    aligne <- unStorableBase aligne'
    acolonne <- unStorableBase acolonne'
    return $ Position aligne acolonne
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Position = CPosition
  toStorableBase (Position aligne acolonne) f =
    toStorableBase aligne $ \aligne' ->  toStorableBase acolonne $ \acolonne' ->  f (CPosition aligne' acolonne')
  {-# INLINE toStorableBase #-}
  unStorableBase (CPosition aligne' acolonne') = do
    aligne <- unStorableBase aligne'
    acolonne <- unStorableBase acolonne'
    return $ Position aligne acolonne
  {-# INLINE unStorableBase #-}
-- | Échantillon, défini par deux types d’éléments
data Echantillon = Echantillon Case_type Case_type
  deriving(Show, Eq)
data CEchantillon = CEchantillon CCase_type CCase_type
instance Storable CEchantillon where
  sizeOf    _ = (#size echantillon)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    aelement1 <- (#peek echantillon, element1) ptr
    aelement2 <- (#peek echantillon, element2) ptr
    return $ CEchantillon aelement1 aelement2
  {-# INLINE peek #-}
  poke ptr (CEchantillon aelement1 aelement2) = do
    (#poke echantillon, element1) ptr aelement1
    (#poke echantillon, element2) ptr aelement2
  {-# INLINE poke #-}
instance ApiStorable Echantillon where
  type ApiStorableType Echantillon = Ptr CEchantillon
  toStorable (Echantillon aelement1 aelement2) f = toStorableBase aelement1 $ \aelement1' ->  toStorableBase aelement2 $ \aelement2' ->  do
    alloca $ \ptr -> do
      poke ptr $ CEchantillon aelement1' aelement2'
      f ptr
  {-# INLINE toStorable #-}
  unStorable ptr = do
    (CEchantillon aelement1' aelement2') <- peek ptr
    aelement1 <- unStorableBase aelement1'
    aelement2 <- unStorableBase aelement2'
    return $ Echantillon aelement1 aelement2
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Echantillon = CEchantillon
  toStorableBase (Echantillon aelement1 aelement2) f =
    toStorableBase aelement1 $ \aelement1' ->  toStorableBase aelement2 $ \aelement2' ->  f (CEchantillon aelement1' aelement2')
  {-# INLINE toStorableBase #-}
  unStorableBase (CEchantillon aelement1' aelement2') = do
    aelement1 <- unStorableBase aelement1'
    aelement2 <- unStorableBase aelement2'
    return $ Echantillon aelement1 aelement2
  {-# INLINE unStorableBase #-}
-- | Position d’un échantillon, donnée par deux positions adjacentes
data Position_echantillon = Position_echantillon Position Position
  deriving(Show, Eq)
data CPosition_echantillon = CPosition_echantillon CPosition CPosition
instance Storable CPosition_echantillon where
  sizeOf    _ = (#size position_echantillon)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    apos1 <- (#peek position_echantillon, pos1) ptr
    apos2 <- (#peek position_echantillon, pos2) ptr
    return $ CPosition_echantillon apos1 apos2
  {-# INLINE peek #-}
  poke ptr (CPosition_echantillon apos1 apos2) = do
    (#poke position_echantillon, pos1) ptr apos1
    (#poke position_echantillon, pos2) ptr apos2
  {-# INLINE poke #-}
instance ApiStorable Position_echantillon where
  type ApiStorableType Position_echantillon = Ptr CPosition_echantillon
  toStorable (Position_echantillon apos1 apos2) f = toStorableBase apos1 $ \apos1' ->  toStorableBase apos2 $ \apos2' ->  do
    alloca $ \ptr -> do
      poke ptr $ CPosition_echantillon apos1' apos2'
      f ptr
  {-# INLINE toStorable #-}
  unStorable ptr = do
    (CPosition_echantillon apos1' apos2') <- peek ptr
    apos1 <- unStorableBase apos1'
    apos2 <- unStorableBase apos2'
    return $ Position_echantillon apos1 apos2
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Position_echantillon = CPosition_echantillon
  toStorableBase (Position_echantillon apos1 apos2) f =
    toStorableBase apos1 $ \apos1' ->  toStorableBase apos2 $ \apos2' ->  f (CPosition_echantillon apos1' apos2')
  {-# INLINE toStorableBase #-}
  unStorableBase (CPosition_echantillon apos1' apos2') = do
    apos1 <- unStorableBase apos1'
    apos2 <- unStorableBase apos2'
    return $ Position_echantillon apos1 apos2
  {-# INLINE unStorableBase #-}
-- | Action représentée dans l’historique. L’action ``placer_echantillon`` utilise ``pos1`` et ``pos2``. L’action ``transmuter`` utilise ``pos1``. L’action ``catalyser`` utilise ``pos1``, ``id_apprenti`` et ``nouvelle_case``. L’action ``donner_echantillon`` n’est pas représentée dans l’historique, car ``echantillon_tour`` donne l’information.
data Action_hist = Action_hist {
      atype :: Action_type -- ^ Type de l’action
  ,   pos1 :: Position -- ^ Position, pour les actions placer (1er élément), transmuter et catalyser
  ,   pos2 :: Position -- ^ Position, pour l’action placer (2e élément)
  ,   id_apprenti :: Int -- ^ ID de l’apprenti, pour l’action catalyser
  ,   nouvelle_case :: Case_type -- ^ Élément pour l’action catalyser
}
  deriving(Show, Eq)
data CAction_hist = CAction_hist {
      catype :: CAction_type -- ^ Type de l’action
  ,   cpos1 :: CPosition -- ^ Position, pour les actions placer (1er élément), transmuter et catalyser
  ,   cpos2 :: CPosition -- ^ Position, pour l’action placer (2e élément)
  ,   cid_apprenti :: CInt -- ^ ID de l’apprenti, pour l’action catalyser
  ,   cnouvelle_case :: CCase_type -- ^ Élément pour l’action catalyser
}
instance Storable CAction_hist where
  sizeOf    _ = (#size action_hist)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    aatype <- (#peek action_hist, atype) ptr
    apos1 <- (#peek action_hist, pos1) ptr
    apos2 <- (#peek action_hist, pos2) ptr
    aid_apprenti <- (#peek action_hist, id_apprenti) ptr
    anouvelle_case <- (#peek action_hist, nouvelle_case) ptr
    return $ CAction_hist aatype apos1 apos2 aid_apprenti anouvelle_case
  {-# INLINE peek #-}
  poke ptr (CAction_hist aatype apos1 apos2 aid_apprenti anouvelle_case) = do
    (#poke action_hist, atype) ptr aatype
    (#poke action_hist, pos1) ptr apos1
    (#poke action_hist, pos2) ptr apos2
    (#poke action_hist, id_apprenti) ptr aid_apprenti
    (#poke action_hist, nouvelle_case) ptr anouvelle_case
  {-# INLINE poke #-}
instance ApiStorable Action_hist where
  type ApiStorableType Action_hist = Ptr CAction_hist
  toStorable (Action_hist aatype apos1 apos2 aid_apprenti anouvelle_case) f = toStorableBase aatype $ \aatype' ->  toStorableBase apos1 $ \apos1' ->  toStorableBase apos2 $ \apos2' ->  toStorableBase aid_apprenti $ \aid_apprenti' ->  toStorableBase anouvelle_case $ \anouvelle_case' ->  do
    alloca $ \ptr -> do
      poke ptr $ CAction_hist aatype' apos1' apos2' aid_apprenti' anouvelle_case'
      f ptr
  {-# INLINE toStorable #-}
  unStorable ptr = do
    (CAction_hist aatype' apos1' apos2' aid_apprenti' anouvelle_case') <- peek ptr
    aatype <- unStorableBase aatype'
    apos1 <- unStorableBase apos1'
    apos2 <- unStorableBase apos2'
    aid_apprenti <- unStorableBase aid_apprenti'
    anouvelle_case <- unStorableBase anouvelle_case'
    return $ Action_hist aatype apos1 apos2 aid_apprenti anouvelle_case
  {-# INLINE unStorable #-}
  type ApiStorableBaseType Action_hist = CAction_hist
  toStorableBase (Action_hist aatype apos1 apos2 aid_apprenti anouvelle_case) f =
    toStorableBase aatype $ \aatype' ->  toStorableBase apos1 $ \apos1' ->  toStorableBase apos2 $ \apos2' ->  toStorableBase aid_apprenti $ \aid_apprenti' ->  toStorableBase anouvelle_case $ \anouvelle_case' ->  f (CAction_hist aatype' apos1' apos2' aid_apprenti' anouvelle_case')
  {-# INLINE toStorableBase #-}
  unStorableBase (CAction_hist aatype' apos1' apos2' aid_apprenti' anouvelle_case') = do
    aatype <- unStorableBase aatype'
    apos1 <- unStorableBase apos1'
    apos2 <- unStorableBase apos2'
    aid_apprenti <- unStorableBase aid_apprenti'
    anouvelle_case <- unStorableBase anouvelle_case'
    return $ Action_hist aatype apos1 apos2 aid_apprenti anouvelle_case
  {-# INLINE unStorableBase #-}
data CPosition_array = CPosition_array { cPosition_arrayPtr :: Ptr CPosition, cPosition_arraySize :: CSize }

instance Storable CPosition_array where
  sizeOf    _ = (#size position_array)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    length <- (#peek position_array, length) ptr
    datas <- (#peek position_array, datas) ptr
    return $ CPosition_array datas length
  {-# INLINE peek #-}
  poke ptr (CPosition_array datas length) = do
    (#poke position_array, length) ptr length
    (#poke position_array, datas) ptr datas
  {-# INLINE poke #-}

instance ApiStorable [Position] where
  type ApiStorableType [Position] = Ptr CPosition_array
  toStorable xs f = toStorableBase xs $ \a -> alloca $ \ptr -> do
    poke ptr a
    f ptr
  {-# INLINE toStorable #-}
  unStorable xa = do
    (CPosition_array xa' xl) <- peek xa
    xs <- peekArray (fromIntegral xl) xa'
    mapM unStorableBase xs
  {-# INLINE unStorable #-}
  type ApiStorableBaseType [Position] = CPosition_array

  toStorableBase xs f = do
    let xl = length xs
    allocaArray xl $ \xa ->
      foldl'
        (\acc (i, c) -> toStorableBase c $ \c' -> do
          poke (advancePtr xa i) c'
          acc
        )
        (f $ CPosition_array xa (fromIntegral xl))
        (zip [0..] xs)
  {-# INLINE toStorableBase #-}
  unStorableBase (CPosition_array xa xl) = do
    xs <- peekArray (fromIntegral xl) xa
    mapM unStorableBase xs
  {-# INLINE unStorableBase #-}
data CPosition_echantillon_array = CPosition_echantillon_array { cPosition_echantillon_arrayPtr :: Ptr CPosition_echantillon, cPosition_echantillon_arraySize :: CSize }

instance Storable CPosition_echantillon_array where
  sizeOf    _ = (#size position_echantillon_array)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    length <- (#peek position_echantillon_array, length) ptr
    datas <- (#peek position_echantillon_array, datas) ptr
    return $ CPosition_echantillon_array datas length
  {-# INLINE peek #-}
  poke ptr (CPosition_echantillon_array datas length) = do
    (#poke position_echantillon_array, length) ptr length
    (#poke position_echantillon_array, datas) ptr datas
  {-# INLINE poke #-}

instance ApiStorable [Position_echantillon] where
  type ApiStorableType [Position_echantillon] = Ptr CPosition_echantillon_array
  toStorable xs f = toStorableBase xs $ \a -> alloca $ \ptr -> do
    poke ptr a
    f ptr
  {-# INLINE toStorable #-}
  unStorable xa = do
    (CPosition_echantillon_array xa' xl) <- peek xa
    xs <- peekArray (fromIntegral xl) xa'
    mapM unStorableBase xs
  {-# INLINE unStorable #-}
  type ApiStorableBaseType [Position_echantillon] = CPosition_echantillon_array

  toStorableBase xs f = do
    let xl = length xs
    allocaArray xl $ \xa ->
      foldl'
        (\acc (i, c) -> toStorableBase c $ \c' -> do
          poke (advancePtr xa i) c'
          acc
        )
        (f $ CPosition_echantillon_array xa (fromIntegral xl))
        (zip [0..] xs)
  {-# INLINE toStorableBase #-}
  unStorableBase (CPosition_echantillon_array xa xl) = do
    xs <- peekArray (fromIntegral xl) xa
    mapM unStorableBase xs
  {-# INLINE unStorableBase #-}
data CAction_hist_array = CAction_hist_array { cAction_hist_arrayPtr :: Ptr CAction_hist, cAction_hist_arraySize :: CSize }

instance Storable CAction_hist_array where
  sizeOf    _ = (#size action_hist_array)
  {-# INLINE sizeOf #-}
  alignment _ = alignment (undefined :: CInt)
  {-# INLINE alignment #-}
  peek ptr = do
    length <- (#peek action_hist_array, length) ptr
    datas <- (#peek action_hist_array, datas) ptr
    return $ CAction_hist_array datas length
  {-# INLINE peek #-}
  poke ptr (CAction_hist_array datas length) = do
    (#poke action_hist_array, length) ptr length
    (#poke action_hist_array, datas) ptr datas
  {-# INLINE poke #-}

instance ApiStorable [Action_hist] where
  type ApiStorableType [Action_hist] = Ptr CAction_hist_array
  toStorable xs f = toStorableBase xs $ \a -> alloca $ \ptr -> do
    poke ptr a
    f ptr
  {-# INLINE toStorable #-}
  unStorable xa = do
    (CAction_hist_array xa' xl) <- peek xa
    xs <- peekArray (fromIntegral xl) xa'
    mapM unStorableBase xs
  {-# INLINE unStorable #-}
  type ApiStorableBaseType [Action_hist] = CAction_hist_array

  toStorableBase xs f = do
    let xl = length xs
    allocaArray xl $ \xa ->
      foldl'
        (\acc (i, c) -> toStorableBase c $ \c' -> do
          poke (advancePtr xa i) c'
          acc
        )
        (f $ CAction_hist_array xa (fromIntegral xl))
        (zip [0..] xs)
  {-# INLINE toStorableBase #-}
  unStorableBase (CAction_hist_array xa xl) = do
    xs <- peekArray (fromIntegral xl) xa
    mapM unStorableBase xs
  {-# INLINE unStorableBase #-}
-- | Place l’échantillon du tour sur l’établi, avec les coordonnées de deux cases adjacentes.
placer_echantillon :: Position ->  Position -> IO Erreur
placer_echantillon pos1 pos2 = toStorable pos1 $ \pos1' ->  toStorable pos2 $ \pos2' ->  (hs_placer_echantillon pos1' pos2') >>= unStorable

foreign import ccall
  hs_placer_echantillon :: (ApiStorableType Position) -> (ApiStorableType Position) ->  IO (ApiStorableType Erreur)
-- | Provoque la transformation chimique de l’élément à la case ciblée, ainsi que tous les éléments adjacents du même type, ceux du même type adjacents à ces derniers, etc. Ils disparaissent alors tous dans leur transmutation en or ou en catalyseur.
transmuter :: Position -> IO Erreur
transmuter pos = toStorable pos $ \pos' ->  (hs_transmuter pos') >>= unStorable

foreign import ccall
  hs_transmuter :: (ApiStorableType Position) ->  IO (ApiStorableType Erreur)
-- | Utilise un catalyseur sur la case ciblée de l'apprenti indiqué. Transforme l’ancien élément en l’élément indiqué.
catalyser :: Position ->  Int ->  Case_type -> IO Erreur
catalyser pos id_apprenti terrain = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  toStorable terrain $ \terrain' ->  (hs_catalyser pos' id_apprenti' terrain') >>= unStorable

foreign import ccall
  hs_catalyser :: (ApiStorableType Position) -> (ApiStorableType Int) -> (ApiStorableType Case_type) ->  IO (ApiStorableType Erreur)
-- | Définit l’échantillon que l’adversaire recevra à son prochain tour.
donner_echantillon :: Echantillon -> IO Erreur
donner_echantillon echantillon_donne = toStorable echantillon_donne $ \echantillon_donne' ->  (hs_donner_echantillon echantillon_donne') >>= unStorable

foreign import ccall
  hs_donner_echantillon :: (ApiStorableType Echantillon) ->  IO (ApiStorableType Erreur)
-- | Renvoie le type d’une case donnée, ou 0 si la case est invaide.
type_case :: Position ->  Int -> IO Case_type
type_case pos id_apprenti = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_type_case pos' id_apprenti') >>= unStorable

foreign import ccall
  hs_type_case :: (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType Case_type)
-- | Indique si une case donnée est vide ou contient un élément. Renvoie faux en cas d'erreur.
est_vide :: Position ->  Int -> IO Bool
est_vide pos id_apprenti = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_est_vide pos' id_apprenti') >>= unStorable

foreign import ccall
  hs_est_vide :: (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType Bool)
-- | Renvoie la propriété de l’élément sur une case donnée. Un élément invalide n'a pas de propriété.
propriete_case :: Position ->  Int -> IO Element_propriete
propriete_case pos id_apprenti = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_propriete_case pos' id_apprenti') >>= unStorable

foreign import ccall
  hs_propriete_case :: (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType Element_propriete)
-- | Renvoie la propriété d’un type de case donné.
propriete_case_type :: Case_type -> IO Element_propriete
propriete_case_type ctype = toStorable ctype $ \ctype' ->  (hs_propriete_case_type ctype') >>= unStorable

foreign import ccall
  hs_propriete_case_type :: (ApiStorableType Case_type) ->  IO (ApiStorableType Element_propriete)
-- | Renvoie la taille de la région à laquelle appartient un élément. Renvoie -1 si la position est invalide.
taille_region :: Position ->  Int -> IO Int
taille_region pos id_apprenti = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_taille_region pos' id_apprenti') >>= unStorable

foreign import ccall
  hs_taille_region :: (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType Int)
-- | Renvoie la liste des positions des cases composant la région à laquelle appartient un élément donné. Renvoie une liste vide en cas d'erreur.
positions_region :: Position ->  Int -> IO [Position]
positions_region pos id_apprenti = toStorable pos $ \pos' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_positions_region pos' id_apprenti') >>= unStorable

foreign import ccall
  hs_positions_region :: (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType [Position])
-- | Détermine si le placement d’un échantillon est valide.
placement_possible_echantillon :: Echantillon ->  Position ->  Position ->  Int -> IO Bool
placement_possible_echantillon echantillon_a_placer pos1 pos2 id_apprenti = toStorable echantillon_a_placer $ \echantillon_a_placer' ->  toStorable pos1 $ \pos1' ->  toStorable pos2 $ \pos2' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_placement_possible_echantillon echantillon_a_placer' pos1' pos2' id_apprenti') >>= unStorable

foreign import ccall
  hs_placement_possible_echantillon :: (ApiStorableType Echantillon) -> (ApiStorableType Position) -> (ApiStorableType Position) -> (ApiStorableType Int) ->  IO (ApiStorableType Bool)
-- | Renvoie la liste des placements possibles pour un échantillon donné sur l’établi d’un apprenti donné. Renvoie une liste vide en cas d'erreur.
placements_possible_echantillon :: Echantillon ->  Int -> IO [Position_echantillon]
placements_possible_echantillon echantillon_a_placer id_apprenti = toStorable echantillon_a_placer $ \echantillon_a_placer' ->  toStorable id_apprenti $ \id_apprenti' ->  (hs_placements_possible_echantillon echantillon_a_placer' id_apprenti') >>= unStorable

foreign import ccall
  hs_placements_possible_echantillon :: (ApiStorableType Echantillon) -> (ApiStorableType Int) ->  IO (ApiStorableType [Position_echantillon])
-- | Renvoie la liste des actions jouées par l’adversaire pendant son tour, dans l’ordre chronologique.
historique :: IO [Action_hist]
historique  =  (hs_historique ) >>= unStorable

foreign import ccall
  hs_historique ::  IO (ApiStorableType [Action_hist])
-- | Renvoie votre numéro d’apprenti.
moi :: IO Int
moi  =  (hs_moi ) >>= unStorable

foreign import ccall
  hs_moi ::  IO (ApiStorableType Int)
-- | Renvoie le numéro d’apprenti de votre adversaire.
adversaire :: IO Int
adversaire  =  (hs_adversaire ) >>= unStorable

foreign import ccall
  hs_adversaire ::  IO (ApiStorableType Int)
-- | Renvoie la quantité d’or amassée par l’apprenti désigné par le numéro ``id_apprenti``. Renvoie 0 si ``id_apprenti`` est invalide (attention, le score d’un apprenti valide peut aussi être 0).
score :: Int -> IO Int
score id_apprenti = toStorable id_apprenti $ \id_apprenti' ->  (hs_score id_apprenti') >>= unStorable

foreign import ccall
  hs_score :: (ApiStorableType Int) ->  IO (ApiStorableType Int)
-- | Renvoie le numéro du tour actuel.
tour_actuel :: IO Int
tour_actuel  =  (hs_tour_actuel ) >>= unStorable

foreign import ccall
  hs_tour_actuel ::  IO (ApiStorableType Int)
-- | Annule la dernière action. Renvoie ``false`` quand il n’y a pas d’action à annuler ce tour-ci.
annuler :: IO Bool
annuler  =  (hs_annuler ) >>= unStorable

foreign import ccall
  hs_annuler ::  IO (ApiStorableType Bool)
-- | Indique le nombre de catalyseurs en votre possession.
nombre_catalyseurs :: IO Int
nombre_catalyseurs  =  (hs_nombre_catalyseurs ) >>= unStorable

foreign import ccall
  hs_nombre_catalyseurs ::  IO (ApiStorableType Int)
-- | Indique l’échantillon reçu pour ce tour.
echantillon_tour :: IO Echantillon
echantillon_tour  =  (hs_echantillon_tour ) >>= unStorable

foreign import ccall
  hs_echantillon_tour ::  IO (ApiStorableType Echantillon)
-- | Indique si l’échantillon reçu pour ce tour a déjà été posé.
a_pose_echantillon :: IO Bool
a_pose_echantillon  =  (hs_a_pose_echantillon ) >>= unStorable

foreign import ccall
  hs_a_pose_echantillon ::  IO (ApiStorableType Bool)
-- | Indique si un échantillon a déjà été donné ce tour.
a_donne_echantillon :: IO Bool
a_donne_echantillon  =  (hs_a_donne_echantillon ) >>= unStorable

foreign import ccall
  hs_a_donne_echantillon ::  IO (ApiStorableType Bool)
-- | Renvoie la quantité d’or (et donc le score) obtenue par la transmutation de ``taille_region`` éléments transmutables en or.
quantite_transmutation_or :: Int -> IO Int
quantite_transmutation_or taille_region = toStorable taille_region $ \taille_region' ->  (hs_quantite_transmutation_or taille_region') >>= unStorable

foreign import ccall
  hs_quantite_transmutation_or :: (ApiStorableType Int) ->  IO (ApiStorableType Int)
-- | Renvoie la quantité de catalyseurs obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
quantite_transmutation_catalyseur :: Int -> IO Int
quantite_transmutation_catalyseur taille_region = toStorable taille_region $ \taille_region' ->  (hs_quantite_transmutation_catalyseur taille_region') >>= unStorable

foreign import ccall
  hs_quantite_transmutation_catalyseur :: (ApiStorableType Int) ->  IO (ApiStorableType Int)
-- | Renvoie la quantité d’or obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
quantite_transmutation_catalyseur_or :: Int -> IO Int
quantite_transmutation_catalyseur_or taille_region = toStorable taille_region $ \taille_region' ->  (hs_quantite_transmutation_catalyseur_or taille_region') >>= unStorable

foreign import ccall
  hs_quantite_transmutation_catalyseur_or :: (ApiStorableType Int) ->  IO (ApiStorableType Int)
-- | Indique l’échantillon par défaut lors du premier tour
echantillon_defaut_premier_tour :: IO Echantillon
echantillon_defaut_premier_tour  =  (hs_echantillon_defaut_premier_tour ) >>= unStorable

foreign import ccall
  hs_echantillon_defaut_premier_tour ::  IO (ApiStorableType Echantillon)
-- | Affiche l'état actuel des deux établis dans la console.
afficher_etablis :: IO ()
afficher_etablis  =  (hs_afficher_etablis ) >>= unStorable

foreign import ccall
  hs_afficher_etablis ::  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type case_type
afficher_case_type :: Case_type -> IO ()
afficher_case_type v = toStorable v $ \v' ->  (hs_afficher_case_type v') >>= unStorable

foreign import ccall
  hs_afficher_case_type :: (ApiStorableType Case_type) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type element_propriete
afficher_element_propriete :: Element_propriete -> IO ()
afficher_element_propriete v = toStorable v $ \v' ->  (hs_afficher_element_propriete v') >>= unStorable

foreign import ccall
  hs_afficher_element_propriete :: (ApiStorableType Element_propriete) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type erreur
afficher_erreur :: Erreur -> IO ()
afficher_erreur v = toStorable v $ \v' ->  (hs_afficher_erreur v') >>= unStorable

foreign import ccall
  hs_afficher_erreur :: (ApiStorableType Erreur) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type action_type
afficher_action_type :: Action_type -> IO ()
afficher_action_type v = toStorable v $ \v' ->  (hs_afficher_action_type v') >>= unStorable

foreign import ccall
  hs_afficher_action_type :: (ApiStorableType Action_type) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type position
afficher_position :: Position -> IO ()
afficher_position v = toStorable v $ \v' ->  (hs_afficher_position v') >>= unStorable

foreign import ccall
  hs_afficher_position :: (ApiStorableType Position) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type echantillon
afficher_echantillon :: Echantillon -> IO ()
afficher_echantillon v = toStorable v $ \v' ->  (hs_afficher_echantillon v') >>= unStorable

foreign import ccall
  hs_afficher_echantillon :: (ApiStorableType Echantillon) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type position_echantillon
afficher_position_echantillon :: Position_echantillon -> IO ()
afficher_position_echantillon v = toStorable v $ \v' ->  (hs_afficher_position_echantillon v') >>= unStorable

foreign import ccall
  hs_afficher_position_echantillon :: (ApiStorableType Position_echantillon) ->  IO (ApiStorableType ())
-- | Affiche le contenu d'une valeur de type action_hist
afficher_action_hist :: Action_hist -> IO ()
afficher_action_hist v = toStorable v $ \v' ->  (hs_afficher_action_hist v') >>= unStorable

foreign import ccall
  hs_afficher_action_hist :: (ApiStorableType Action_hist) ->  IO (ApiStorableType ())
