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

#include "interface.hh"
#include <cstdlib>

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

template<>
std::string lang2cxx<char*, std::string>(char* in)
{
  return in;
}

template<typename Lang, typename Lang_array, typename Cxx>
std::vector<Cxx> lang2cxx_array(Lang_array in)
{
  std::vector<Cxx> out(in.length);
  for (size_t i = 0; i < in.length; ++i)
    out[i] = lang2cxx<Lang, Cxx>(in.datas[i]);
  return out;
}

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

template<>
char* cxx2lang<char*, std::string>(std::string in)
{
  size_t l = in.length();
  char* out = (char *) malloc(l + 1);
  for (int i = 0; i < l; i++) out[i] = in[i];
  out[l] = 0;
  return out;
}

template<typename Lang, typename Lang_array, typename Cxx>
Lang_array cxx2lang_array(const std::vector<Cxx>& in)
{
  Lang_array out = { NULL, in.size() };
  out.datas = (Lang *)malloc((out.length) * sizeof(Lang));
  for (int i = 0; i < out.length; ++i)
    out.datas[i] = cxx2lang<Lang, Cxx>(in[i]);
  return out;
}
/// Position sur la carte, donnée par deux coordonnées
template<>
__internal__cxx__position lang2cxx<position, __internal__cxx__position>(position in)
{
  __internal__cxx__position out;
  out.ligne = lang2cxx<int, int >(in.ligne);
  out.colonne = lang2cxx<int, int >(in.colonne);
  return out;
}

template<>
position cxx2lang<position, __internal__cxx__position>(__internal__cxx__position in)
{
  position out;
  out.ligne = cxx2lang<int, int >(in.ligne);
  out.colonne = cxx2lang<int, int >(in.colonne);
  return out;
}


/// Échantillon, défini par deux types d’éléments
template<>
__internal__cxx__echantillon lang2cxx<echantillon, __internal__cxx__echantillon>(echantillon in)
{
  __internal__cxx__echantillon out;
  out.element1 = lang2cxx<case_type, case_type >(in.element1);
  out.element2 = lang2cxx<case_type, case_type >(in.element2);
  return out;
}

template<>
echantillon cxx2lang<echantillon, __internal__cxx__echantillon>(__internal__cxx__echantillon in)
{
  echantillon out;
  out.element1 = cxx2lang<case_type, case_type >(in.element1);
  out.element2 = cxx2lang<case_type, case_type >(in.element2);
  return out;
}


/// Position d’un échantillon, donnée par deux positions adjacentes
template<>
__internal__cxx__position_echantillon lang2cxx<position_echantillon, __internal__cxx__position_echantillon>(position_echantillon in)
{
  __internal__cxx__position_echantillon out;
  out.pos1 = lang2cxx<position, __internal__cxx__position >(in.pos1);
  out.pos2 = lang2cxx<position, __internal__cxx__position >(in.pos2);
  return out;
}

template<>
position_echantillon cxx2lang<position_echantillon, __internal__cxx__position_echantillon>(__internal__cxx__position_echantillon in)
{
  position_echantillon out;
  out.pos1 = cxx2lang<position, __internal__cxx__position >(in.pos1);
  out.pos2 = cxx2lang<position, __internal__cxx__position >(in.pos2);
  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<>
__internal__cxx__action_hist lang2cxx<action_hist, __internal__cxx__action_hist>(action_hist in)
{
  __internal__cxx__action_hist out;
  out.atype = lang2cxx<action_type, action_type >(in.atype);
  out.pos1 = lang2cxx<position, __internal__cxx__position >(in.pos1);
  out.pos2 = lang2cxx<position, __internal__cxx__position >(in.pos2);
  out.id_apprenti = lang2cxx<int, int >(in.id_apprenti);
  out.nouvelle_case = lang2cxx<case_type, case_type >(in.nouvelle_case);
  return out;
}

template<>
action_hist cxx2lang<action_hist, __internal__cxx__action_hist>(__internal__cxx__action_hist in)
{
  action_hist out;
  out.atype = cxx2lang<action_type, action_type >(in.atype);
  out.pos1 = cxx2lang<position, __internal__cxx__position >(in.pos1);
  out.pos2 = cxx2lang<position, __internal__cxx__position >(in.pos2);
  out.id_apprenti = cxx2lang<int, int >(in.id_apprenti);
  out.nouvelle_case = cxx2lang<case_type, case_type >(in.nouvelle_case);
  return out;
}


extern "C" {
/// Place l’échantillon du tour sur l’établi, avec les coordonnées de deux cases adjacentes.
erreur placer_echantillon(position pos1, position pos2)
{
  return cxx2lang<erreur, erreur >(api_placer_echantillon(lang2cxx<position, __internal__cxx__position >(pos1), lang2cxx<position, __internal__cxx__position >(pos2)));
}


/// 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.
erreur transmuter(position pos)
{
  return cxx2lang<erreur, erreur >(api_transmuter(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Utilise un catalyseur sur la case ciblée de l'apprenti indiqué. Transforme l’ancien élément en l’élément indiqué.
erreur catalyser(position pos, int id_apprenti, case_type terrain)
{
  return cxx2lang<erreur, erreur >(api_catalyser(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti), lang2cxx<case_type, case_type >(terrain)));
}


/// Définit l’échantillon que l’adversaire recevra à son prochain tour.
erreur donner_echantillon(echantillon echantillon_donne)
{
  return cxx2lang<erreur, erreur >(api_donner_echantillon(lang2cxx<echantillon, __internal__cxx__echantillon >(echantillon_donne)));
}


/// Renvoie le type d’une case donnée, ou 0 si la case est invaide.
case_type type_case(position pos, int id_apprenti)
{
  return cxx2lang<case_type, case_type >(api_type_case(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti)));
}


/// Indique si une case donnée est vide ou contient un élément. Renvoie faux en cas d'erreur.
bool est_vide(position pos, int id_apprenti)
{
  return cxx2lang<bool, bool >(api_est_vide(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti)));
}


/// Renvoie la propriété de l’élément sur une case donnée. Un élément invalide n'a pas de propriété.
element_propriete propriete_case(position pos, int id_apprenti)
{
  return cxx2lang<element_propriete, element_propriete >(api_propriete_case(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti)));
}


/// Renvoie la propriété d’un type de case donné.
element_propriete propriete_case_type(case_type ctype)
{
  return cxx2lang<element_propriete, element_propriete >(api_propriete_case_type(lang2cxx<case_type, case_type >(ctype)));
}


/// Renvoie la taille de la région à laquelle appartient un élément. Renvoie -1 si la position est invalide.
int taille_region(position pos, int id_apprenti)
{
  return cxx2lang<int, int >(api_taille_region(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti)));
}


/// 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.
position_array positions_region(position pos, int id_apprenti)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_positions_region(lang2cxx<position, __internal__cxx__position >(pos), lang2cxx<int, int >(id_apprenti)));
}


/// Détermine si le placement d’un échantillon est valide.
bool placement_possible_echantillon(echantillon echantillon_a_placer, position pos1, position pos2, int id_apprenti)
{
  return cxx2lang<bool, bool >(api_placement_possible_echantillon(lang2cxx<echantillon, __internal__cxx__echantillon >(echantillon_a_placer), lang2cxx<position, __internal__cxx__position >(pos1), lang2cxx<position, __internal__cxx__position >(pos2), lang2cxx<int, int >(id_apprenti)));
}


/// 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.
position_echantillon_array placements_possible_echantillon(echantillon echantillon_a_placer, int id_apprenti)
{
  return cxx2lang_array<position_echantillon, position_echantillon_array, __internal__cxx__position_echantillon >(api_placements_possible_echantillon(lang2cxx<echantillon, __internal__cxx__echantillon >(echantillon_a_placer), lang2cxx<int, int >(id_apprenti)));
}


/// Renvoie la liste des actions jouées par l’adversaire pendant son tour, dans l’ordre chronologique.
action_hist_array historique(void)
{
  return cxx2lang_array<action_hist, action_hist_array, __internal__cxx__action_hist >(api_historique());
}


/// Renvoie votre numéro d’apprenti.
int moi(void)
{
  return cxx2lang<int, int >(api_moi());
}


/// Renvoie le numéro d’apprenti de votre adversaire.
int adversaire(void)
{
  return cxx2lang<int, int >(api_adversaire());
}


/// 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).
int score(int id_apprenti)
{
  return cxx2lang<int, int >(api_score(lang2cxx<int, int >(id_apprenti)));
}


/// Renvoie le numéro du tour actuel.
int tour_actuel(void)
{
  return cxx2lang<int, int >(api_tour_actuel());
}


/// Annule la dernière action. Renvoie ``false`` quand il n’y a pas d’action à annuler ce tour-ci.
bool annuler(void)
{
  return cxx2lang<bool, bool >(api_annuler());
}


/// Indique le nombre de catalyseurs en votre possession.
int nombre_catalyseurs(void)
{
  return cxx2lang<int, int >(api_nombre_catalyseurs());
}


/// Indique l’échantillon reçu pour ce tour.
echantillon echantillon_tour(void)
{
  return cxx2lang<echantillon, __internal__cxx__echantillon >(api_echantillon_tour());
}


/// Indique si l’échantillon reçu pour ce tour a déjà été posé.
bool a_pose_echantillon(void)
{
  return cxx2lang<bool, bool >(api_a_pose_echantillon());
}


/// Indique si un échantillon a déjà été donné ce tour.
bool a_donne_echantillon(void)
{
  return cxx2lang<bool, bool >(api_a_donne_echantillon());
}


/// Renvoie la quantité d’or (et donc le score) obtenue par la transmutation de ``taille_region`` éléments transmutables en or.
int quantite_transmutation_or(int taille_region)
{
  return cxx2lang<int, int >(api_quantite_transmutation_or(lang2cxx<int, int >(taille_region)));
}


/// Renvoie la quantité de catalyseurs obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
int quantite_transmutation_catalyseur(int taille_region)
{
  return cxx2lang<int, int >(api_quantite_transmutation_catalyseur(lang2cxx<int, int >(taille_region)));
}


/// Renvoie la quantité d’or obtenue par la transmutation de ``taille_region`` éléments transmutables en catalyseur.
int quantite_transmutation_catalyseur_or(int taille_region)
{
  return cxx2lang<int, int >(api_quantite_transmutation_catalyseur_or(lang2cxx<int, int >(taille_region)));
}


/// Indique l’échantillon par défaut lors du premier tour
echantillon echantillon_defaut_premier_tour(void)
{
  return cxx2lang<echantillon, __internal__cxx__echantillon >(api_echantillon_defaut_premier_tour());
}


/// Affiche l'état actuel des deux établis dans la console.
void afficher_etablis(void)
{
  api_afficher_etablis();
}


/// Affiche le contenu d'une valeur de type case_type
void afficher_case_type(case_type v)
{
  api_afficher_case_type(lang2cxx<case_type, case_type >(v));
}


/// Affiche le contenu d'une valeur de type element_propriete
void afficher_element_propriete(element_propriete v)
{
  api_afficher_element_propriete(lang2cxx<element_propriete, element_propriete >(v));
}


/// Affiche le contenu d'une valeur de type erreur
void afficher_erreur(erreur v)
{
  api_afficher_erreur(lang2cxx<erreur, erreur >(v));
}


/// Affiche le contenu d'une valeur de type action_type
void afficher_action_type(action_type v)
{
  api_afficher_action_type(lang2cxx<action_type, action_type >(v));
}


/// Affiche le contenu d'une valeur de type position
void afficher_position(position v)
{
  api_afficher_position(lang2cxx<position, __internal__cxx__position >(v));
}


/// Affiche le contenu d'une valeur de type echantillon
void afficher_echantillon(echantillon v)
{
  api_afficher_echantillon(lang2cxx<echantillon, __internal__cxx__echantillon >(v));
}


/// Affiche le contenu d'une valeur de type position_echantillon
void afficher_position_echantillon(position_echantillon v)
{
  api_afficher_position_echantillon(lang2cxx<position_echantillon, __internal__cxx__position_echantillon >(v));
}


/// Affiche le contenu d'une valeur de type action_hist
void afficher_action_hist(action_hist v)
{
  api_afficher_action_hist(lang2cxx<action_hist, __internal__cxx__action_hist >(v));
}


}
