//
//ptrarray.c
//
//Handles arrays of pointers
//
//
//-UserX 2001/11/09

#include <stdlib.h>
#include "base/array.h"
#include "base/ptrarray.h"

/**
Functions for handling \Ref{PointerArrayHandle}s
@author UserX
@name ptrarray
*/
//@{

void *blankptr = NULL;
/**
Creates a new array for holding pointers. 
@return Pointer to the new PointerArrayHandle.
*/
PointerArrayHandle *ptrarrayMake(void) {
	return (PointerArrayHandle *) arrayMake(sizeof(void *), 0, &blankptr, NULL, NULL);
}

/**
Releases a pointer array.
@param pa A pointer to a PointerArrayHandle that is to be released.
*/
void ptrarrayFree(PointerArrayHandle *pa) {
	if(pa == NULL) {
		return;
	}
	arrayFree((ArrayHandle *) pa);
	return;
}

/**
Compacts a pointer array by removing all NULL entries.
@param pa A pointer to a PointerArrayHandle.
*/
void ptrarrayCompact(PointerArrayHandle *pa) {
	int i;
	int j;
	if(pa == NULL) {
		return;
	}
	for(i = 0, j = 0;i < pa->size; i++) {
		if(pa->data[i] != NULL) {
			pa->data[j] = pa->data[i];
			j++;
		}
	}

	arrayDeleteElements((ArrayHandle *) pa, pa->size - j);
}

/**
Find the index of an element in a pointer array that matches <B>ptr</B>. 
@param 
@return Index of the result, -1 if not found.
*/
int ptrarrayFind(PointerArrayHandle *pa, void *ptr) {
	int i;
	if(pa == NULL) {
		return -1;
	}
	for(i = 0; i < pa->size; i++) {
		if(pa->data[i] == ptr) {
			return i;
		}
	}
	return -1;
}

/**
Adds a pointer to a pointer array in the first available space.
@param pa A pointer to a PointerArrayHandle.
@param ptr The pointer to be added.
*/
void ptrarrayAdd(PointerArrayHandle *pa, void *ptr) {
	int i;
	//todo: verify NULL test can be skipped.
	if(pa == NULL) {
		return; //todo: maybe: an assert might be more appropriate
	}
	i = ptrarrayFind(pa, NULL);
	if(i == -1) {
		arrayAddElements((ArrayHandle *)pa, 1);
		i = pa->size - 1;
	}
	pa->data[i] = ptr;
}

/**
Removes a pointer to a pointer array.
@param pa A pointer to a PointerArrayHandle.
@param ptr The pointer to be removed.
*/
void ptrarrayDelete(PointerArrayHandle *pa, void *ptr) {
	int i = ptrarrayFind(pa, ptr);
	if(i == -1) {
		return;
	}
	pa->data[i] = NULL;
}

//@} 

