# include "opihi.h"

Variable *variables;   /* variable to store the list of all variables */
int      Nvariables;   /* number of currently available variables */

void InitVariables () {
  Nvariables = 0;
  ALLOCATE (variables, Variable, 1); 
}

int set_local_variable (char *name, char *value) {

  int i;
  char *local, *MacroName;

  /* a local variable has the form (macroname).(varname) */
  MacroName = GetMacroName ();

  /* look for global variable (warning or error)
  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (name, variables[i].name)) {
      fprintf (stderr, "warning: local variable overrides global name\n");
    }
  } */

  /* look for existing local variable */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (local, variables[i].name)) {
      free (variables[i].value);
      free (local);
      variables[i].value = strcreate (value);
      return (TRUE);
    }
  }
  /* NEW variable */
  Nvariables ++;
  REALLOCATE (variables, Variable, Nvariables);
  variables[Nvariables - 1].name = local;
  variables[Nvariables - 1].value = strcreate (value);
  return (TRUE);
}

int set_str_variable (char *name, char *value) {

  int i;
  char *local, *MacroName;

  MacroName = GetMacroName ();

  /* look for local variable first */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (local, variables[i].name)) {
      free (variables[i].value);
      free (local);
      variables[i].value = strcreate (value);
      return (TRUE);
    }
  }
  free (local);

  /* look for global variable */
  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (name, variables[i].name)) {
      free (variables[i].value);
      variables[i].value = strcreate (value);
      return (TRUE);
    }
  }
  /* NEW variable */
  Nvariables ++;
  REALLOCATE (variables, Variable, Nvariables);
  variables[Nvariables - 1].name = strcreate (name);
  variables[Nvariables - 1].value = strcreate (value);
  return (TRUE);
}

int set_variable (char *name, double dvalue) {

  char value[1024];

  sprintf (value, "%.9g", dvalue);
  set_str_variable (name, value);
  return (TRUE);
}

int set_int_variable (char *name, int ivalue) {

  char value[1024];

  sprintf (value, "%d", ivalue);
  set_str_variable (name, value);
  return (TRUE);
}

char *get_variable_ptr (char *name) {
  
  int i;
  char *local, *MacroName;

  MacroName = GetMacroName ();

  /* look for local variable first */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(local, variables[i].name)) {
      free (local);
      return (variables[i].value);
    }
  }
  free (local);

  /* look for global variable */
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(name, variables[i].name)) {
      return (variables[i].value);
    }
  }
  return ((char *) NULL);
}

char *get_variable (char *name) {
  
  int i;
  char *local, *MacroName;

  MacroName = GetMacroName ();

  /* look for local variable first */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(local, variables[i].name)) {
      free (local);
      return (strcreate (variables[i].value));
    }
  }
  free (local);

  /* look for global variable */
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(name, variables[i].name)) {
      return (strcreate (variables[i].value));
    }
  }
  return ((char *) NULL);
}

char *get_local_variable_ptr (char *name) {
  
  int i;
  char *local, *MacroName;

  MacroName = GetMacroName ();

  /* look for local variable first */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(local, variables[i].name)) {
      free (local);
      return (variables[i].value);
    }
  }
  free (local);
  return ((char *) NULL);
}

double get_double_variable (char *name) {
  
  int i;
  char *local, *MacroName;

  MacroName = GetMacroName ();

  /* look for local variable first */
  ALLOCATE (local, char, strlen(name) + strlen(MacroName) + 2);
  sprintf (local, "%s.%s", MacroName, name);
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(local, variables[i].name)) {
      free (local);
      return (atof (variables[i].value));
    }
  }
  free (local);

  /* look for global variable */
  for (i = 0; i < Nvariables; i++) { /* find the variable mentioned */
    if (!strcmp(name, variables[i].name)) {
      return (atof (variables[i].value));
    }
  }
  return (0.0);
}

int DeleteNamedScalar (char *name) {

  int i, j;

  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (name, variables[i].name)) {
      free (variables[i].name);
      free (variables[i].value);
      for (j = i; j < Nvariables - 1; j++) {
	variables[j] = variables[j + 1];
      }
      Nvariables --;
      REALLOCATE (variables, Variable, MAX (Nvariables, 1));
      return (TRUE);
    }
  }
  return (FALSE);
}

int IsScalar (char *name) { 

  int i;

  for (i = 0; i < Nvariables; i++) {
    if (!strcmp (name, variables[i].name)) return (TRUE);
  }
  return (FALSE);
}

void ListVariables () {

  int i;

  if (Nvariables == 0) {
    fprintf (stderr, "No defined variables\n");
    return;
  }

  for (i = 0; i < Nvariables; i++) {
    fprintf (stderr, "%s = %s\n", variables[i].name, variables[i].value);
  }
  return;
}
