/***********************************************************************
 *
 * TITLE:
 *	dynarray.c
 *
 * AUTHOR:
 *	Kevin J. Miller
 *
 * DESCRIPTION:
 *	Defines the methods for a dynamic array of integers
 *
 *				CHANGE HISTORY
 *
 * $Log: dynarray.c,v $
 * Revision 1.5  1994/05/04  23:34:36  clm
 * ported to ANSI C
 *
 ***********************************************************************/

#include <malloc.h>
#include "dynarray.h"

#define NULL 0

/***********************************************************************
 *
 * FUNCTION:
 *	new_dynarray()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *	a new empty dynamic array structure
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	Allocates and returns a new empty dynamic array structure.
 */

struct dynarray *new_dynarray(void)
{
    struct dynarray *ptr;

    ptr = (struct dynarray *)malloc(sizeof(struct dynarray));
    ptr->basptr = NULL;
    ptr->nelems = 0;
    ptr->nslots = 0;
    return ptr;
}

/***********************************************************************
 *
 * FUNCTION:
 *	append_dynarray()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	Appends a new element to an existing dynarray structure.
 */

void append_dynarray(struct dynarray *ptr, int x)
{
    if (ptr->nelems >= ptr->nslots) {
	ptr->nslots += DYNARRAY_BATCH_SIZE;
	if (ptr->basptr == NULL) {
	    ptr->basptr = (int (*)[])malloc(ptr->nslots * sizeof(int));
	} else {
	    ptr->basptr = (int (*)[])realloc(ptr->basptr, ptr->nslots
		* sizeof(int));
	}
    }
    (*(ptr->basptr))[(ptr->nelems)++] = x;
}

/***********************************************************************
 *
 * FUNCTION:
 *	delete_dynarray()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	Deletes an entire dynarray structure.
 */

void delete_dynarray(struct dynarray *ptr)
{
    if (ptr->basptr != NULL) {
	free(ptr->basptr);
    }
    ptr->basptr = NULL;
    ptr->nelems = 0;
    ptr->nslots = 0;
}

/***********************************************************************
 *
 * FUNCTION:
 *      delete_element()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      Deletes an element of the dynarray structure.
 */

void
delete_element(int co, struct dynarray *ptr)
{
    int i;

    if ((ptr != NULL) && (ptr->nelems != 0)) {
        /*
         * find the element you are looking for
         */
        for (i = 0; i < sizeof_dynarray(ptr); i++) {
            if (elemof_dynarray(ptr, i) == co) {
                break;
            }
        }
        /*
         * move all subsequent elements up in the array
         */
        if (i < sizeof_dynarray(ptr)) {
            while (i+1 < sizeof_dynarray(ptr)) {
                elemof_dynarray(ptr, i) = elemof_dynarray(ptr, i+1);
                i++;
            }
            ptr->nelems--;
        }
    }
}
