/*
 * File:
 *   list.c
 */

#include "list.h"

list newList() {
  list tmp = (list) malloc(sizeof(struct LIST));
  if (!tmp) return tmp;
  /* Initialize the fields. */
  tmp->head = (node *) NULL;
  tmp->current = (node *) NULL;
  tmp->length = 0;
  return tmp;
} /* newList() */

/* Return value indicates success/failure. */
int addAfterCurrent(list ls, void *val) {
  node *tmp = (node *) malloc(sizeof(node));
  if (!tmp) return 0;
  tmp->contents = val;
  /* If there is a current element ... */
  if (ls->current) {
    tmp->next = ls->current->next;
    ls->current->next = tmp;
    ++(ls->length);
  }
  else {
    tmp->next = (node *) NULL;
    ls->head = tmp;
    ls->length = 1;
  }
  ls->current = tmp;
  return 1;
} /* addAfterCurrent(list, void *) */

/* Advance the cursor to the next value in the list. */
/* Advance could fail when ...
   + There is no cursor (e.g., the list is empty).
 */
/* What should advance do if the cursor refers to
 * the last element?
 * * Return failure and leave the cursor where it is.
 */
/* Daren suggests that advance return the address of the
   value in the current node. */
int advance(list ls) {
  /* If the list is empty, give up. */
  if ((!ls->current) || (!ls->current->next))
    return 0;
  ls->current = ls->current->next;
  return 1;
} /* advance(list) */

/* Special cases:
   (1) Empty list
   (2) Current is first element
   (3) Current is last element
   (4) Current is the only element (maybe)
 */
void *deleteCurrent(list ls) {
  void *val = ls->current->contents;
  node *tmp = ls->current;
  /* Verify that the list is nonempty. */
  if (!ls->current) return (void *) NULL;
  /* If there is a previous element, update it. */
  if (ls->current->prev)
    ls->current->prev->next = ls->current->next;
  /* If there is not a previous element, fix the head, too. */
  else
    ls->head = ls->current->next;
  /* If there is a previous element, update it. */
  if (ls->current->next)
    ls->current->next->prev = ls->current->prev;
  /* Advance current */
  /* Handle painful special case of being last element. */
  ls->current = ls->current->next;
  /* Free the memory associated with the current element. */
  free(tmp);
  /* Decrease the length */
  --(ls->length);
  /* That's it, we're done. */
  return val;
} /* deleteCurrent(list) */

deleteCurrent is a lot easier if you have a previous pointer,
too.

moveCursorToFront(ls);
while (tmp = deleteCurrent(ls))
  free(tmp);

/* THERE ARE STILL A FEW ERRORS.  FIX 'EM FOR FRIDAY! */

int insertBeforeCurrent(PARAMS) {
} /* ENDCOMMENT */
