/**
* \file main.cpp
* \author basile.graf@epfl.ch
* 
* This is the main program file, containing the main function and loop.
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <math.h>


#include "SDL.h"
#include "SDL_OpenGL.h"

#include "main.h"

//----------------Includes for MATLAB MEX------------------------------------------
#include "math.h"
#include "mex.h"   
//---------------------------------------------------------------------------------


//----------------Includes for graphics------------------------------------------
#include "oGL_graphics/graphics_relative.h"
#include "oGL_graphics/solid_objects.h"
//---------------------------------------------------------------------------------



#include "string.h"

//----------------Includes for hydropter-------------------------------------------
#include "hydro_source/hydro_includes.h"
//---------------------------------------------------------------------------------


//-------------Includes for SUNDIALS CVODE solver:---------------------------------
#include "CVODEincludes.h"  // ODE solver includes
//---------------------------------------------------------------------------------

//-------------Include for timing functions----------------------------------------
#include "timing/timing.h"
//---------------------------------------------------------------------------------

#include "f.h"





static GLboolean should_rotate = GL_TRUE; 

	/* Color depth in bits of our window. */ 
//	int bpp = 0; 
	/* Flags we will pass into SDL_SetVideoMode. */ 
//	int flags = 0; 

float rot1 = 0.0f;
float rot2 = 0.0f;

int goLoop = 1;

ODE_data f_dats; 
ODE_data *f_dat = &f_dats;
	
/*	
GLfloat LightAmbient[]= { 0.35f, 0.35f, 0.5f, 1.0f }; 				// Ambient Light Values ( NEW )
GLfloat LightDiffuse[]= { 0.6f, 0.6f, 0.6f, 1.0f };				 // Diffuse Light Values ( NEW )
GLfloat LightPosition[]= { -10.0f, 20.0f, 150.0f, 0.0f };				 // Light Position ( NEW )
*/	
	



///Program quit function
/**
* This function quits the program ant returns the error code passed to it to the standard error (shell)
* Pass 0 to to quit normally, and any other value to indicate a quit on an error. 
* \param code : error code
*/
void quit_tutorial( int code ) 
{ 
	joystick_close();
	SDL_Quit( ); 
	close_font();
	/* Exit program. */ 
	//exit( code ); 
	free_wave_variables();
	solver_free(f_dat);
	delete f_dat->state; //delete_state(f_dat->state);
	Boat_delete();
	exit( code ); 
}



 







///Main function (program entry)
/**
* This is the programm entry. On OS X, be aware that there is a cocoa wrap around it (see SDLmain.m and/or SDL.framework)
*/
int main( int argc, char* argv[] ) 
{ 
	int width = 640; 
	int height = 480;
	
	//--------------------------------
	parameters Par; ///< parameters Par;   parameters structure (from MATLAB)
	parameters *P = &Par; ///< parameters *P;  pointer to Par, will be passed to many functions
	joy_parameters jPar;  ///<  joy_parameters jPar;  joystick parameters structure (from MATLAB)
	joy_parameters *jP = &jPar;  ///< joy_parameters *jP;  pointer to jPar, will be passed to other functions
	datas dat;  ///<  datas dat;   model data structure containing all model (physics) informations
	datas *d = &dat; ///< pointer to dat, will be passed to many many functions
//	ODE_data f_dats;  ///< ODE_data f_dats;  solver data structure, contains pointer to the other structures and some solver relative informations
//	ODE_data *f_dat = &f_dats;  ///< ODE_data *f_dat;   pointer to f_dats, will be passed to solver relative functions
	//--------------------------------
	
	
	int kk;

	double *state = new double[STATENUM];
	char* flag;
	char def_flag[]  = "";
	char output_flag[]  = "output";
	long tLength;

	float Time;
	double time;
	bool go=1;
	
	read_arguments_from_file(P, jP, state, &time);
	 pass_joy_parameters(jP);
	
//	state = dummy_get_state();//state = get_state(nlhs, plhs, nrhs, prhs);

	f_dat->d = d;
	f_dat->P = P;
	
	
	f_dat->state = state;
	
	fprintf( stderr, "state: \n");
	for (kk=0; kk<12; kk++) fprintf( stderr,"%f \n", float(state[kk]));
	
//	dummy_initParameters(P);
	
	f_dat->time_param = time; //a la place de get_time
	
	
	data_init(d);
	data_update_state(d, state);
	data_update_param(d, P);
	
	
	solver_init(f_dat);
	
	wave_init();

	Boat_create(d);
	
	
	//---------------------------------
	setup_SDL(width, height);
	
	kk = joystick_init(); //must be initialised _AFTER_ SDL
	
	
	setup_opengl( width, height ); 
	
	setup_font();
	
	
	while( getCallibatingPhase() )
	{ 
		process_events( ); 
		kk = DrawGLScene(d);
		SDL_GL_SwapBuffers(); 
		do_on_keystate(d);	
	}
	
	tic(); // Measure time from now on
	
	while( go )
	{ 
		/* Process incoming events. */ 
		process_events( ); 
		Time = toc(); // Get total elapsed time
		solve_ODE(f_dat, Time);
		/* Draw the screen. */ 
		//draw_screen( ); 
		kk = DrawGLScene(d);
		SDL_GL_SwapBuffers(); 
		do_on_keystate(d);	
		if ((f_dat->time_param != 0.0) && (d->t > f_dat->time_param)) go=0;
	}
	
	// If we reach this place, this that the simulation time was reached and that we have to write results to file:
	kk = write_results_to_file();
	
	quit_tutorial( 0 );
	
	return 0; 
} 


