/*******************************menu.c*********************************/
/* Anne Wright:  Menu functions (which also allow variables to be set 
   via the frob knob and selection buttons) for robot. 11/14/91 
   Updated for v2.8 of ic, 3/5/94 
*/

 /* abstractions for chosen_button */
int NEITHER_B=0;
int CHOOSE_B =1;
int ESCAPE_B =2;

/* abstractions for wait_button */
int UP_B     =3;
int DOWN_B   =4;
int CYCLE_B  =5;

/* abstractions for line parsing */
int NEWLINE=10;

/*****************************button routines*************************/
int min(int a,int b)
{
  if(a<b)
    return(a);
  else
    return(b);
}
float fmin(float a,float b)
{
  if(a<b)
    return(a);
  else
    return(b);
}

int chosen_button()
{
/* returns which button is depressed.  If both, choose has precedence */

  if(choose_button())
    return CHOOSE_B;
  else if(escape_button())
    return ESCAPE_B;
  else 
    return NEITHER_B;
}  

int wait_button(int i)
{
/* wait until button is depressed(DOWN_B), released(UP_B), or both(CYCLE_B) and 
     return which button if any activated the sequence */

  if(i==DOWN_B)
    {while(!(choose_button() || escape_button()));
     return chosen_button();}
  else if (i==UP_B)
    {int b;
     b=chosen_button();
     while(choose_button() || escape_button());
     return b;}
  else
    {int b;
     while(!(choose_button() || escape_button()));
     b=chosen_button();
     while(choose_button() || escape_button());
     return b;}
} 
/**********************Menu selection routines*****************************/
/*returns an integer value between min_val and max_val chosen using frob */
int select_int_value(char s[],int min_val,int max_val)
{
  int val, coarseness=(255)/(max_val-min_val),selection;

  printf("%s%d to %d\n",s,min_val, max_val);
  sleep(.05);

  wait_button(UP_B);
  while(!(choose_button() || escape_button()))
    {
      val=min((frob_knob())/coarseness+min_val,max_val);
      printf("%s %d\n",s,val);
      sleep(.1);
    }
  if(wait_button(UP_B)==ESCAPE_B)
    return -1; /** -1 means escape -- do not reset value **/
  else
    return min(val,max_val);
}
float select_float_value(char s[],float min_val,float max_val)
{
  float val, coarseness=(255.)/(max_val-min_val),selection;

  printf("%s %f to %f\n",s,min_val,max_val);
  sleep(.05);

  wait_button(UP_B);
  while(!(choose_button() || escape_button()))
    {
      val=fmin(((float)frob_knob())/coarseness+min_val,max_val);
      printf("%s %f\n",s,val);
      sleep(.05);
    }
  if(wait_button(UP_B)==ESCAPE_B)
    return -1.0; /** -1 means escape -- do not reset value **/
  else
    return fmin(val,max_val);
}

/* multiple line string parser */
int substr(char string[],int line)
{
  int i,l;
  for(i=0,l=0;string[i]!=0 && l<line;i++)
    if(string[i]==NEWLINE)
      l++;
  return i;
}

int strcpy(char s1[],char s2[])
{ 
  int i;
  for(i=0;s2[i]!=0;i++)
    s1[i]=s2[i];
  s1[i]=0;
  return i;
}

int linecpy(char s1[],char s2[],int line)
{
  int i,offset;
  offset=substr(s2,line);
  for(i=0;s2[i+offset]!=NEWLINE && s2[i+offset]!=0;i++)
    s1[i]=s2[i+offset];
  s1[i]=0;
  return i;
}

int select_string(char names[],int n)
{
  int coarseness=255/(n-1),selection,last_selection=-1;
  char slate[40];

  while(!(choose_button() || escape_button()))
    {selection=frob_knob()/coarseness;
     if(selection!=last_selection)
       {
	 linecpy(slate,names,selection);
	 last_selection=selection;
	 printf("%s\n",slate);
	 sleep(.05);
       }
   }
  if(wait_button(UP_B)==ESCAPE_B)
    return -1;
  else
    return min(selection,n-1);
}


int select_string_with_values(char names[],int values[],int n)
{
  int coarseness=255/n,selection,last_selection=-1;
  char slate[40];

  printf("Setting values...\n");
  sleep(.5);

  while(!(choose_button() || escape_button()))
    {
      selection=min(frob_knob()/coarseness,n-1);
      if(selection!=last_selection)
	{
	  linecpy(slate,names,selection);
	  last_selection=selection;
	  printf(">%s=%d\n",slate,values[selection]);
	  sleep(.05);
	}
    }
  if(wait_button(UP_B)==ESCAPE_B)
    return -1;
  else
    return selection;
}

int set_general_values(int number,int valarr[],int max_vals[],char strings[])
{
  char slate[40];
  int selection,value;

  printf("Setting values...\n",number);
  sleep(.5);
  if((selection=select_string_with_values(strings,valarr,number))==-1)
    return -1;
  linecpy(slate,strings,selection);
  if((value=select_int_value(slate,0,max_vals[selection]))==-1)
    return -1;

  valarr[selection]=value;
  return selection;
}


