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

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

template<>
__internal__cxx__alien_info lang2cxx<alien_info, __internal__cxx__alien_info>(alien_info in)
{
  __internal__cxx__alien_info out;
  out.pos = lang2cxx<position, __internal__cxx__position >(in.pos);
  out.points_capture = lang2cxx<int, int >(in.points_capture);
  out.tour_invasion = lang2cxx<int, int >(in.tour_invasion);
  out.duree_invasion = lang2cxx<int, int >(in.duree_invasion);
  out.capture_en_cours = lang2cxx<int, int >(in.capture_en_cours);
  return out;
}

template<>
alien_info cxx2lang<alien_info, __internal__cxx__alien_info>(__internal__cxx__alien_info in)
{
  alien_info out;
  out.pos = cxx2lang<position, __internal__cxx__position >(in.pos);
  out.points_capture = cxx2lang<int, int >(in.points_capture);
  out.tour_invasion = cxx2lang<int, int >(in.tour_invasion);
  out.duree_invasion = cxx2lang<int, int >(in.duree_invasion);
  out.capture_en_cours = cxx2lang<int, int >(in.capture_en_cours);
  return out;
}

template<>
__internal__cxx__alien_info lang2cxx<alien_info*, __internal__cxx__alien_info>(alien_info* in)
{
  __internal__cxx__alien_info out;
  out.pos = lang2cxx<position, __internal__cxx__position >(in->pos);
  out.points_capture = lang2cxx<int, int >(in->points_capture);
  out.tour_invasion = lang2cxx<int, int >(in->tour_invasion);
  out.duree_invasion = lang2cxx<int, int >(in->duree_invasion);
  out.capture_en_cours = lang2cxx<int, int >(in->capture_en_cours);
  return out;
}

template<>
alien_info* cxx2lang<alien_info*, __internal__cxx__alien_info>(__internal__cxx__alien_info in)
{
  static alien_info out;
  out.pos = cxx2lang<position, __internal__cxx__position >(in.pos);
  out.points_capture = cxx2lang<int, int >(in.points_capture);
  out.tour_invasion = cxx2lang<int, int >(in.tour_invasion);
  out.duree_invasion = cxx2lang<int, int >(in.duree_invasion);
  out.capture_en_cours = cxx2lang<int, int >(in.capture_en_cours);
  return &out;
}

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.id_agent = lang2cxx<int, int >(in.id_agent);
  out.dir = lang2cxx<direction, direction >(in.dir);
  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.id_agent = cxx2lang<int, int >(in.id_agent);
  out.dir = cxx2lang<direction, direction >(in.dir);
  return out;
}

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.id_agent = lang2cxx<int, int >(in->id_agent);
  out.dir = lang2cxx<direction, direction >(in->dir);
  return out;
}

template<>
action_hist* cxx2lang<action_hist*, __internal__cxx__action_hist>(__internal__cxx__action_hist in)
{
  static action_hist out;
  out.atype = cxx2lang<action_type, action_type >(in.atype);
  out.id_agent = cxx2lang<int, int >(in.id_agent);
  out.dir = cxx2lang<direction, direction >(in.dir);
  return &out;
}

extern "C" erreur hs_deplacer(int id_agent, direction dir)
{
  return cxx2lang<erreur, erreur >(api_deplacer(lang2cxx<int, int >(id_agent), lang2cxx<direction, direction >(dir)));
}

extern "C" erreur hs_glisser(int id_agent, direction dir)
{
  return cxx2lang<erreur, erreur >(api_glisser(lang2cxx<int, int >(id_agent), lang2cxx<direction, direction >(dir)));
}

extern "C" erreur hs_pousser(int id_agent, direction dir)
{
  return cxx2lang<erreur, erreur >(api_pousser(lang2cxx<int, int >(id_agent), lang2cxx<direction, direction >(dir)));
}

extern "C" erreur hs_debug_afficher_drapeau(position* pos, debug_drapeau drapeau)
{
  return cxx2lang<erreur, erreur >(api_debug_afficher_drapeau(lang2cxx<position*, __internal__cxx__position >(pos), lang2cxx<debug_drapeau, debug_drapeau >(drapeau)));
}

extern "C" int hs_points_action_agent(int id_agent)
{
  return cxx2lang<int, int >(api_points_action_agent(lang2cxx<int, int >(id_agent)));
}

extern "C" direction_array* hs_chemin(position* pos1, position* pos2)
{
  return cxx2lang_array_ptr<direction, direction_array, direction >(api_chemin(lang2cxx<position*, __internal__cxx__position >(pos1), lang2cxx<position*, __internal__cxx__position >(pos2)));
}

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" int hs_agent_sur_case(position* pos)
{
  return cxx2lang<int, int >(api_agent_sur_case(lang2cxx<position*, __internal__cxx__position >(pos)));
}

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

extern "C" position* hs_position_agent(int id_joueur, int id_agent)
{
  return cxx2lang<position*, __internal__cxx__position >(api_position_agent(lang2cxx<int, int >(id_joueur), lang2cxx<int, int >(id_agent)));
}

extern "C" alien_info* hs_info_alien(position* pos)
{
  return cxx2lang<alien_info*, __internal__cxx__alien_info >(api_info_alien(lang2cxx<position*, __internal__cxx__position >(pos)));
}

extern "C" alien_info_array* hs_liste_aliens(void)
{
  return cxx2lang_array_ptr<alien_info, alien_info_array, __internal__cxx__alien_info >(api_liste_aliens());
}

extern "C" action_hist_array* hs_historique(void)
{
  return cxx2lang_array_ptr<action_hist, action_hist_array, __internal__cxx__action_hist >(api_historique());
}

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

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" bool hs_annuler(void)
{
  return cxx2lang<bool, bool >(api_annuler());
}

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

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_direction(direction v)
{
  api_afficher_direction(lang2cxx<direction, direction >(v));
}

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

extern "C" void hs_afficher_action_type(action_type v)
{
  api_afficher_action_type(lang2cxx<action_type, action_type >(v));
}

extern "C" void hs_afficher_debug_drapeau(debug_drapeau v)
{
  api_afficher_debug_drapeau(lang2cxx<debug_drapeau, debug_drapeau >(v));
}

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

extern "C" void hs_afficher_alien_info(alien_info* v)
{
  api_afficher_alien_info(lang2cxx<alien_info*, __internal__cxx__alien_info >(v));
}

extern "C" void hs_afficher_action_hist(action_hist* v)
{
  api_afficher_action_hist(lang2cxx<action_hist*, __internal__cxx__action_hist >(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();
}
