# include "runsim.h"

void erg(struct rxn *rxn_ptr, struct array_sizes *arsz_ptr, struct cmpd_data *cmpds, int ** stoich_mat, struct run_constants *r_c, double **evlog, int *event_num, int *times_executed, double *sim_time) 
{

	int rxnnum, is;
	double tnext, ai_sum;
	int stoch_alg, evlogflag;
    int mol_id, ev_num;
    double time, rem;
    double snapshot_interval; 
    
    ev_num = *event_num;
	time = *sim_time;
    rem = fmod(time, r_c->snapshot_interval);
    snapshot_interval = r_c->snapshot_interval - rem;
    
	ai_sum = r_c->ai_sum;
	stoch_alg = r_c->stoch_algor;
	evlogflag = r_c->evlog_flag;
    tnext = r_c->tnext;
    rxnnum = r_c->rxnnum;

	while (tnext <= (time + snapshot_interval)) 
    {
/*     Execute reaction with Stoichiometry matrix           */
        
                 for (is =0; is < arsz_ptr->num_cmpds; is++)
                 { 
                     if (stoich_mat[rxnnum][is] != 0)
                         cmpds[is].value += stoich_mat[rxnnum][is];   
                 }
		times_executed[rxnnum] += 1;
		update_rxn_prob_erg(&ai_sum, rxn_ptr, rxnnum, cmpds, tnext, r_c, arsz_ptr);
        
			if (evlogflag == 1)
            {
                    evlog[0][ev_num] = tnext;
					evlog[1][ev_num] = rxnnum+1;
					ev_num ++;
                    
				if (ev_num >= r_c->eventlog_maxelements) 
                {
                    *event_num = ev_num;
                    *sim_time = tnext;
                    find_next_reaction_erg(&tnext, &rxnnum, &ai_sum, rxn_ptr, stoch_alg, 0, arsz_ptr, tnext);
                    r_c->ai_sum = ai_sum;
                    r_c->tnext = tnext;
                    r_c->rxnnum = rxnnum;
                    return;
                }
            }
             
		find_next_reaction_erg(&tnext, &rxnnum, &ai_sum, rxn_ptr, stoch_alg, 0, arsz_ptr, tnext);
  
	} 
                
               time += snapshot_interval;          
               *event_num = ev_num;
               *sim_time = time;
               r_c->ai_sum = ai_sum;
               r_c->tnext = tnext;
               r_c->rxnnum = rxnnum;
               
    return;
}
