
// gfxllist.h
//
// Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.

#ifndef __GFXLLIST_H__
#define __GFXLLIST_H__

#include "stdgfx.h"
#include "gfxadst.h"

template <class Type>
class LISTOBJECT : public DATAOBJECT
  {
    public :
      LISTOBJECT<Type> *PrevObject;
      LISTOBJECT<Type> *NextObject;
      Type Data;

      LISTOBJECT () : DATAOBJECT ()
        {
          PrevObject = NextObject = NULL;
        }; // End of Constructor for LISTOBJECT

      virtual ~LISTOBJECT ()
        {
          if (NextObject!=NULL)
            delete NextObject;
          NextObject = PrevObject = NULL;
        }; // End of Destructor for LISTOBJECT
  }; // End of LISTOBJECT

template <class Type>
class LINKEDLIST : public ADST
  {
    protected :
      LISTOBJECT<Type> *Head;
      LISTOBJECT<Type> *Tail;

    public :
      LINKEDLIST () : ADST ()
        {
          Head = Tail = NULL;
        }; // End of Constructor for LINKEDLIST

      virtual ~LINKEDLIST ()
        {
          while (Head!=NULL)
            {
              RemoveNode ( Head );
            } // End while
          Head = Tail = NULL;
        }; // End of Destructor for LINKEDLIST

      LISTOBJECT<Type>* GetHead () { return Head; };
      LISTOBJECT<Type>* GetTail () { return Tail; };

      BOOLEAN AddObject ( Type Data )
        {
          LISTOBJECT<Type> *NewNode;

          NewNode = new LISTOBJECT<Type> ();
          if (NewNode==NULL)
            return FALSE;

          NewNode->Data = Data;

          // Add it to list
          if (Head==NULL) // If empty
            {
              Head = NewNode;
              Tail = Head;
              NumObjects = 1;
            } // End if
          else
            {
              Tail->NextObject = NewNode;
              NewNode->PrevObject = Tail;
              Tail = NewNode;
              NumObjects++;
            } // End else
          return TRUE;
        }; // End of AddObject for LINKEDLIST

      VOID DiscardNode ( LISTOBJECT<Type> *Node )
        {
          if (Node==NULL)
            return;
          if (Node->PrevObject==NULL) // If Head
            {
              Head = Node->NextObject;
              if (Head==NULL)
                Tail = NULL;
              else
                Head->PrevObject = NULL;
            } // End if
          else
            {
              Node->PrevObject->NextObject = Node->NextObject;
              if (Node->NextObject==NULL) // If Last
                {
                  Tail = Node->PrevObject;
                } // End if
              else
                {
                  Node->NextObject->PrevObject =
                                      Node->PrevObject;
                } // End else
            } // End else
          Node->NextObject = NULL;
          Node->PrevObject = NULL;
          NumObjects--;
        }; // End of DiscardObject for LINKEDLIST

      VOID RemoveNode ( LISTOBJECT<Type>* Node )
        {
          if (Node==NULL)
            return;
          DiscardNode ( Node );
          delete Node;
        }; // End of RemoveObject for LINKEDLIST

      VOID ClearAllNode ()
        {
          while (Head!=NULL)
            {
              if (Head->Data!=NULL)
                delete Head->Data;
              Head->Data = NULL;
              RemoveNode ( Head );  
            } // End while
          Head = Tail = NULL;  
        }; // End of ClearNode for LINKEDLIST  
  }; // End of LINKEDLIST

#endif
