/* General doubly linked list V2.05 1/5/05
   Copyright 2008 Jeffrey Lee
   This file is part of WOUM.
   WOUM is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
   WOUM is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   You should have received a copy of the GNU General Public License
   along with WOUM.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _GDLL_H
#define _GDLL_H

struct _gdll;

typedef struct _gdll_item {
	struct _gdll_item *next,*prev; /* Next and previous items in this list, where 'next' is towards the tail end */
	struct _gdll *parent; /* The list we are in */
	void *me; /* The object associated with this item */
} gdll_item;

typedef struct _gdll {
	gdll_item *head,*tail; /* Head and tail ends of the list */
	unsigned long size; /* Number of items in the list */
	void *me; /* The object associated with this list */
} gdll;

extern gdll *gdll_create(void *me); /* Creates a new GDLL header, returns 0 on failure */
extern gdll_item *gdll_createitem(void *me); /* Creates a new GDLL item, returns 0 on failure */
extern int gdll_kill(gdll *h,int anditems); /* Deletes the list h, after first removing all its contents. If anditems != 0  then the items will be deleted too. Returns !0 on failure */
extern int gdll_killitem(gdll_item *i); /* Delete item i (First removing it from any list it's in) */
extern void gdll_remove(gdll_item *i); /* Removes i from any list it is in */
extern void gdll_addhead(gdll *h,gdll_item *i); /* Adds i to the head of list h */
extern void gdll_addtail(gdll *h,gdll_item *i); /* Adds i to the tail of list h */
extern void gdll_addnext(gdll_item *i,gdll_item *n); /* Adds i to n's list so that n comes after i */
extern void gdll_addprev(gdll_item *i,gdll_item *p); /* Adds i to p's list so that p comes before i */
extern unsigned long gdll_size(gdll *h); /* Returns the number of items in list h */
extern gdll_item *gdll_head(gdll *h); /* Returns the head item in list h, or 0 for none/failure */
extern gdll_item *gdll_tail(gdll *h); /* Returns the tail item in list h, or 0 for none/failure */
extern gdll_item *gdll_next(gdll_item *i); /* Returns the next item in list i, or 0 for none/failure */
extern gdll_item *gdll_prev(gdll_item *i); /* Returns the previous item in list i, or 0 for none/failure */
extern gdll *gdll_parent(gdll_item *i); /* Returns the GDLL that item i is in, or 0 for none/failure */
extern int gdll_sort(gdll *h,int (*func)(const void *,const void *)); /* Sort the list, using the supplied comparison function (Which takes item values as arguments). Returns !0 on failure */
extern gdll_item *gdll_findhead(gdll *h,void *i); /* Return the item pointer for the first occurence of an item 'it' where it->me == i, searching from the head end of the list. Returns 0 on failure */
extern gdll_item *gdll_findtail(gdll *h,void *i); /* Return the item pointer for the first occurence of an item 'it' where it->me == i, searching from the tail end of the list. Returns 0 on failure */
extern void **gdll_array(gdll *h); /* Return an array containing the 'me' pointers for all items in the list, starting from the head. Returns 0 on failure. */

#endif
