/* Stacks with Arrays Lab
   Version 4:  Stack contains array of strings
               push copies string to stack
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

/* MaxStack stands for the size of all stack arrays */
#define MaxStack 50

/* maximum length of string on stack */
#define StringLength 5

typedef struct {
  int topPosition;
  char items[MaxStack][StringLength];
} stringStack;      /* type for a stack of strings */

/* index of standard stack operations            changes from Version 1 */
void
initialize(stringStack* stack);           /* unchanged */

int
size(const stringStack* stack);           /* unchanged */

int
isEmpty(const stringStack* stack);        /* unchanged */

int
isFull(const stringStack* stack);         /* unchanged */

int
push(stringStack* stack, char* item);     /* must copy string to stack */
/* post-condition:  item string is added to stack  
                    length of string is returned 
*/
char*
pop(stringStack *stack);                  /* must create copied string */

char*
top(const stringStack* stack);            /* must create copied string */

void
print(const stringStack* stack);          /* unchanged */

char*
get(const stringStack* stack, int index); /*  must create copied string */
/* assume indexing starts at 1 */

/* ---------------------------------------------------------------------- */
/* Implementation of stack operations */

void
initialize(stringStack* stack)
{
  stack->topPosition = -1;
}

int
size(const stringStack* stack)
{
  return stack->topPosition+1;
}

int
isEmpty(const stringStack* stack)
{
  return (stack->topPosition == -1);
}

int
isFull(const stringStack* stack)
{
  return (stack->topPosition == (MaxStack-1));
}


int
push(stringStack *stack, char * item)
{
/* post-condition:  item string is added to stack
                    length of string is returned 
*/
  /* return -1 if stack full */
  if (isFull(stack))
    return -1;
  
  /* add item to stack */
  (stack->topPosition) ++;
  strncpy (stack->items[stack->topPosition], item, StringLength);
  return strlen(item);
}

char*
pop(stringStack* stack)
{
  char* item;  /* string [base address] to return */

  /* return -1 if stack empty */
  if (isEmpty(stack)) 
    return (char *)(-1);

  /* remove item from stack */
  item = stack->items[stack->topPosition];
  (stack->topPosition) --;
  return item;
}
  
char*
top(const stringStack* stack)
{
  char* item;  /* string [base address] to return */

  /* return -1 if stack empty */
  if (isEmpty(stack))
    return (char *)(-1);

  /* remove item from stack */  
  item = (char*)(stack->items[stack->topPosition]);
  return item;
}

void
print(const stringStack* stack)
{
  int i;
  printf("contents of stack from top to bottom:\n");
  for (i = stack->topPosition; i >= 0; i--)
    printf("    %s\n", stack->items[i]);
  printf("end of stack\n");
}

char*
get(const stringStack* stack, int index) {
  /* assume nth indexing starts at 1
     translate to 0-indexed arrays, counting from topPosition 
     return null if invalid index specified */
  char* item;  /* string [base address] to return */
  if ((index < 1) || (index > stack->topPosition+1))
    return (char*)(-1);

  item = malloc(strlen (stack->items[stack->topPosition - index + 1])+1);
  strcpy(item, stack->items[(stack->topPosition) - index + 1]);
  return item;
}
