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

#include "yhost.h"


int YHostIsAllocated(int n);
YHost *YHostGetPtr(int n);
int YHostInList(YIPUnion *ip);
int YHostDeleteByHost(YIPUnion *ip);

int YHostAllocate(YIPUnion *ip);
void YHostDelete(int n);
void YHostDeleteAll(void);


#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define ABSOLUTE(x)     (((x) < 0) ? ((x) * -1) : (x))


/*
 *	Checks if host n is allocated.
 */
int YHostIsAllocated(int n)
{
	if((n < 0) ||
	   (n >= total_yhosts) ||
	   (yhost == NULL)
	)
	    return(0);
	else if(yhost[n] == NULL)
	    return(0);
	else
	    return(1);
}

/*
 *	Returns the pointer to host n if it is valid or NULL if it is
 *	not.
 */
YHost *YHostGetPtr(int n)
{
	if(YHostIsAllocated(n))
	    return(yhost[n]);
	else
	    return(NULL);
}


/*
 *	Checks if the specified host ip is in the list.
 *	Returns 1 if it is or 0 if it is not.
 */
int YHostInList(YIPUnion *ip)
{
	int i;
	YHost **ptr, *yhost_ptr;


	if(ip == NULL)
	    return(0);

	for(i = 0, ptr = yhost;
	    i < total_yhosts;
	    i++, ptr++
	)
	{
	    yhost_ptr = *ptr;
	    if(yhost_ptr == NULL)
		continue;

	    if(ip->whole == yhost_ptr->ip.whole)
		return(1);
	}

	return(0);
}

/*
 *	Deletes host matching the given ip, returns the index number
 *	of the host that was just deleted (which would be invalid
 *	after the call) or -1 if no matching host ip was found in
 *	the list.
 */
int YHostDeleteByHost(YIPUnion *ip)
{
	int i;
	YHost **ptr;


	if(ip == NULL)
	    return(-1);


	for(i = 0, ptr = yhost;
	    i < total_yhosts;
	    i++, ptr++
	)
	{
	    if(*ptr == NULL)
		continue;

	    if(ip->whole == (*ptr)->ip.whole)
	    {
		YHostDelete(i);
		return(i);
	    }
	}


	return(-1);
}

/*
 *	Allocate a new host structure with the given ip.
 */
int YHostAllocate(YIPUnion *ip)
{
	int i, n;


	if(total_yhosts < 0)
	    total_yhosts = 0;

	for(i = 0; i < total_yhosts; i++)
	{
	    if(yhost[i] == NULL) 
		break;
	}
	if(i < total_yhosts)
	{
	    n = i;
	}
	else
	{
	    n = total_yhosts;
	    total_yhosts++;

	    yhost = (YHost **)realloc(
		yhost,
		total_yhosts * sizeof(YHost *)
	    );
	    if(yhost == NULL)
	    {
		total_yhosts = 0;
		return(-1);
	    }
	}

	yhost[n] = (YHost *)calloc(1, sizeof(YHost));
	if(yhost[n] == NULL)
	    return(-1);

	/* Set values. */
	if(ip != NULL)
	    yhost[n]->ip.whole = ip->whole;
	else
	    yhost[n]->ip.whole = 0x00000000;


	return(n);
}

/*
 *	Delete host n.
 */
void YHostDelete(int n)
{
	if(YHostIsAllocated(n))
	{
	    /* Free structure itself. */
	    free(yhost[n]);
	    yhost[n] = NULL;
	}

	return;
}

/*
 *	Delete all hosts.
 */
void YHostDeleteAll(void)
{
	int i;

	for(i = 0; i < total_yhosts; i++)
	    YHostDelete(i);

	free(yhost);   
	yhost = NULL;

	total_yhosts = 0;

	return;
}
