#include <ctype.h>
#include <nicklib.h>
#include <xsearch.h> 
#define IDSIZE 40

#ifndef ADMUTILS

typedef struct {
  char ID[IDSIZE];
  char *egroup ;
  char gender;     /* 'M' or 'F' */
  double theta_mode;     /* most likely theta on mesh */
  double lambda_mode; /* mean of log10(lambda) from probability distribution */

  double Xtheta_mode;     /* most likely theta on mesh */
  double Xlambda_mode;  /* most likely lambda on mesh */

  int idnum ;
  int affstatus;      /* affected status */
  int ignore ;        /* YES => do not use */
  int flag   ;
  double thetatrue ;
  double Xthetatrue ;
  double lambdatrue ;
  double Xlambdatrue ;
  double totgamms[3] ;
  double totscore ;
  double rawqval ;
  double qval ;
} Indiv; 

typedef struct {
  char ID[IDSIZE];
  int chrom;
  char cchrom[6] ;
  double genpos;
  double physpos;
  double aa_cauc_freq;    /* frequencies in ancestral pop to AA */
  double aa_af_freq;
  double cauc_freq;    /* frequencies of variant allele */
  double af_freq;
  double  cftrue ;
  double  aftrue ;
  double  aa_cftrue ;
  double  aa_aftrue ;
  int  markernum ; /* marker number */
  char *pbuff ; 
  char *ebuff ;   /* for random ethnic path */
  int  isfake ;   /* 1 if fake marker  else 0 */
  int  isrfake ;  
/* real marker treated as fake.  Used for 2D scoring */
  int ignore ;
  int  ngtypes ;  /* 	number of gtypes */
  int  *gtypes ;
  int  af_nn[2] ;  
  int  cauc_nn[2] ;  
  double *modelscores ;
  double *totmodelscores ;
  double score ;
  double weight ;
  double estgenpos ; 
  double estdis ; 
  double dis ; 
  double esum ;  
  double lsum ;
  double gpsum ; 
  double gpnum ;
  void *pcupt ;
  int tagnumber ;
  char alleles[2] ;
  int chimpfudge ;
} SNP; 

typedef struct {
 char ID[IDSIZE] ;
 Indiv *father ; 
 Indiv *mother ; 
 Indiv *child ;
 int findex ;
 int mindex ;
 int cindex ; 
 int base ;
}   TRIO ;
// ?index into original Indiv array.  base is work variable used in phasetrio to store init index in new array

typedef struct {  
 char gname[IDSIZE] ;  
 SNP **snpm ;
 Indiv **indivm ;  
 int numsnps; 
 int numindivs ; 
 int rlen ;
 int fdes ;
 int snpindex ;
 unsigned char *buff ;
} genofile ;

typedef struct {  
 double xd[4] ;
 double xc[9] ;
 double ap1 ;
 double ap2 ;
 double cp1 ;
 double cp2 ;
 double rpowersum ;
 double crpowersum ;
 double gammasum[2] ;
 double gammanum[2] ;
 int  pubfmodern ;
}  SNPMC ;
// gammasum for cases/controls
#endif
#define ADMUTILS

void loadstats(FILE *statsfile, Indiv *indiv_array, int *numindivs);
void loadXstats(FILE *Xstatsfile, Indiv *indiv_array, int numindivs, int *numloaded);

void sett1(double *tt, double theta, int numstates) ;
void sett1r(double *tt, double theta, int numstate, double risks) ;
void gettln(SNP *cupt, Indiv *indx, 
  double *ptheta, double *plambda, int *pnumstates, int *pignore)  ;

void puttln(SNP *cupt, Indiv *indx, 
  double theta, double lambda) ;


/* UTILITY FUNCTIONS */

int countcol (char *fname);
int countcolumns (FILE *fp);

void fataly(const char *name);
int compare_doubles (const void *a, const void *b);

void pcheck (char *name, char x) ;
void printm(double **M, int numstates) ;
int numvalids(Indiv *indx, SNP **snpmarkers, int fc, int lc)  ; 
void gethpos(int *fc, int *lc, SNP **snpm, int numsnps,  
 int xchrom, int lo, int hi)  ; 
int numvalidgtypes(SNP *cupt) ;
double malefreq(Indiv **indivmarkers, int numindivs)  ;
int isimatch(int a, int b) ;   
void makedir(char *dirname) ;   
int indxindex(char **namelist, int len, char *strid)  ;
int indindex(Indiv **indivmarkers, int numindivs, char *indid)  ;
int snpindex(SNP **snpmarkers, int numsnps, char *snpid) ;
void inddupcheck(Indiv **indivmarkers, int numindivs) ;
void freesnpindex() ;
int ignoresnp(SNP *cupt) ;
double entrop(double *a, int n)  ;
double xxlog2(double t)  ;
void testnan(double *a, int n) ;
void hap2dip(SNP *cupt) ; 
void flipalleles(SNP *cupt) ;
void flipalleles_phased(SNP *cupt) ;
int   getgtypes(SNP *cupt, int k) ;
void  putgtypes(SNP *cupt, int k, int val) ;
int   getep(SNP *cupt, int k) ;
void  putep(SNP *cupt, int k, int val) ;
int hasharr(char **xarr, int nxarr)   ;
void wbuff(unsigned char *buff, int num, int g) ;  
int rbuff(unsigned char *buff, int num)  ;
int ridfile(char *fname) ;
double hwcheck(SNP *cupt, double *cc) ;
double hwcheckx(SNP *cupt, Indiv **indm, double *cc) ;
void cntit(double *xc, SNP *cupt1, SNP *cupt2) ;
// dup routines 
void setfastdupnum(int num) ;
void setfastdupthresh(double thresh, double kill) ;
void killxhets(SNP **snpmarkers, Indiv **indivmarkers, int numsnps, int numindivs) ;
void fastdupcheck(SNP **snpmarkers, Indiv **indivmarkers, int numsnps, int numindivs) ;
int grabgtypes(int *gtypes, SNP *cupt, int numindivs) ;
int kcode(int *w, int len, int base) ;
void cdup(SNP **snpm, Indiv **indm, int nsnp, int *buff, int lbuff) ;
void printdup(SNP **snpm, int nsnp, Indiv *inda, Indiv *indb, int nmatch, int nnomatch); 
void killdup(Indiv *inda, Indiv *indb, SNP **snpm, int nsnp) ;
double kurtosis(double *a, int n) ;
int getlist(char *name, char **list) ; 
void printvers(char *progname, char *vers) ;
int numvalidind(Indiv **indivmarkers, int  numind)   ;
void numvalidgtallind(int *x, SNP **snpm, int numsnps, int numind) ; 
int numvalidgtind(SNP **snpm, int numsnps, int ind)  ;
int numvalidgt(Indiv **indivmarkers, SNP *cupt)   ;
int numvalidgtx(Indiv **indivmarkers, SNP *cupt, int affst)  ;
int isxmale(SNP *cupt, Indiv *indx) ;

void printmatz(double *ww, char **eglist, int n) ;
void printmatz5(double *ww, char **eglist, int n) ;
void printmatz10(double *ww, char **eglist, int n) ;
char *get3(char *ss) ;
char *getshort(char *ss, int n) ;


#undef max 
#define max(A,B)  ((A) > (B) ? (A) : (B))

#define MAXNUMR  200 
// max number models

#define CNULL '\0' 
