

#include <lists.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
extern APTR SysBase;
#include <pragmas/exec_pragmas.h>

#undef	Prototype
#define Prototype extern


#if 0

Prototype struct Node *DLL_GetHead (struct List *l);
struct Node *DLL_GetHead (struct List *l) {
    return l->lh_Head->ln_Succ ? l->lh_Head : NULL;
} /* DLL_GetHead */

Prototype struct Node *DLL_GetTail (struct List *l);
struct Node *DLL_GetTail (struct List *l) {
    return l->lh_TailPred->ln_Succ ? l->lh_TailPred : NULL;
} /* DLL_GetTail */

Prototype struct Node *DLL_GetSucc (struct List *l, struct Node *n);
struct Node *DLL_GetSucc (struct List *l, struct Node *n) {
    return n->ln_Succ->ln_Succ ? n->ln_Succ : NULL;
} /* DLL_GetSucc */

struct Node *DLL_GetPred (struct List *l, struct Node *n) {
    return (n->ln_Pred->ln_Pred ? n->ln_Pred : NULL;
} /* DLL_GetPred */


#endif

#define DLL_RemoveNode(l,n) Remove(n)
#define DLL_GetHead(l)   GetHead(l)
#define DLL_RemHead(l)   RemHead(l)
#define DLL_RemTail(l)   RemTail(l)
#define DLL_GetTail(l)   GetTail(l)
#define DLL_GetSucc(l,n) GetSucc(n)
#define DLL_GetPred(l,n) GetPred(n)
#define DLL_AddHead(l,n) AddHead(l,n)
#define DLL_AddTail(l,n) AddTail(l,n)


#if 0


Prototype void DLL_Sort (struct List *l, int (*comp)(struct Node *, struct Node *));
void DLL_Sort (struct List *l, int (*comp)(struct Node *, struct Node *)) {
    struct Node *n, *c;
    struct List inter;
    int diff;

    NewList (&inter);

    while (n = DLL_GetHead(l)) {
	for (c = DLL_GetSucc(l,n); c; c = DLL_GetSucc(c)) {
	    diff = (*comp)(c, n);
	    if (diff < 0)
		n = c;
	} /* for */
	DLL_RemoveNode (l, n);
	DLL_AddHead(&inter, n);
    } /* while */

    while (n = DLL_RemHead(&inter)) {
	AddHead(l, n);
    } /* while */
} /* DLL_Sort */


Prototype void DLL_Filter (struct List *l, struct List *dest, int (*check)(struct Node *, void *), void *ud);
void DLL_Filter (struct List *l, struct List *dest, int (*check)(struct Node *, void *), void *ud) {
    struct Node *n, *nn;
    int chck;

    for (n = DLL_GetHead(l); n; n = nn) {
	nn = DLL_GetSucc(l,n);

	chck = (*check)(n, ud);
	if (chck) {
	    DLL_RemoveNode(l, n);
	    DLL_AddTail(dest, n);
	} /* if */
    } /* for */
} /* DLL_Filter */


Prototype void DLL_Scan (struct List *l, void (*scan)(struct Node *, void *, int), void *ud);
void DLL_Scan (struct List *l, void (*scan)(struct Node *, void *, int), void *ud) {
    struct Node *n, *nn;
    int i = 0;
    for (n = DLL_GetHead(l); n; n = nn) {
	nn = DLL_GetSucc(l,n);
	(*scan)(n, ud, i++);
    } /* for */
} /* DLL_Scan */



Prototype int DLL_Length (struct List *list);
int DLL_Length (struct List *list) {
    struct Node *nod;
    int 	num = 0;

    for (nod = DLL_GetHead (list); nod; nod = DLL_GetSucc (nod)) {
	num ++;
    } /* for */
    return (num);
} /* DLL_Length */


#endif

Prototype struct Node *DLL_Search (struct List *l, int (*search)(struct Node *, void *), void *ud);
struct Node *DLL_Search (struct List *l, int (*search)(struct Node *, void *), void *ud) {
    struct Node *n;
    for (n = DLL_GetHead(l); n; n = DLL_GetSucc(l,n)) {
	if ((*search)(n, ud))
	    return n;
    } /* for */
} /* DLL_Search */


Prototype struct Node *DLL_NumToNode (struct List *l, int num);
struct Node *DLL_NumToNode (struct List *l, int num) {
    struct Node *n;
    if (num >= 0) {
	for (n = DLL_GetHead (l); (num > 0) && (n != NULL); n = DLL_GetSucc (l,n), num --);
    } else {
	for (n = DLL_GetTail (l); (num < 0) && (n != NULL); n = DLL_GetPred (l,n), num ++);
    } /* if */

    return n;
} /* DLL_NumToNode */


Prototype int DLL_NodeToNum (struct List *l, struct Node *n);
int DLL_NodeToNum (struct List *l, struct Node *n) {
    int num = 0;

    if (n != NULL) {
	while (n = DLL_GetPred (l,n)) {
	    num ++;
	} /* while */

	return (num);
    } /* if */
    return (-1);
} /* DLL_NodeToNum */


Prototype void DLL_Join (struct List *dest, struct List *add);
void DLL_Join (struct List *dest, struct List *add) {
#if 1
    struct Node *inter;

    while (inter = DLL_RemHead (add)) {
	AddTail (dest, inter);
    } /* while */
#else
    struct Node *last	= dest->lh_TailPred;
    struct Node *afirst = DLL_GetHead (add);

    if (afirst) {
	last->ln_Succ	= afirst;
	afirst->ln_Pred = last;
	last = DLL_GetTail (add);

	last->ln_Succ	  = &dest->lh_Tail;
	dest->lh_TailPred = last;

	NewList (add);
    } /* if */
#endif /* NOT_DEF */
} /* DLL_Join */


Prototype void DLL_AddSorted (struct List *l, struct Node *n, int (*comp)(struct Node *, struct Node *, void *), void *ud);
void DLL_AddSorted (struct List *l, struct Node *n, int (*comp)(struct Node *, struct Node *, void *), void *ud) {
    struct Node *m;
    for (m = DLL_GetHead(l); m && ((*comp)(m, n, ud) < 0); m = DLL_GetSucc (l,m));
    if (!m) {
	DLL_AddTail(l,n);
    } else {
	Insert(l, n, m->ln_Pred);
    }
} /* DLL_AddSorted */



