# include "opihi.h"

int check_stack (StackVar *stack, int Nstack, int validsize) {

  int i, Nx, Ny, Nv, size;
  char *c1, *c2;

  Nv = Nx = Ny = -1;

  for (i = 0; i < Nstack; i++) {
    if (stack[i].type == 'X') {

      /** if this is a number, put it on the list of scalars and move on.  assume value is
       * an int unless proven otherwise **/
      stack[i].FltValue = strtod (stack[i].name, &c1);
      stack[i].IntValue = strtol (stack[i].name, &c2, 0);
      if (c2 == stack[i].name + strlen (stack[i].name)) {
	stack[i].type  = 's'; // 's' == (int)
	continue;
      } 
      if (c1 == stack[i].name + strlen (stack[i].name)) {
	stack[i].type  = 'S'; // 'S' == (float)
	continue;
      } 

      /** if this is a matrix, find the dimensions and check with existing values **/
      if (IsBuffer (stack[i].name)) {
	stack[i].buffer = SelectBuffer (stack[i].name, OLDBUFFER, TRUE);
	stack[i].type   = 'M';
	if (Nx == -1) {
	  Nx = stack[i].buffer[0].matrix.Naxis[0];
	  Ny = stack[i].buffer[0].matrix.Naxis[1];
	} 
	if ((Nx != stack[i].buffer[0].matrix.Naxis[0]) && (Ny != stack[i].buffer[0].matrix.Naxis[1])) {
	  push_error ("dimensions don't match");
	  return (-1);
	}	
	if (Nv != -1) {
	  if ((Nv != Nx) && (Nv != Ny)) {
	    push_error ("dimensions don't match");
	    return (-1);
	  }
	}	
	continue;
      }

      /** if this is a vector, find the dimensions and check with existing values **/
      if (IsVector (stack[i].name)) {
	stack[i].vector = SelectVector (stack[i].name, OLDVECTOR, FALSE);
	stack[i].type   = 'V';

	if (Nv == -1) Nv = stack[i].vector[0].Nelements;
	if (Nv != stack[i].vector[0].Nelements) {
	  push_error ("dimensions don't match");
	  return (-1);
	}
	if (Nx != -1) {
	  if ((Nx != Nv) && (Ny != Nv)) {
	    push_error ("dimensions don't match");
	    return (-1);
	  }
	}	
	continue;
      }

      /* this is not a scalar, vector, or matrix.  must be string */
      stack[i].type  = 'W';
    }
  }

  /* return object dimensions */
  size = 0;
  if (Nv != -1) size = 1;
  if (Nx != -1) size = 2;
  if (validsize == -1)   return (size);
  if (validsize != size) return (-1);
  return (size);
}

/* check stack identifies the data elements as scalar, vector, matrix, or word.
   operators have already been identified.  
   check stack returns the total stack dimensionality (0,1,2)
   on error, check stack returns -1
   possible errors:
     - mismatch with requested dimensionality
     - mismatch in data dimensions
*/
