/* Copyright 1988 Timothy L. Davis
 *
 * $Source: /mit/hst/src/data/RCS/parameter.c,v $
 * $Log:	parameter.c,v $
 * Revision 2.2  90/08/18  18:31:24  tldavis
 * Added ref to .h file.
 * 
 * Revision 2.1  90/08/07  15:49:45  tldavis
 * Fixed compiler warnings.
 * 
 * Revision 2.0  90/08/06  17:50:56  tldavis
 * Final X11R3 version.
 * 
 * Revision 1.3  90/08/06  17:10:24  tldavis
 * No changes.
 * 
 * Revision 1.2  88/08/16  18:11:27  tldavis
 * *** empty log message ***
 * 
 */
#ifndef lint
static char 
*rcs = "$Header: /mit/hst/src/data/RCS/parameter.c,v 2.2 90/08/18 18:31:24 tldavis Exp Locker: tldavis $";
#endif

#include <stdio.h>
#ifdef SVR4
#include <string.h>
#else
#include <strings.h>
#endif
#include "../sim/CVDefs.h"
#ifdef RSAIX
extern void *malloc(), *realloc();
#else
#ifdef __STDC__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#endif
/* 
 * Private Data
 */

static VarData *vars[15][6];
static int     varCount[15][6];
SIMULATION savedsim[2];

static char *VarUnits[] = 
{ /*** depends on type defines in cvdefs.h ***/
  "cm/sec",
  "ml/sec",
  "mmHg",
  "ml",
  "ml/mmHg",
  "ml/mmHg",
  "ml/mmHg",
  "ml",
  "mmHg*sec/ml",
  "beats/min",
  "mmHg",
};

/*************************************
 *
 *   Public Routines
 *
 *************************************/

/*PUBLIC*/
VarData *get_vardata(place, type)
int place, type;
{
  VarData *p;
  int i;

  if (place < 0 || type < 0) return(NULL);
  if (type == TIME) place = SYSTEM;
  for (i=0; i<7; i++) {
    p = vars[place][i];
    if (p != NULL)
      while (p->var != ENDVAR) {
	if (p->var == type)
	  return(p);
	else p++;
      }
  }
  return(NULL); /*no such variable*/
}

/*PUBLIC*/
int *get_varlist(place, device, dep)
int place, device, dep;
{
  int *l, n, o;
  VarData *p;
  if (place < 0 || device < 0 || place > 8 || device > 6) {
    printf("Error: get_varlist: illegal parameter.\n");
    exit(1);
  }
  l = (int *) malloc((unsigned)(5*sizeof(int)));
  p = vars[place][device];
  n = o = 0;
  while (p && (p+o)->var != ENDVAR) {
    if ((p+o)->dep == dep) l[n++] = (p+o)->var;
    o++;
  }
  l[n] = ENDVAR;
  return(l);
}

/*PUBLIC*/
int var_in_bounds(place, type, value)
int type, place;
double value;
{
  VarData *p;
  int i;

  for (i = 0; i<7; i++) {
    p = vars[place][i];
    if (p != NULL)
      while (p->var != ENDVAR)
	if (p->var == type) {
	  if (p->min <= value && p->max >= value) {
	    return(1);
	  } else { 
	    return(0);
	  }
	} else p++;
  }
  return(0); /* no such variable exists */
}

/*PUBLIC*/
void LoadParameterData(path)
char *path;
{
  FILE *fp;
  VarData *vdPtr;
  int c;
  char place[80], dev[80], type[80], dep[80], name[80];
  double def, min, max, gmin, gmax;
  int placeCode = -1, devCode = -1, typeCode = -1, depCode = -1;

  if ((fp = fopen(path, "r")) == NULL) {
    fprintf(stderr, "Can't open parameter file %s.\n",path);
    exit(1);
  }
  {
    register int x, y;
    for (x=0; x<15; x++)
      for (y=0; y<6; y++)
	{ if (vars[x][y]) free(vars[x][y]);
	  vars[x][y] = NULL;
	  varCount[x][y] = 0;
	}
  }
  while ((c=fgetc(fp)) != EOF) {
    if (c=='#') {
      while ((c=fgetc(fp)) != '\n' && c != EOF) 
	;
    } else {
      c = fscanf(fp,":%[^:]:%[^:]:%[^:]:%[^:]:%lf :%lf :%lf :%lf :%lf :%[^\n]",
		 place,dev, type, dep, &def,&min,&max,&gmin,&gmax, name);
      if (c == 0) continue;
      else if (c == EOF) break;
      else if (c < 10) {
	fprintf(stderr, "Bad database line: %s :%s :%s :%s: ...etc... :%s\n",
		place, dev, type, dep, name);
	continue;
      }
      if (strncmp(place, "l", 1) == 0) placeCode = LV;
      else if (strncmp(place, "r", 1) == 0) placeCode = RV;
      else if (strncmp(place, "a", 1) == 0) placeCode = SA;
      else if (strncmp(place, "v", 1) == 0) placeCode = SV;
      else if (strncmp(place, "pa",2) == 0) placeCode = PA;
      else if (strncmp(place, "pv",2) == 0) placeCode = PV;
      else if (strncmp(place, "micro",1)==0) placeCode = SC;
      else if (strncmp(place, "pmicro",2)==0)placeCode = PC;
      else if (strncmp(place,"sys",3) == 0) placeCode = SYSTEM;
      else {fprintf(stderr,"Bad Place %s in db %s.\n", place, path); exit(1);}

      if (strncmp(dev, "cap", 3) == 0) devCode = CAPACITOR;
      else if (strncmp(dev, "res", 3) == 0) devCode = RESISTOR;
      else if (strncmp(dev, "vcap",4) == 0) devCode = VARCAPACITOR;
      else if (strncmp(dev, "system",6) == 0) devCode = SYSTEMOR;
      else {fprintf(stderr,"Bad Device %s in db %s.\n", dev, path); exit(1);}

      if (strncmp(type, "csys", 4) == 0) typeCode = CAPACITANCE_SYS;
      else if (strncmp(type, "cdias", 4) == 0) typeCode = CAPACITANCE_DIAS;
      else if (strncmp(type, "cap", 3) == 0) typeCode = CAPACITANCE;
      else if (strncmp(type, "zvol",4) == 0) typeCode = ZPVOLUME;
      else if (strncmp(type, "res", 3) == 0) typeCode = RESISTANCE;
      else if (strncmp(type, "hr", 2) == 0) typeCode = HEARTRATE;
      else if (strncmp(type, "pres", 4) == 0) typeCode = PRESSURE;
      else if (strncmp(type, "vol",  3) == 0) typeCode = VOLUME;
      else if (strncmp(type, "flow", 4) == 0) typeCode = FLOW;
      else if (strncmp(type, "time", 4) == 0) typeCode = TIME;
      else {fprintf(stderr,"Bad Type %s in db %s.\n", type, path); exit(1);}

      if (dep[0] == 'i') depCode = INDEPENDENT;
      else if (dep[0] == 'd') depCode = DEPENDENT;
      else {fprintf(stderr, "Bad Dep. flag %s in db %s.\n",dep,path); exit(1);}

      if (vars[placeCode][devCode] == NULL) {
	vars[placeCode][devCode] = 
	  (VarData *)malloc((unsigned)(2*sizeof(VarData)));
	varCount[placeCode][devCode]++;
      } else {
	vars[placeCode][devCode] = 
	  (VarData *)realloc((char *)vars[placeCode][devCode],
			     (unsigned)((++varCount[placeCode][devCode]+1)
			     *sizeof(VarData)));
      }
      vdPtr = vars[placeCode][devCode] + (varCount[placeCode][devCode]-1);
      vdPtr->var = typeCode;
      vdPtr->dep = depCode;
      vdPtr->normal = def;
      vdPtr->min = min;
      vdPtr->max = max;
      vdPtr->gmin = gmin;
      vdPtr->gmax = gmax;
      vdPtr->name = malloc((unsigned)((strlen(name)+1)*sizeof(char)));
      strcpy(vdPtr->name, name);
      vdPtr->units = VarUnits[typeCode];
      (vdPtr+1)->var = ENDVAR;
    }
  }
  /* Set the NORMAL set: */
  savedsim[1].Vl0 = get_vardata(LV,ZPVOLUME)->normal;
  savedsim[1].Vr0 = get_vardata(RV,ZPVOLUME)->normal;
  savedsim[1].Va0 = get_vardata(SA,ZPVOLUME)->normal;
  savedsim[1].Vv0 = get_vardata(SV,ZPVOLUME)->normal;
  savedsim[1].VPa0 = get_vardata(PA,ZPVOLUME)->normal;
  savedsim[1].VPv0 = get_vardata(PV,ZPVOLUME)->normal;
  savedsim[1].bv = get_vardata(SYSTEM,VOLUME)->normal;
  savedsim[1].Ra = get_vardata(SC,RESISTANCE)->normal;
  savedsim[1].Rv = get_vardata(SV,RESISTANCE)->normal;
  savedsim[1].RPv = get_vardata(PC,RESISTANCE)->normal;
  savedsim[1].Rli = get_vardata(PV,RESISTANCE)->normal;
  savedsim[1].Rlo = get_vardata(LV,RESISTANCE)->normal;
  savedsim[1].Rro = get_vardata(RV,RESISTANCE)->normal;
  savedsim[1].Ca = get_vardata(SA,CAPACITANCE)->normal;
  savedsim[1].Cv = get_vardata(SV,CAPACITANCE)->normal;
  savedsim[1].CPa = get_vardata(PA,CAPACITANCE)->normal;
  savedsim[1].CPv = get_vardata(PV,CAPACITANCE)->normal;
  savedsim[1].Cldias = get_vardata(LV,CAPACITANCE_DIAS)->normal;
  savedsim[1].Clsys = get_vardata(LV,CAPACITANCE_SYS)->normal;
  savedsim[1].Crdias = get_vardata(RV,CAPACITANCE_DIAS)->normal;
  savedsim[1].Crsys = get_vardata(RV,CAPACITANCE_SYS)->normal;
  savedsim[1].pth = get_vardata(SYSTEM,PRESSURE)->normal;
  savedsim[1].hr = get_vardata(SYSTEM,HEARTRATE)->normal;

  /* Set the CURRENT set (same as normal for now): */
  savedsim[0].Vl0 = get_vardata(LV,ZPVOLUME)->normal;
  savedsim[0].Vr0 = get_vardata(RV,ZPVOLUME)->normal;
  savedsim[0].Va0 = get_vardata(SA,ZPVOLUME)->normal;
  savedsim[0].Vv0 = get_vardata(SV,ZPVOLUME)->normal;
  savedsim[0].VPa0 = get_vardata(PA,ZPVOLUME)->normal;
  savedsim[0].VPv0 = get_vardata(PV,ZPVOLUME)->normal;
  savedsim[0].bv = get_vardata(SYSTEM,VOLUME)->normal;
  savedsim[0].Ra = get_vardata(SC,RESISTANCE)->normal;
  savedsim[0].Rv = get_vardata(SV,RESISTANCE)->normal;
  savedsim[0].RPv = get_vardata(PC,RESISTANCE)->normal;
  savedsim[0].Rli = get_vardata(PV,RESISTANCE)->normal;
  savedsim[0].Rlo = get_vardata(LV,RESISTANCE)->normal;
  savedsim[0].Rro = get_vardata(RV,RESISTANCE)->normal;
  savedsim[0].Ca = get_vardata(SA,CAPACITANCE)->normal;
  savedsim[0].Cv = get_vardata(SV,CAPACITANCE)->normal;
  savedsim[0].CPa = get_vardata(PA,CAPACITANCE)->normal;
  savedsim[0].CPv = get_vardata(PV,CAPACITANCE)->normal;
  savedsim[0].Cldias = get_vardata(LV,CAPACITANCE_DIAS)->normal;
  savedsim[0].Clsys = get_vardata(LV,CAPACITANCE_SYS)->normal;
  savedsim[0].Crdias = get_vardata(RV,CAPACITANCE_DIAS)->normal;
  savedsim[0].Crsys = get_vardata(RV,CAPACITANCE_SYS)->normal;
  savedsim[0].pth = get_vardata(SYSTEM,PRESSURE)->normal;
  savedsim[0].hr = get_vardata(SYSTEM,HEARTRATE)->normal;
}



/***** OLD STUFF BELOW HERE ******/
      
#ifdef NOTDEF
/* The following are not used currently */
static struct cvstatus cvstat[] = {
        { "Current Patient",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   NRA,NRV,NRPV,NRLI,NRLO,NRRO,
	   NCA,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Normal",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   NRA,NRV,NRPV,NRLI,NRLO,NRRO,
	   NCA,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Aging",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   NRA,NRV,NRPV,NRLI,NRLO,NRRO,
	   0.8,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Chronic Hypertension",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   1.6,NRV,NRPV,NRLI,NRLO,NRRO,
	   1.0,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Aortic Stenosis",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   NRA,NRV,NRPV,NRLI,0.22,NRRO,
	   NCA,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Hypovolemic Shock",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,4500.0,
	   NRA,NRV,NRPV,NRLI,NRLO,NRRO,
	   NCA,NCV,NCPA,NCPV,NCLDIAS,NCLSYS,NCRDIAS,NCRSYS,
	   NPTH,NHR},
	{ "Cardiogenic Shock",
	   NVL0,NVR0,NVA0,NVV0,NVPA0,NVPV0,NBV,
	   NRA,NRV,NRPV,NRLI,NRLO,NRRO,
	   NCA,NCV,NCPA,NCPV,NCLDIAS,1.2,NCRDIAS,NCRSYS,
	   NPTH,NHR},
};

static int NEXAMPLES = (sizeof(cvstat) / sizeof(cvstat[0]));
#endif
static int NEXAMPLES = 2;

/*PUBLIC*/
SIMULATION *setsimulation()
{
  savedsim[0].Vl0 = get_vardata(LV,ZPVOLUME)->normal;
  savedsim[0].Vr0 = get_vardata(RV,ZPVOLUME)->normal;
  savedsim[0].Va0 = get_vardata(SA,ZPVOLUME)->normal;
  savedsim[0].Vv0 = get_vardata(SV,ZPVOLUME)->normal;
  savedsim[0].VPa0 = get_vardata(PA,ZPVOLUME)->normal;
  savedsim[0].VPv0 = get_vardata(PV,ZPVOLUME)->normal;
  savedsim[0].bv = get_vardata(SYSTEM,VOLUME)->normal;
  savedsim[0].Ra = get_vardata(SC,RESISTANCE)->normal;
  savedsim[0].Rv = get_vardata(SV,RESISTANCE)->normal;
  savedsim[0].RPv = get_vardata(PC,RESISTANCE)->normal;
  savedsim[0].Rli = get_vardata(PV,RESISTANCE)->normal;
  savedsim[0].Rlo = get_vardata(LV,RESISTANCE)->normal;
  savedsim[0].Rro = get_vardata(RV,RESISTANCE)->normal;
  savedsim[0].Ca = get_vardata(SA,CAPACITANCE)->normal;
  savedsim[0].Cv = get_vardata(SV,CAPACITANCE)->normal;
  savedsim[0].CPa = get_vardata(PA,CAPACITANCE)->normal;
  savedsim[0].CPv = get_vardata(PV,CAPACITANCE)->normal;
  savedsim[0].Cldias = get_vardata(LV,CAPACITANCE_DIAS)->normal;
  savedsim[0].Clsys = get_vardata(LV,CAPACITANCE_SYS)->normal;
  savedsim[0].Crdias = get_vardata(RV,CAPACITANCE_DIAS)->normal;
  savedsim[0].Crsys = get_vardata(RV,CAPACITANCE_SYS)->normal;
  savedsim[0].pth = get_vardata(SYSTEM,PRESSURE)->normal;
  savedsim[0].hr = get_vardata(SYSTEM,HEARTRATE)->normal;
  return(&savedsim[0]);
}

/*PUBLIC*/
SIMULATION *getsimulation(pathology)
int pathology;
{
  if (pathology < 0 || pathology >= NEXAMPLES)
    fprintf(stderr,"Bad physiologic state code to getsimulation.\n");
  return((SIMULATION *) &(savedsim[pathology]));
}

