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

#include "interface.hh"

static void _init_php();

template <typename Lang, typename Cxx>
Lang cxx2lang(Cxx in)
{
    return in.__if_that_triggers_an_error_there_is_a_problem;
}

template <>
zval cxx2lang<zval, int>(int in)
{
    zval x;
    ZVAL_LONG(&x, (long)in);
    return x;
}

template <>
zval cxx2lang<zval, bool>(bool in)
{
    zval x;
    ZVAL_BOOL(&x, in);
    return x;
}

template <>
zval cxx2lang<zval, double>(double in)
{
    zval x;
    ZVAL_DOUBLE(&x, in);
    return x;
}

template <>
zval cxx2lang<zval, std::string>(std::string in)
{
    zval x;
    ZVAL_STRINGL(&x, in.c_str(), in.length());
    return x;
}

template <typename Cxx>
zval cxx2lang_array(const std::vector<Cxx>& in)
{
    zval x;
    array_init(&x);

    size_t s = in.size();

    for (size_t i = 0; i < s; ++i) {
      zval tmp = cxx2lang<zval, Cxx>(in[i]);
      add_next_index_zval(&x, &tmp);
    }

    return x;
}

template <typename Lang, typename Cxx>
Cxx lang2cxx(Lang in)
{
    return in.__if_that_triggers_an_error_there_is_a_problem;
}

template <>
int lang2cxx<zval*, int>(zval* in)
{
    if (Z_TYPE_P(in) != IS_LONG) {
        zend_error(E_WARNING, "parameter should be an int");
        throw 42;
    }
    return (int)Z_LVAL_P(in);
}

template <>
double lang2cxx<zval*, double>(zval* in)
{
    if (Z_TYPE_P(in) != IS_DOUBLE) {
        zend_error(E_WARNING, "parameter should be a double");
        throw 42;
    }
    return (double)Z_DVAL_P(in);
}

template <>
bool lang2cxx<zval*, bool>(zval* in)
{
    if (Z_TYPE_P(in) != IS_TRUE && Z_TYPE_P(in) != IS_FALSE) {
        zend_error(E_WARNING, "parameter should be a boolean");
        throw 42;
    }
    return (bool)(Z_TYPE_P(in) == IS_TRUE);
}

template <>
std::string lang2cxx<zval*, std::string>(zval* in)
{
    if (Z_TYPE_P(in) != IS_STRING) {
        zend_error(E_WARNING, "parameter should be a string");
        throw 42;
    }
    return Z_STRVAL_P(in);
}

template <typename Cxx>
std::vector<Cxx> lang2cxx_array(zval* in)
{
    if (Z_TYPE_P(in) != IS_ARRAY) {
        zend_error(E_WARNING, "parameter should be an array");
        throw 42;
    }

    HashTable* ht = Z_ARRVAL_P(in);
    std::vector<Cxx> out;
    size_t s = zend_hash_num_elements(ht);

    for (size_t i = 0; i < s; ++i)
    {
        zval* v = zend_hash_index_find(ht, i);
        out.push_back(lang2cxx<zval*, Cxx>(v));
    }

    return out;
}
/// Types de cases
template <>
zval cxx2lang<zval, case_type>(case_type in)
{
    return cxx2lang<zval, int>((int)in);
}

template <>
case_type lang2cxx<zval*, case_type>(zval* in)
{
    return (case_type)lang2cxx<zval*, int>(in);
}

/// Types de propriétés des éléments
template <>
zval cxx2lang<zval, element_propriete>(element_propriete in)
{
    return cxx2lang<zval, int>((int)in);
}

template <>
element_propriete lang2cxx<zval*, element_propriete>(zval* in)
{
    return (element_propriete)lang2cxx<zval*, int>(in);
}

/// Erreurs possibles
template <>
zval cxx2lang<zval, erreur>(erreur in)
{
    return cxx2lang<zval, int>((int)in);
}

template <>
erreur lang2cxx<zval*, erreur>(zval* in)
{
    return (erreur)lang2cxx<zval*, int>(in);
}

/// Types d’actions
template <>
zval cxx2lang<zval, action_type>(action_type in)
{
    return cxx2lang<zval, int>((int)in);
}

template <>
action_type lang2cxx<zval*, action_type>(zval* in)
{
    return (action_type)lang2cxx<zval*, int>(in);
}

/// Position sur la carte, donnée par deux coordonnées
template <>
zval cxx2lang<zval, position>(position in)
{
    zval ret;
    zval tmp;
    array_init(&ret);
    tmp = (cxx2lang<zval, int>(in.ligne));
    add_assoc_zval(&ret, "ligne", &tmp);
    tmp = (cxx2lang<zval, int>(in.colonne));
    add_assoc_zval(&ret, "colonne", &tmp);
    return ret;
}

template <>
position lang2cxx<zval*, position>(zval* in)
{
    position out;
    if (Z_TYPE_P(in) != IS_ARRAY) {
        zend_error(E_WARNING, "parameter is not a structure");
        throw 42;
    }
    HashTable* ht = Z_ARRVAL_P(in);
    zval* tmp = NULL;
    tmp = zend_hash_str_find(ht, "ligne", 5);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"ligne\" of struct \"position\" not found");
        throw 42;
    }
    out.ligne = lang2cxx<zval*, int>(tmp);

    tmp = zend_hash_str_find(ht, "colonne", 7);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"colonne\" of struct \"position\" not found");
        throw 42;
    }
    out.colonne = lang2cxx<zval*, int>(tmp);

    return out;
}

/// Échantillon, défini par deux types d’éléments
template <>
zval cxx2lang<zval, echantillon>(echantillon in)
{
    zval ret;
    zval tmp;
    array_init(&ret);
    tmp = (cxx2lang<zval, case_type>(in.element1));
    add_assoc_zval(&ret, "element1", &tmp);
    tmp = (cxx2lang<zval, case_type>(in.element2));
    add_assoc_zval(&ret, "element2", &tmp);
    return ret;
}

template <>
echantillon lang2cxx<zval*, echantillon>(zval* in)
{
    echantillon out;
    if (Z_TYPE_P(in) != IS_ARRAY) {
        zend_error(E_WARNING, "parameter is not a structure");
        throw 42;
    }
    HashTable* ht = Z_ARRVAL_P(in);
    zval* tmp = NULL;
    tmp = zend_hash_str_find(ht, "element1", 8);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"element1\" of struct \"echantillon\" not found");
        throw 42;
    }
    out.element1 = lang2cxx<zval*, case_type>(tmp);

    tmp = zend_hash_str_find(ht, "element2", 8);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"element2\" of struct \"echantillon\" not found");
        throw 42;
    }
    out.element2 = lang2cxx<zval*, case_type>(tmp);

    return out;
}

/// Position d’un échantillon, donnée par deux positions adjacentes
template <>
zval cxx2lang<zval, position_echantillon>(position_echantillon in)
{
    zval ret;
    zval tmp;
    array_init(&ret);
    tmp = (cxx2lang<zval, position>(in.pos1));
    add_assoc_zval(&ret, "pos1", &tmp);
    tmp = (cxx2lang<zval, position>(in.pos2));
    add_assoc_zval(&ret, "pos2", &tmp);
    return ret;
}

template <>
position_echantillon lang2cxx<zval*, position_echantillon>(zval* in)
{
    position_echantillon out;
    if (Z_TYPE_P(in) != IS_ARRAY) {
        zend_error(E_WARNING, "parameter is not a structure");
        throw 42;
    }
    HashTable* ht = Z_ARRVAL_P(in);
    zval* tmp = NULL;
    tmp = zend_hash_str_find(ht, "pos1", 4);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"pos1\" of struct \"position_echantillon\" not found");
        throw 42;
    }
    out.pos1 = lang2cxx<zval*, position>(tmp);

    tmp = zend_hash_str_find(ht, "pos2", 4);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"pos2\" of struct \"position_echantillon\" not found");
        throw 42;
    }
    out.pos2 = lang2cxx<zval*, position>(tmp);

    return out;
}

/// 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.
template <>
zval cxx2lang<zval, action_hist>(action_hist in)
{
    zval ret;
    zval tmp;
    array_init(&ret);
    tmp = (cxx2lang<zval, action_type>(in.atype));
    add_assoc_zval(&ret, "atype", &tmp);
    tmp = (cxx2lang<zval, position>(in.pos1));
    add_assoc_zval(&ret, "pos1", &tmp);
    tmp = (cxx2lang<zval, position>(in.pos2));
    add_assoc_zval(&ret, "pos2", &tmp);
    tmp = (cxx2lang<zval, int>(in.id_apprenti));
    add_assoc_zval(&ret, "id_apprenti", &tmp);
    tmp = (cxx2lang<zval, case_type>(in.nouvelle_case));
    add_assoc_zval(&ret, "nouvelle_case", &tmp);
    return ret;
}

template <>
action_hist lang2cxx<zval*, action_hist>(zval* in)
{
    action_hist out;
    if (Z_TYPE_P(in) != IS_ARRAY) {
        zend_error(E_WARNING, "parameter is not a structure");
        throw 42;
    }
    HashTable* ht = Z_ARRVAL_P(in);
    zval* tmp = NULL;
    tmp = zend_hash_str_find(ht, "atype", 5);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"atype\" of struct \"action_hist\" not found");
        throw 42;
    }
    out.atype = lang2cxx<zval*, action_type>(tmp);

    tmp = zend_hash_str_find(ht, "pos1", 4);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"pos1\" of struct \"action_hist\" not found");
        throw 42;
    }
    out.pos1 = lang2cxx<zval*, position>(tmp);

    tmp = zend_hash_str_find(ht, "pos2", 4);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"pos2\" of struct \"action_hist\" not found");
        throw 42;
    }
    out.pos2 = lang2cxx<zval*, position>(tmp);

    tmp = zend_hash_str_find(ht, "id_apprenti", 11);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"id_apprenti\" of struct \"action_hist\" not found");
        throw 42;
    }
    out.id_apprenti = lang2cxx<zval*, int>(tmp);

    tmp = zend_hash_str_find(ht, "nouvelle_case", 13);
    if (tmp == NULL) {
        zend_error(E_WARNING, "field \"nouvelle_case\" of struct \"action_hist\" not found");
        throw 42;
    }
    out.nouvelle_case = lang2cxx<zval*, case_type>(tmp);

    return out;
}

/// Place l’échantillon du tour sur l’établi, avec les coordonnées de deux cases adjacentes.
PHP_FUNCTION(php_api_placer_echantillon)
{
    zval* _pos1;
    zval* _pos2;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos1, &_pos2) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, erreur>(api_placer_echantillon(lang2cxx<zval*, position>(_pos1), lang2cxx<zval*, position>(_pos2)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// 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.
PHP_FUNCTION(php_api_transmuter)
{
    zval* _pos;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_pos) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, erreur>(api_transmuter(lang2cxx<zval*, position>(_pos)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Utilise un catalyseur sur la case ciblée de l'apprenti indiqué. Transforme l’ancien élément en l’élément indiqué.
PHP_FUNCTION(php_api_catalyser)
{
    zval* _pos;
    zval* _id_apprenti;
    zval* _terrain;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &_pos, &_id_apprenti, &_terrain) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, erreur>(api_catalyser(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti), lang2cxx<zval*, case_type>(_terrain)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Définit l’échantillon que l’adversaire recevra à son prochain tour.
PHP_FUNCTION(php_api_donner_echantillon)
{
    zval* _echantillon_donne;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_echantillon_donne) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, erreur>(api_donner_echantillon(lang2cxx<zval*, echantillon>(_echantillon_donne)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie le type d’une case donnée, ou 0 si la case est invaide.
PHP_FUNCTION(php_api_type_case)
{
    zval* _pos;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, case_type>(api_type_case(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique si une case donnée est vide ou contient un élément. Renvoie faux en cas d'erreur.
PHP_FUNCTION(php_api_est_vide)
{
    zval* _pos;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, bool>(api_est_vide(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la propriété de l’élément sur une case donnée. Un élément invalide n'a pas de propriété.
PHP_FUNCTION(php_api_propriete_case)
{
    zval* _pos;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, element_propriete>(api_propriete_case(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la propriété d’un type de case donné.
PHP_FUNCTION(php_api_propriete_case_type)
{
    zval* _ctype;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_ctype) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, element_propriete>(api_propriete_case_type(lang2cxx<zval*, case_type>(_ctype)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la taille de la région à laquelle appartient un élément. Renvoie -1 si la position est invalide.
PHP_FUNCTION(php_api_taille_region)
{
    zval* _pos;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, int>(api_taille_region(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// 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.
PHP_FUNCTION(php_api_positions_region)
{
    zval* _pos;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_pos, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang_array(api_positions_region(lang2cxx<zval*, position>(_pos), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Détermine si le placement d’un échantillon est valide.
PHP_FUNCTION(php_api_placement_possible_echantillon)
{
    zval* _echantillon_a_placer;
    zval* _pos1;
    zval* _pos2;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzzz", &_echantillon_a_placer, &_pos1, &_pos2, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, bool>(api_placement_possible_echantillon(lang2cxx<zval*, echantillon>(_echantillon_a_placer), lang2cxx<zval*, position>(_pos1), lang2cxx<zval*, position>(_pos2), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// 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.
PHP_FUNCTION(php_api_placements_possible_echantillon)
{
    zval* _echantillon_a_placer;
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &_echantillon_a_placer, &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang_array(api_placements_possible_echantillon(lang2cxx<zval*, echantillon>(_echantillon_a_placer), lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la liste des actions jouées par l’adversaire pendant son tour, dans l’ordre chronologique.
PHP_FUNCTION(php_api_historique)
{
    try {
        zval ret = cxx2lang_array(api_historique());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie votre numéro d’apprenti.
PHP_FUNCTION(php_api_moi)
{
    try {
        zval ret = cxx2lang<zval, int>(api_moi());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie le numéro d’apprenti de votre adversaire.
PHP_FUNCTION(php_api_adversaire)
{
    try {
        zval ret = cxx2lang<zval, int>(api_adversaire());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// 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).
PHP_FUNCTION(php_api_score)
{
    zval* _id_apprenti;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_id_apprenti) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, int>(api_score(lang2cxx<zval*, int>(_id_apprenti)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie le numéro du tour actuel.
PHP_FUNCTION(php_api_tour_actuel)
{
    try {
        zval ret = cxx2lang<zval, int>(api_tour_actuel());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Annule la dernière action. Renvoie ``false`` quand il n’y a pas d’action à annuler ce tour-ci.
PHP_FUNCTION(php_api_annuler)
{
    try {
        zval ret = cxx2lang<zval, bool>(api_annuler());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique le nombre de catalyseurs en votre possession.
PHP_FUNCTION(php_api_nombre_catalyseurs)
{
    try {
        zval ret = cxx2lang<zval, int>(api_nombre_catalyseurs());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique l’échantillon reçu pour ce tour.
PHP_FUNCTION(php_api_echantillon_tour)
{
    try {
        zval ret = cxx2lang<zval, echantillon>(api_echantillon_tour());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique si l’échantillon reçu pour ce tour a déjà été posé.
PHP_FUNCTION(php_api_a_pose_echantillon)
{
    try {
        zval ret = cxx2lang<zval, bool>(api_a_pose_echantillon());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique si un échantillon a déjà été donné ce tour.
PHP_FUNCTION(php_api_a_donne_echantillon)
{
    try {
        zval ret = cxx2lang<zval, bool>(api_a_donne_echantillon());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la quantité d’or (et donc le score) obtenue par la transmutation de ``taille_region`` éléments transmutables en or.
PHP_FUNCTION(php_api_quantite_transmutation_or)
{
    zval* _taille_region;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_taille_region) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, int>(api_quantite_transmutation_or(lang2cxx<zval*, int>(_taille_region)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la quantité de catalyseurs obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
PHP_FUNCTION(php_api_quantite_transmutation_catalyseur)
{
    zval* _taille_region;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_taille_region) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, int>(api_quantite_transmutation_catalyseur(lang2cxx<zval*, int>(_taille_region)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Renvoie la quantité d’or obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
PHP_FUNCTION(php_api_quantite_transmutation_catalyseur_or)
{
    zval* _taille_region;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_taille_region) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
        zval ret = cxx2lang<zval, int>(api_quantite_transmutation_catalyseur_or(lang2cxx<zval*, int>(_taille_region)));
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Indique l’échantillon par défaut lors du premier tour
PHP_FUNCTION(php_api_echantillon_defaut_premier_tour)
{
    try {
        zval ret = cxx2lang<zval, echantillon>(api_echantillon_defaut_premier_tour());
        RETURN_ZVAL(&ret, 0, 0);
    } catch (...) { RETURN_NULL(); }
}

/// Affiche l'état actuel des deux établis dans la console.
PHP_FUNCTION(php_api_afficher_etablis)
{
    try {
api_afficher_etablis();
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type case_type
PHP_FUNCTION(php_api_afficher_case_type)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_case_type(lang2cxx<zval*, case_type>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type element_propriete
PHP_FUNCTION(php_api_afficher_element_propriete)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_element_propriete(lang2cxx<zval*, element_propriete>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type erreur
PHP_FUNCTION(php_api_afficher_erreur)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_erreur(lang2cxx<zval*, erreur>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type action_type
PHP_FUNCTION(php_api_afficher_action_type)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_action_type(lang2cxx<zval*, action_type>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type position
PHP_FUNCTION(php_api_afficher_position)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_position(lang2cxx<zval*, position>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type echantillon
PHP_FUNCTION(php_api_afficher_echantillon)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_echantillon(lang2cxx<zval*, echantillon>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type position_echantillon
PHP_FUNCTION(php_api_afficher_position_echantillon)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_position_echantillon(lang2cxx<zval*, position_echantillon>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

/// Affiche le contenu d'une valeur de type action_hist
PHP_FUNCTION(php_api_afficher_action_hist)
{
    zval* _v;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &_v) == FAILURE)
    {
        RETURN_NULL();
    }

    try {
api_afficher_action_hist(lang2cxx<zval*, action_hist>(_v));
    RETURN_NULL();
    } catch (...) { RETURN_NULL(); }
}

static zend_function_entry module_functions_table[] = {
    PHP_FALIAS(placer_echantillon, php_api_placer_echantillon, NULL)    PHP_FALIAS(transmuter, php_api_transmuter, NULL)    PHP_FALIAS(catalyser, php_api_catalyser, NULL)    PHP_FALIAS(donner_echantillon, php_api_donner_echantillon, NULL)    PHP_FALIAS(type_case, php_api_type_case, NULL)    PHP_FALIAS(est_vide, php_api_est_vide, NULL)    PHP_FALIAS(propriete_case, php_api_propriete_case, NULL)    PHP_FALIAS(propriete_case_type, php_api_propriete_case_type, NULL)    PHP_FALIAS(taille_region, php_api_taille_region, NULL)    PHP_FALIAS(positions_region, php_api_positions_region, NULL)    PHP_FALIAS(placement_possible_echantillon, php_api_placement_possible_echantillon, NULL)    PHP_FALIAS(placements_possible_echantillon, php_api_placements_possible_echantillon, NULL)    PHP_FALIAS(historique, php_api_historique, NULL)    PHP_FALIAS(moi, php_api_moi, NULL)    PHP_FALIAS(adversaire, php_api_adversaire, NULL)    PHP_FALIAS(score, php_api_score, NULL)    PHP_FALIAS(tour_actuel, php_api_tour_actuel, NULL)    PHP_FALIAS(annuler, php_api_annuler, NULL)    PHP_FALIAS(nombre_catalyseurs, php_api_nombre_catalyseurs, NULL)    PHP_FALIAS(echantillon_tour, php_api_echantillon_tour, NULL)    PHP_FALIAS(a_pose_echantillon, php_api_a_pose_echantillon, NULL)    PHP_FALIAS(a_donne_echantillon, php_api_a_donne_echantillon, NULL)    PHP_FALIAS(quantite_transmutation_or, php_api_quantite_transmutation_or, NULL)    PHP_FALIAS(quantite_transmutation_catalyseur, php_api_quantite_transmutation_catalyseur, NULL)    PHP_FALIAS(quantite_transmutation_catalyseur_or, php_api_quantite_transmutation_catalyseur_or, NULL)    PHP_FALIAS(echantillon_defaut_premier_tour, php_api_echantillon_defaut_premier_tour, NULL)    PHP_FALIAS(afficher_etablis, php_api_afficher_etablis, NULL)    PHP_FALIAS(afficher_case_type, php_api_afficher_case_type, NULL)    PHP_FALIAS(afficher_element_propriete, php_api_afficher_element_propriete, NULL)    PHP_FALIAS(afficher_erreur, php_api_afficher_erreur, NULL)    PHP_FALIAS(afficher_action_type, php_api_afficher_action_type, NULL)    PHP_FALIAS(afficher_position, php_api_afficher_position, NULL)    PHP_FALIAS(afficher_echantillon, php_api_afficher_echantillon, NULL)    PHP_FALIAS(afficher_position_echantillon, php_api_afficher_position_echantillon, NULL)    PHP_FALIAS(afficher_action_hist, php_api_afficher_action_hist, NULL)    {NULL, NULL, NULL}
};
static zend_module_entry api_module_entry = {
    STANDARD_MODULE_HEADER,
    "api",
    module_functions_table,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "1.0",
    STANDARD_MODULE_PROPERTIES
};

static void _init_php()
{
    static int initialized = 0;
    if (initialized)
        return;
    initialized = 1;

    char* argv[] = { "champion", NULL };
    char buffer[1024];
    const char* path;
    zend_file_handle script;

    path = getenv("CHAMPION_PATH");
    if (!path)
        path = ".";

    snprintf(buffer, 1024, "include('%s/%s.php');", path, "prologin");

    php_embed_init(1, argv);
    zend_startup_module(&api_module_entry);
    zend_eval_string(buffer, NULL, "PHP to Stechec interface");
}

/// Fonction appelée au début de la partie.
extern "C" void partie_init()
{
    zval ret;
    zval fname;
    _init_php();

    ZVAL_STRING(&fname, "partie_init");
    if (call_user_function(EG(function_table), NULL, &fname, &ret, 0, NULL TSRMLS_CC) == FAILURE)
    {
        abort();
    }
}

/// Fonction appelée à chaque tour.
extern "C" void jouer_tour()
{
    zval ret;
    zval fname;
    _init_php();

    ZVAL_STRING(&fname, "jouer_tour");
    if (call_user_function(EG(function_table), NULL, &fname, &ret, 0, NULL TSRMLS_CC) == FAILURE)
    {
        abort();
    }
}

/// Fonction appelée à la fin de la partie.
extern "C" void partie_fin()
{
    zval ret;
    zval fname;
    _init_php();

    ZVAL_STRING(&fname, "partie_fin");
    if (call_user_function(EG(function_table), NULL, &fname, &ret, 0, NULL TSRMLS_CC) == FAILURE)
    {
        abort();
    }
}

