/* 
 * smeg - A satellite modelling and prediction tool
 * Copyright (C) 1999  Tom Rothamel
 * 
 * This program 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 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef LIST_H
#define LIST_H

template <class C>
class List {
public:
	struct Element {
		Element *next;
		Element *prev;
		C *data;
		int sort;

		Element () {
			next = NULL;
		}
	};

	Element *first;
	Element *last;
	Element *cur;
	int count;

      	List() {
		first = NULL;
		last = NULL;
		cur = NULL;
		count = 0;
	}

	~List() {
		Element *c;
		Element *n;

		c = first;
		while (c) {
			n = c->next;
			delete c;
			c = n;
		}
	}
			
	void add(C *n) {
		Element *e = new Element;
		e->data = n;
		e->next = NULL;

		if (first) {
			last->next = e;
			last = e;
		} else {
			first = e;
			last = e;
		}

		count++;
	}

	void add_sorted(C *n, int sort) {
		Element *e = new Element();
		static Element *c;
		
		e->data = n;
		e->sort = sort;
		count++;

		if (!first) {
			first = e;
			last = e;
			return;
		}

		if (sort < first->sort) {
			e->next = first;
			first = e;
			return;
		}

		if (!c) c = first;
		if (c->sort > sort) c = first;

		while (c->next) {
			if (c->next->sort > sort) break;
			c = c->next;
		}

		e->next = c->next;
		c->next = e;
	}

	void buildprev() {
		Element *c;
		Element *oc;
		
		c = first;
		c->prev = NULL;

		while (c->next) {
			oc = c;
			c = c->next;
			c->prev = oc;
		}

		last = c; /* Fix a sorted list. */
	}
			
	void reset() {
		cur = NULL;
	}

	int nextp() {
		return (cur->next != NULL);
	}

	int prevp() {
		return (cur->prev != NULL);
	}	

	C *next() {
		if (cur == NULL) {
			cur = first;
			return cur->data;
		}
		if (cur->next == NULL) {
			cur = NULL;
			return NULL;
		}

		cur = cur->next;
		return cur->data;
	}

	C *prev() {
		if (cur == NULL) {
			cur = last;
			return cur->data;
		}
		if (cur->prev == NULL) {
			cur = NULL;
			return NULL;
		}

		cur = cur->prev;
		return cur->data;
	}
};

#endif
