/* Conceptual list collection backed by a list of arrays with increasing size.
 * Supports the following operations:
 *  create     - Create a new listarray
 *  size       - Return the number of elements in a listarray
 *  add        - Insert an item at the end of the listarray
 *  get        - Get the item at a given index of the list array
 *  set        - Set the item at a given index of the list array
 *  contains   - Determine whether the list array contains a specified item
 *  clear      - free all the memory associated with a listarray
 *
 *  Header author: Jerod Weinman
 */
#ifndef __LISTARRAY_H__
#define __LISTARRAY_H__

#include <stdbool.h>

typedef int data_t;
typedef struct node node_t;

struct node {
  data_t * array;
  int length;
  node_t * next;
};

typedef struct {
  node_t * first;
  int size;
} listarray_t;

/* Allocate a new listarray with the specified initial array capacity
 * Precondition:
 *  capacity > 0
 * Postcondition:
 *  Return value is NULL if memory cannot be allocated
 */
listarray_t *
create (int capacity);

/* Return the current size of the specified list
 * Precondition:
 *  list is a valid listarray_t pointer (i.e., returned by create)
 * Postcondition:
 *  produces the number of times add has been successfully called on list
 */
int
size (const listarray_t * list);

/* Add the specified item to the end of the collection
 * Preconditions:
 *  list points to a valid listarray_t
 * Produces:
 *  true if the item was added
 * Postconditions:
 *  If the item was successfully added:
 *    get (list,size(list)-1) == item
 *    size(list) increases by one 
 *  list is unmodified if the item was not successfully added
 */
bool
add (listarray_t * list, data_t item);

/* Get the item at the specified index in list
 * Preconditions:
 *  list points to a valid listarray_t
 *  index < size(list)
 * Produces:
 *   item
 * Postcondition:
 *  list is unmodified
 *  item is the element at the specified position in list
 */
data_t
get (const listarray_t * list, int index);

/* Replace the item at the specified index in list
 * Precondition:
 *  list points to a valid listarray_t
 *  index < size(list)
 * Produces:
 *  previous
 * Postcondition:
 *  get(list,index) = item
 *  previous = get(listbefore,index)
 */
data_t
set (listarray_t * list, int index, data_t item);

/* Determine whether the list contains the specified item
 * Precondition:
 *  list points to a valid listarray_t
 * Postcondition:
 *  list is unmodified
 *  Returns true if there exists an index such that get(list,index)==item
 */
bool
contains (const listarray_t * list, data_t item);

/* Clear the contents of the list, releasing all memory
 * Precondition:
 *  list points to a valid listarray_t
 * Postcondition:
 *   all memory associated with list is freed
 *   pointer list can no longer be used */
void
clear (listarray_t * list);


#endif
