#include "psmod.h"

particle_system_p
psAlloc(void)
{
	particle_system_p ps;
	ps = memAllocZ(sizeof(particle_system_t));
	V_ASSERT(ps);
	stackInit(&ps->particles,sizeof(particle_parameters_t));
	ps->binary_interaction = NULL;
	vpsInit(&ps->unary_effects);
	icInitDC(&ps->dc);
	ps->solver.solver_handle = LIBV_INVALID_HANDLE;
	ps->solver.current_time = 0;
	ps->solver.rt_timer = timerCreate();
	V_ASSERT(ps->solver.rt_timer != LIBV_INVALID_HANDLE);
	ps->solver.verbose = true;
	vpsInit(&ps->solver.monitors);
	ps->solver.main_monitor_routine = psmodMonitor;
	ps->solver.right_side = psmodRightSide;
	fifoInit(&ps->solver.stages,sizeof(solver_stage_t));
	ps->solver.current_stage.load_file[0] = 0;
	ps->solver.current_stage.save_file[0] = 0;
	ps->solver.current_stage.upper_time = 0;
	ps->solver.current_stage.realtime_limit = 3600;
	ps->solver.current_stage.RK_tolerance = 1e-2;
	ps->solver.current_stage.RK_timeout = 10;
	ps->solver.current_stage.initial_step = 1e-6;
	ps->solver.current_stage.minimal_step = 1e-15;
	ps->solver.current_stage.monitor_cps = 10;
	ps->solver.current_stage.exact_monitoring = false;
	return ps;
}

void
psDestroy(particle_system_p ps)
{
	if(!ps)
		return;
	icClearDC(&ps->dc);
	stackClear(&ps->particles);
	if(ps->binary_interaction)
		ctlFree(ps->binary_interaction);
	ufxDestroyEffects(ps);
	if(ps->phase)
		memFree(ps->phase);
	if(ps->force)
		memFree(ps->force);
	if(ps->solver.rt_timer != LIBV_INVALID_HANDLE)
		timerDestroy(ps->solver.rt_timer);
	if(ps->solver.solver_handle != LIBV_INVALID_HANDLE)
		odeDestroySolver(ps->solver.solver_handle);
	if(ps->solver.rt_timer != LIBV_INVALID_HANDLE)
		timerDestroy(ps->solver.rt_timer);
	vpsClear(&ps->solver.monitors);
	fifoClear(&ps->solver.stages);
	memFree(ps);
	if(random_generator != LIBV_INVALID_HANDLE)
	{
		ranDestroyGenerator(random_generator);
		random_generator = LIBV_INVALID_HANDLE;
	}
}
