/*
 * fontconfig/src/fcptrlist.c
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of the author(s) not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  The authors make no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include "fcint.h"

typedef struct _FcPtrListEntry {
    struct _FcPtrListEntry	*next;
    void			*data;
} FcPtrListEntry;
struct _FcPtrList {
    FcDestroyFunc	destroy_func;
    FcPtrListEntry	*list;
};
typedef struct _FcPtrListIterPrivate {
    const FcPtrList	*list;
    FcPtrListEntry	*entry;
    FcPtrListEntry	*prev;
} FcPtrListIterPrivate;

FcPtrList *
FcPtrListCreate (FcDestroyFunc func)
{
    FcPtrList *ret = (FcPtrList *) malloc (sizeof (FcPtrList));

    if (ret)
    {
	ret->destroy_func = func;
	ret->list = NULL;
    }

    return ret;
}

void
FcPtrListDestroy (FcPtrList *list)
{
    FcPtrListIter iter;

    FcPtrListIterInit (list, &iter);
    do
    {
	if (FcPtrListIterGetValue (list, &iter))
	    list->destroy_func (FcPtrListIterGetValue (list, &iter));
	FcPtrListIterRemove (list, &iter);
    } while (FcPtrListIterIsValid (list, &iter));

    free (list);
}

void
FcPtrListIterInit (const FcPtrList	*list,
		 FcPtrListIter		*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;

    priv->list = list;
    priv->entry = list->list;
    priv->prev = NULL;
}

void
FcPtrListIterInitAtLast (FcPtrList	*list,
		       FcPtrListIter	*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
    FcPtrListEntry **e, **p;

    e = &list->list;
    p = e;
    for (; *e; p = e, e = &(*e)->next);

    priv->list = list;
    priv->entry = *e;
    priv->prev = *p;
}

FcBool
FcPtrListIterNext (const FcPtrList	*list,
		 FcPtrListIter		*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;

    if (list != priv->list)
	return FcFalse;
    priv->prev = priv->entry;
    priv->entry = priv->entry->next;

    return priv->entry != NULL;
}

FcBool
FcPtrListIterIsValid (const FcPtrList	*list,
		    const FcPtrListIter	*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;

    return list == priv->list && priv->entry;
}

void *
FcPtrListIterGetValue (const FcPtrList		*list,
		     const FcPtrListIter	*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;

    if (list != priv->list ||
	!priv->entry)
	return NULL;

    return priv->entry->data;
}

FcBool
FcPtrListIterAdd (FcPtrList	*list,
		FcPtrListIter	*iter,
		void		*data)
{
    FcPtrListEntry *e;
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;

    if (list != priv->list)
	return FcFalse;

    e = (FcPtrListEntry *) malloc (sizeof (FcPtrListEntry));
    if (!e)
	return FcFalse;
    e->data = data;

    if (priv->entry)
    {
	e->next = priv->entry->next;
	priv->entry->next = e;
    }
    else
    {
	e->next = NULL;
	if (priv->prev)
	{
	    priv->prev->next = e;
	    priv->entry = priv->prev;
	}
	else
	{
	    list->list = e;
	    priv->entry = e;

	    return FcTrue;
	}
    }

    return FcPtrListIterNext (list, iter);
}

FcBool
FcPtrListIterRemove (FcPtrList		*list,
		   FcPtrListIter	*iter)
{
    FcPtrListIterPrivate *priv = (FcPtrListIterPrivate *) iter;
    FcPtrListEntry *e;

    if (list != priv->list)
	return FcFalse;
    if (!priv->entry)
	return FcTrue;

    if (list->list == priv->entry)
	list->list = list->list->next;
    e = priv->entry;
    if (priv->prev)
	priv->prev->next = priv->entry->next;
    priv->entry = priv->entry->next;
    free (e);

    return FcTrue;
}

#define __fcplist__
#include "fcaliastail.h"
#undef __fcplist__
