/*
*	header file for mex implementation of erg (execute reaction group) for bns3p0
*     Made it consistent with standalone BNS          Slava Chushak      12/06
*/

#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <float.h>
#include <ctype.h>
#include "ranlib.h"
#include <limits.h>

enum reaction_types { BINDING, UNIQUE_BI_BI, UNBINDING, UNI_UNI, UNI_MULTI, HOMO_LTOR, TRANSV1, GENM, NTH_ORDER, UNDEFINED };

struct array_sizes {
	int num_rxns;
	int num_cmpds;
	int num_monitor;
	int max_ssdata_rows;
	int *num_dependent;
      int *num_subs;
      int *num_prods;
};

struct run_constants {
	double time_start;
	double time_end;
	double volume;
	int stoch_algor;
    double tau_error;
	int eventlog_maxelements;
	int randseed;
	double snapshot_interval;
	int evlog_flag;
	int *comps_to_mon;
	int num_sets;
	int *num_repeats;
      double globtime;
      double timestep; 
      double ai_sum;
      double tnext;
      int rxnnum;
};

struct rxn {
	char type[81];
	int rxn_index;
	int id;
	int *substrates;
	int *numsubs_used;
	double *misc_subval;
	int *products;
	int *numprods_made;
        char kineticlaw[132];
        int num_rates;
        struct rate_data *rates;
	double ai;
	double rxn_time;
	int *rxn_depend;
};

struct cmpd_data {
	char name[81];
        int id;
	int value;
};

struct rate_data {
	char name[81];
        int id; 
	double value;
};
 
struct set_data{
	int num_cmpds;
        struct cmpd_data *cmpds;
        int num_rates;
        int *rxn_id;
        struct rate_data *rates;
};

struct evlog_data{
        int event_num;
        double *eventlog_time;
        int *eventlog_rxn;
};


void erg(struct rxn *, struct array_sizes *, struct cmpd_data *, int **, struct run_constants *, double **, int *,int *, double *);
void erg_tau(struct rxn *, struct array_sizes *, struct cmpd_data *, int **, struct run_constants *, double **, int *,int *, double *);
void find_next_reaction_erg(double *, int *, double *, struct rxn *, int , int, struct array_sizes *, double);
void update_rxn_prob_erg(double *, struct rxn *, int, struct cmpd_data *, double, struct run_constants *, struct array_sizes *);
double calc_rxn_prob_erg(struct rxn *, struct cmpd_data *cmpds, struct run_constants *, struct array_sizes *, int);
double rxn_prob_undef(struct rxn *, struct cmpd_data *);
void create_stoich_matrix( struct array_sizes  *, struct rxn *, int  **);
void calc_dependency(struct array_sizes *, struct rxn* );
void read_constants(struct rxn *, struct array_sizes *, struct cmpd_data *, struct run_constants *, struct set_data *, char *);
int assign_rxn_index(char *);
double rxn_prob_undef(struct rxn*, struct cmpd_data*);
double drand(void);
double find_tau(struct  array_sizes *,struct  rxn 	*,struct  cmpd_data *,int **,double );
long my_poisson(double );
void update_rxn_prob_all(struct rxn *, struct cmpd_data *,  struct run_constants *, struct array_sizes *, double );
