/****************************************************************************
 * FILE:        MYLIST.H                                                    *
 *                                                                          *
 * AUTHOR:      Daniel A. Rodriguez                                         *
 * DATE:        4/6/1999                                                    *
 ****************************************************************************/

#if !defined(MY_LIST)
#define MY_LIST

#include <stdlib.h>
#include <real.h>
#include <cellpos.h>

typedef struct lNode
{
	CellPosition	element;
	Real		*value;
	lNode		*next;
} lNode;


class mList
{
	public:
		mList()
			{ firstNode = lastNode = NULL; }

		~mList()
			{ this->clear(); }
	
		void clear();
		void add(CellPosition &elem, Real *val);

		void initCursor()
			{ cursor = firstNode; }
			
		bool endCursor()
			{ return (cursor == NULL)?true:false; }
			
		void next()
			{ cursor = cursor->next; }
			
		void modifyAtCursor(CellPosition &elem, Real *v)
			{ cursor->element = elem;
			  cursor->value = v; }

		CellPosition elementCell()	// Returns the element pointed by the cursor
			{ return cursor->element; }			

		Real *elementValue()	// Returns the element pointed by the cursor
			{ return cursor->value; }			

		lNode *exists(const CellPosition &elem);
					// Devuelve un puntero al elemento
					// encontrado si existe. Sino
					// devuelve NULL
					
		void setValue(CellPosition &elem, Real *v);

		void setValue(const CellPosition &elem, Real *v);
		
		void setRealValue(CellPosition &elem, const Real v);

	private:
		lNode	*firstNode;
		lNode	*lastNode;
		lNode	*cursor;
};

inline void mList::clear()
{
        lNode	*auxNode;
        
	while (firstNode != NULL)
        {
        	auxNode = firstNode->next;
                delete firstNode;
                
                firstNode = auxNode;
        }
        lastNode = NULL;
        cursor = lastNode;
}

inline void mList::add(CellPosition &elem, Real *v)
{
        lNode	*auxNode = new lNode;

        auxNode->element = elem;
        auxNode->value = v;
        auxNode->next = NULL;
        
        if (lastNode == NULL)
        {
        	lastNode = auxNode;		// Inserto al principio
                firstNode = auxNode;		// total no hay nada
        }
        else
        {
        	lastNode->next = auxNode;	// Relaciono el NEXT
                lastNode = auxNode;		// Hago que el elem sea el ultimo
        }
}

inline lNode *mList::exists(const CellPosition &elem)
{
        lNode	*auxNode = firstNode;
        
	while (auxNode != NULL)
        {
		if (auxNode->element == elem)
			return auxNode;

        	auxNode = auxNode->next;
        }
        return NULL;
}

inline void mList::setValue(CellPosition &elem, Real *v)
{
	lNode	*aux;

	if ((aux = this->exists(elem)) != NULL)
	{
		aux->element = elem;
		aux->value = v;
	}
	else
		add(elem,v);
}

inline void mList::setValue(const CellPosition &elem, Real *v)
{
	lNode	*aux;

	if ((aux = this->exists(elem)) != NULL)
	{
		aux->element = elem;	// Como existe entonces modifico
		aux->value = v;
	}
	else
		add(* ((CellPosition *) &elem), v);// Si no existe agrego
}

inline void mList::setRealValue(CellPosition &elem, const Real v)
{
	lNode	*aux;

	aux = this->exists(elem);
	MASSERTMSG( aux != NULL, "Can't find the reference to a cell in the NeighborList");

	*(aux->value) = v;	// Como existe entonces actualizo
}
                                                        
#endif	// MY_LIST
