/// 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.x = lang2cxx<int, int >(in.x);
  out.y = lang2cxx<int, int >(in.y);
  return out;
}

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


/// Représente un pulsar existant.
template<>
__internal__cxx__pulsar_info lang2cxx<pulsar_info, __internal__cxx__pulsar_info>(pulsar_info in)
{
  __internal__cxx__pulsar_info out;
  out.periode = lang2cxx<int, int >(in.periode);
  out.puissance = lang2cxx<double, double >(in.puissance);
  out.pulsations_restantes = lang2cxx<int, int >(in.pulsations_restantes);
  out.pulsations_totales = lang2cxx<int, int >(in.pulsations_totales);
  return out;
}

template<>
pulsar_info cxx2lang<pulsar_info, __internal__cxx__pulsar_info>(__internal__cxx__pulsar_info in)
{
  pulsar_info out;
  out.periode = cxx2lang<int, int >(in.periode);
  out.puissance = cxx2lang<double, double >(in.puissance);
  out.pulsations_restantes = cxx2lang<int, int >(in.pulsations_restantes);
  out.pulsations_totales = cxx2lang<int, int >(in.pulsations_totales);
  return out;
}


extern "C" {
/// Construit un tuyau sur une case donnée.
erreur construire(position pos)
{
  return cxx2lang<erreur, erreur >(api_construire(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Améliore un tuyau en Super Tuyau™.
erreur ameliorer(position pos)
{
  return cxx2lang<erreur, erreur >(api_ameliorer(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Détruit un tuyau sur une case donnée.
erreur detruire(position pos)
{
  return cxx2lang<erreur, erreur >(api_detruire(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Déplace une unité de puissance d'aspiration d'une case de votre base vers une autre.
erreur deplacer_aspiration(position source, position destination)
{
  return cxx2lang<erreur, erreur >(api_deplacer_aspiration(lang2cxx<position, __internal__cxx__position >(source), lang2cxx<position, __internal__cxx__position >(destination)));
}


/// Déblaye une case de débris.
erreur deblayer(position pos)
{
  return cxx2lang<erreur, erreur >(api_deblayer(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie le type d'une case donnée.
case_type type_case(position pos)
{
  return cxx2lang<case_type, case_type >(api_type_case(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie la liste de tous les pulsars présents.
position_array liste_pulsars(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_pulsars());
}


/// Renvoie la liste des cases contenant du plasma.
position_array liste_plasmas(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_plasmas());
}


/// Renvoie la liste des cases contenant un tuyau ou Super Tuyau™.
position_array liste_tuyaux(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_tuyaux());
}


/// Renvoie la liste des cases contenant un Super Tuyau™.
position_array liste_super_tuyaux(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_super_tuyaux());
}


/// Renvoie la liste des cases contenant des débris.
position_array liste_debris(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_liste_debris());
}


/// Renvoie vrai si et seulement si la case contient un pulsar.
bool est_pulsar(position pos)
{
  return cxx2lang<bool, bool >(api_est_pulsar(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie vrai si et seulement si la case contient un tuyau ou un Super Tuyau™.
bool est_tuyau(position pos)
{
  return cxx2lang<bool, bool >(api_est_tuyau(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie vrai si et seulement si la case contient un simple tuyau.
bool est_simple_tuyau(position pos)
{
  return cxx2lang<bool, bool >(api_est_simple_tuyau(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie vrai si et seulement si la case contient un Super Tuyau™.
bool est_super_tuyau(position pos)
{
  return cxx2lang<bool, bool >(api_est_super_tuyau(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie vrai si et seulement si la case contient un débris.
bool est_debris(position pos)
{
  return cxx2lang<bool, bool >(api_est_debris(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie vrai si et seulement s'il est possible de construire sur cette case.
bool est_libre(position pos)
{
  return cxx2lang<bool, bool >(api_est_libre(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie les informations propres au pulsar à la position donnée.
pulsar_info info_pulsar(position pos)
{
  return cxx2lang<pulsar_info, __internal__cxx__pulsar_info >(api_info_pulsar(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie la quantité de plasma sur une case donnée.
double charges_presentes(position pos)
{
  return cxx2lang<double, double >(api_charges_presentes(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie le numéro du joueur ayant dernièrement construit ou amélioré un tuyau sur une case.
int constructeur_tuyau(position pos)
{
  return cxx2lang<int, int >(api_constructeur_tuyau(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie le numéro du propriétaire d'une case de base.
int proprietaire_base(position pos)
{
  return cxx2lang<int, int >(api_proprietaire_base(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie la liste des cases composant votre base.
position_array ma_base(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_ma_base());
}


/// Renvoie la liste des cases composant la base de votre ennemi.
position_array base_ennemie(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_base_ennemie());
}


/// Renvoie la puissance d'aspiration d'une case de base donnée. Renvoie -1 si la position n'est pas celle d'une base.
int puissance_aspiration(position pos)
{
  return cxx2lang<int, int >(api_puissance_aspiration(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie pour une case donnée la liste des cases vers lesquelles le plasma se propagera. Renvoie la liste vide si la case n'est pas une case contenant un tuyau ou si elle n'est reliée à aucune base.
position_array directions_plasma(position pos)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_directions_plasma(lang2cxx<position, __internal__cxx__position >(pos)));
}


/// Renvoie la valeur du coût de la prochaine modification de vos puissances d'aspiration.
int cout_prochaine_modification_aspiration(void)
{
  return cxx2lang<int, int >(api_cout_prochaine_modification_aspiration());
}


/// Renvoie la liste des tuyaux construits par votre adversaire au dernier tour.
position_array hist_tuyaux_construits(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_tuyaux_construits());
}


/// Renvoie la liste des tuyaux détruits par votre adversaire au dernier tour.
position_array hist_tuyaux_detruits(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_tuyaux_detruits());
}


/// Renvoie la liste des tuyaux améliorés par votre adversaire au dernier tour.
position_array hist_tuyaux_ameliores(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_tuyaux_ameliores());
}


/// Renvoie la liste des débris déblayés par votre adversaire au dernier tour.
position_array hist_debris_deblayes(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_debris_deblayes());
}


/// Renvoie la liste des cases de base de votre adversaire qui ont reçu un point d'aspiration (une même case peut apparaître plusieurs fois).
position_array hist_points_aspiration_ajoutes(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_points_aspiration_ajoutes());
}


/// Renvoie la liste des cases de base de votre adversaire qui ont perdu un point d'aspiration (une même case peut apparaître plusieurs fois).
position_array hist_points_aspiration_retires(void)
{
  return cxx2lang_array<position, position_array, __internal__cxx__position >(api_hist_points_aspiration_retires());
}


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


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


/// Indique votre nombre de points d'actions restants pour ce tour-ci.
int points_action(void)
{
  return cxx2lang<int, int >(api_points_action());
}


/// Renvoie le score du joueur désigné par le numéro ``id_joueur``. Renvoie -1 si ``id_joueur`` est invalide.
int score(int id_joueur)
{
  return cxx2lang<int, int >(api_score(lang2cxx<int, int >(id_joueur)));
}


/// 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());
}


/// 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 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 position
void afficher_position(position v)
{
  api_afficher_position(lang2cxx<position, __internal__cxx__position >(v));
}


/// Affiche le contenu d'une valeur de type pulsar_info
void afficher_pulsar_info(pulsar_info v)
{
  api_afficher_pulsar_info(lang2cxx<pulsar_info, __internal__cxx__pulsar_info >(v));
}


}
