/* ReSCAL - Engine entry
 *
 * Copyright (C) 2011-2012
 *
 * Author: Olivier Rozier <rozier@ipgp.fr>
 *
 * This file is part of ReSCAL.
 *
 * ReSCAL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */


#include <stdio.h>
#include <locale.h>

#include "defs.h"
#include "macros.h"
#include "rescal.h"
//#include "monitor.h"
#include "interface.h"
#ifdef PARALLEL
#include "synchro.h"
#endif
#include "cells.h"
#include "space.h"
#include "surface.h"
#include "simul.h"
#include "models.h"
#include "doublets.h"
#include "transitions.h"
#include "param.h"
#include "trace.h"


#ifdef LGCA
#include "lgca.h"
#endif

extern unsigned char opt_info, opt_nv;
extern unsigned long int iter;        // nombre d'iterations
extern double csp_time;                    // temps reel simule
#ifdef PARALLEL
extern int mode_par;    //mode parallele
#endif

//int stop_simul = 0;                 //semaphore (pour le multithreading)
int fin_simul = 0;                  //semaphore (pour l'arret des callbacks)


void rescal_params()
{
  init_liste_params();
  params_simul();
  params_modele();
#ifdef LGCA
  params_collisions();
#endif
}

void rescal_usage()
{
  printf("\nusage: rescal PARAMETERS_FILE [OPTIONS]\n\n");
  rescal_params();
  param_usage();
}

//initialization of rescal thread
void rescal_init(char *param_filename)
{
#ifdef NUM_MODE
  setlocale(LC_NUMERIC, NUM_MODE);
#endif

  rescal_params();
  lecture_parametres(param_filename);
  //init_signal();

#ifdef PARALLEL
  if (mode_par) synchro_init();
#endif

  init_simul();

  cree_terre();
  calcule_couloir();
  compute_h_ceil();
  compute_h_floor();
#ifdef PARALLEL
  cree_tunnels();
#endif

  init_Ncel();
  init_modele();
  init_transitions();
  init_db_pos();
#ifdef LGCA
  init_collisions();
#endif

  if (opt_info){
    log_cell();
    dump_doublets();
    dump_transitions();
  }

#ifdef ALTI
  calcule_alti(ALTI, ALTI_MODE_BAS);
  calcule_normales();
#endif

#if defined(MODELE_DUN) && defined(LGCA)
  //dump_cgv();
#endif

#ifdef SURRECTIONS
  //regul_niveau();
#endif

#if MODE_TRACE
  trace_init();
#endif

  LogPrintf("rescal_init: end\n");

}

int rescal(int n)
{
  static unsigned char start=0;
  unsigned char stop=0;

  if (!start) {
#ifdef PARALLEL
    if (mode_par) synchro_start();
#endif
    //monitor_signal();
    LogPrintf("debut de la simulation ...\n");
    push_status("running",0);
    start = 1;
  }

  while (!stop){
#if defined(TRACE_SRC) || defined(TRACE_AIRE) || defined(TRACE_PAR)
    stop = trace_init_loop(0);
    if (stop) break;
#endif
    stop = simul_csp(n);
#if defined(TRACE_AIRE) || defined(TRACE_PAR)
    trace_end_loop();
    stop = 0;
#endif
  }

  if (stop){
    LogPrintf("fin de la simulation\n");
    fin_simul = 1;
    pop_status(0);
  }

  return 0;
}

/*

void rescal_quit()
{
  rescal_stop();
#ifdef TRACE_TRANS
  trace_trans_quit();
#endif
#ifdef TRACE3D_CEL
  trace3d_cel_quit();
#endif
  fin_db_pos();
  apocalypse();
}
*/

