/// 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

#include "HsFFI.h"
extern "C" {
  void hs_partie_init(void);
  void hs_jouer_tour(void);
  void hs_partie_fin(void);
  extern void __attribute__((weak)) __stginit_Prologin ( void );
}
#include "interface.hh"

extern "C" void haskell_init(){
  static bool done = false;
  if(!done){
    hs_init(0, 0);
    hs_add_root(__stginit_Prologin);
    done = true;
  }
}
static std::vector<void*> __internal_need_free;

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 Lang_array, typename Cxx>
std::vector<Cxx> lang2cxx_array_ptr(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);
  __internal_need_free.push_back(out);
  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));
  __internal_need_free.push_back(out.datas);
  for (int i = 0; i < out.length; ++i)
    out.datas[i] = cxx2lang<Lang, Cxx>(in[i]);
  return out;
}

template<typename Lang, typename Lang_array, typename Cxx>
Lang_array* cxx2lang_array_ptr(const std::vector<Cxx>& in)
{
  static Lang_array out; out = { NULL, in.size() };
  out.datas = (Lang *)malloc((out.length) * sizeof(Lang));
  __internal_need_free.push_back(out.datas);
  for (int i = 0; i < out.length; ++i)
    out.datas[i] = cxx2lang<Lang, Cxx>(in[i]);
  return &out;
}
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;
}

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)
{
  static position out;
  out.x = cxx2lang<int, int >(in.x);
  out.y = cxx2lang<int, int >(in.y);
  return &out;
}

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;
}

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)
{
  static 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" erreur hs_construire(position* pos)
{
  return cxx2lang<erreur, erreur >(api_construire(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" erreur hs_ameliorer(position* pos)
{
  return cxx2lang<erreur, erreur >(api_ameliorer(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" erreur hs_detruire(position* pos)
{
  return cxx2lang<erreur, erreur >(api_detruire(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" erreur hs_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)));
}

extern "C" erreur hs_deblayer(position* pos)
{
  return cxx2lang<erreur, erreur >(api_deblayer(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" case_type hs_type_case(position* pos)
{
  return cxx2lang<case_type, case_type >(api_type_case(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" position_array* hs_liste_pulsars(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_liste_pulsars());
}

extern "C" position_array* hs_liste_plasmas(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_liste_plasmas());
}

extern "C" position_array* hs_liste_tuyaux(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_liste_tuyaux());
}

extern "C" position_array* hs_liste_super_tuyaux(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_liste_super_tuyaux());
}

extern "C" position_array* hs_liste_debris(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_liste_debris());
}

extern "C" bool hs_est_pulsar(position* pos)
{
  return cxx2lang<bool, bool >(api_est_pulsar(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" bool hs_est_tuyau(position* pos)
{
  return cxx2lang<bool, bool >(api_est_tuyau(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" bool hs_est_simple_tuyau(position* pos)
{
  return cxx2lang<bool, bool >(api_est_simple_tuyau(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" bool hs_est_super_tuyau(position* pos)
{
  return cxx2lang<bool, bool >(api_est_super_tuyau(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" bool hs_est_debris(position* pos)
{
  return cxx2lang<bool, bool >(api_est_debris(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" bool hs_est_libre(position* pos)
{
  return cxx2lang<bool, bool >(api_est_libre(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" pulsar_info* hs_info_pulsar(position* pos)
{
  return cxx2lang<pulsar_info*, __internal__cxx__pulsar_info >(api_info_pulsar(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" double hs_charges_presentes(position* pos)
{
  return cxx2lang<double, double >(api_charges_presentes(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" int hs_constructeur_tuyau(position* pos)
{
  return cxx2lang<int, int >(api_constructeur_tuyau(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" int hs_proprietaire_base(position* pos)
{
  return cxx2lang<int, int >(api_proprietaire_base(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" position_array* hs_ma_base(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_ma_base());
}

extern "C" position_array* hs_base_ennemie(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_base_ennemie());
}

extern "C" int hs_puissance_aspiration(position* pos)
{
  return cxx2lang<int, int >(api_puissance_aspiration(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" position_array* hs_directions_plasma(position* pos)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_directions_plasma(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" int hs_cout_prochaine_modification_aspiration(void)
{
  return cxx2lang<int, int >(api_cout_prochaine_modification_aspiration());
}

extern "C" position_array* hs_hist_tuyaux_construits(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_tuyaux_construits());
}

extern "C" position_array* hs_hist_tuyaux_detruits(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_tuyaux_detruits());
}

extern "C" position_array* hs_hist_tuyaux_ameliores(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_tuyaux_ameliores());
}

extern "C" position_array* hs_hist_debris_deblayes(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_debris_deblayes());
}

extern "C" position_array* hs_hist_points_aspiration_ajoutes(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_points_aspiration_ajoutes());
}

extern "C" position_array* hs_hist_points_aspiration_retires(void)
{
  return cxx2lang_array_ptr<position, position_array, __internal__cxx__position >(api_hist_points_aspiration_retires());
}

extern "C" int hs_moi(void)
{
  return cxx2lang<int, int >(api_moi());
}

extern "C" int hs_adversaire(void)
{
  return cxx2lang<int, int >(api_adversaire());
}

extern "C" int hs_points_action(void)
{
  return cxx2lang<int, int >(api_points_action());
}

extern "C" int hs_score(int id_joueur)
{
  return cxx2lang<int, int >(api_score(lang2cxx<int, int >(id_joueur)));
}

extern "C" int hs_tour_actuel(void)
{
  return cxx2lang<int, int >(api_tour_actuel());
}

extern "C" bool hs_annuler(void)
{
  return cxx2lang<bool, bool >(api_annuler());
}

extern "C" void hs_afficher_erreur(erreur v)
{
  api_afficher_erreur(lang2cxx<erreur, erreur >(v));
}

extern "C" void hs_afficher_case_type(case_type v)
{
  api_afficher_case_type(lang2cxx<case_type, case_type >(v));
}

extern "C" void hs_afficher_position(position* v)
{
  api_afficher_position(lang2cxx<position*, __internal__cxx__position >(v));
}

extern "C" void hs_afficher_pulsar_info(pulsar_info* v)
{
  api_afficher_pulsar_info(lang2cxx<pulsar_info*, __internal__cxx__pulsar_info >(v));
}

extern "C" void partie_init(){
  haskell_init();
  hs_partie_init();
  hs_perform_gc();
  for(void* ptr : __internal_need_free){
    free(ptr);
  }
  __internal_need_free.clear();
}
extern "C" void jouer_tour(){
  haskell_init();
  hs_jouer_tour();
  hs_perform_gc();
  for(void* ptr : __internal_need_free){
    free(ptr);
  }
  __internal_need_free.clear();
}
extern "C" void partie_fin(){
  haskell_init();
  hs_partie_fin();
  hs_perform_gc();
  for(void* ptr : __internal_need_free){
    free(ptr);
  }
  __internal_need_free.clear();
}
