# include "pcontrol.h"

/* get object from point in stack (negative == distance from end) */
void *GetStack (Stack *stack, int where) {

  int i;
  void *object;
  
  ASSERT (stack != NULL, "stack missing");

  /* STACK_TOP == 0, STACK_BOTTOM == -1 */
  /* this code correctly handles the negative 'where' and Nobject == 0 */
  if (where < 0) where += stack[0].Nobject;
  if (where < 0) return (NULL);
  if (where >= stack[0].Nobject) return (NULL);

  object = stack[0].object[where];
  stack[0].Nobject --;
  for (i = where; i < stack[0].Nobject; i++) {
    stack[0].object[i] = stack[0].object[i+1];
  }
  return (object);
}

/* push object on top of stack */
int PutStack (Stack *stack, int where, void *object) {

  int i;

  ASSERT (stack != NULL, "stack missing");

  /* STACK_TOP == 0, STACK_BOTTOM == -1 */
  /* this code correctly handles the negative 'where' and Nobject == 0 */
  if (where < 0) where += stack[0].Nobject + 1;
  if (where < 0) return (FALSE);
  if (where > stack[0].Nobject) return (FALSE);

  /* extend stack as needed */
  if (stack[0].Nobject >= stack[0].NOBJECT) {
    stack[0].NOBJECT += 100;
    REALLOCATE (stack[0].object, void *, stack[0].NOBJECT);
  }

  for (i = stack[0].Nobject; i > where; i--) {
    stack[0].object[i] = stack[0].object[i-1];
  }
  stack[0].object[where] = object;
  stack[0].Nobject ++;
  return (TRUE);
}

/* allocate stack, setup with default values, allocate data */
Stack *InitStack () {

  Stack *stack;

  ALLOCATE (stack, Stack, 1);

  stack[0].Nobject = 0;
  stack[0].NOBJECT = 50;
  ALLOCATE (stack[0].object, void *, stack[0].NOBJECT);
  return (stack);
}

/* these stacks are not super efficient, and should probably be replaced with linked lists, 
   but I find these easier to get my brain around
*/
