// file: link_list.h
//
// this is the header file for the linked list class

// make sure definitions are made only once
//
#ifndef __ISIP_LINK_LIST
#define __ISIP_LINK_LIST

// isip include files
//
#ifndef __ISIP_INTEGRAL
#include <integral.h>
#endif

#ifndef __ISIP_INTEGRAL_CONSTANTS
#include <integral_constants.h>
#endif

// forward declaration of classes
//
#ifndef __ISIP_LINK_NODE
#include <link_node.h>
#endif

#ifndef __ISIP_MEMORY_MANAGER
#include <memory_manager.h>
#endif

// Link_list
//
// this file defines a class that implements a bi-directional linked list
//
class Link_list {
  
  //---------------------------------------------------------------------------
  //
  // protected data
  //
  //---------------------------------------------------------------------------
protected:
  
  // link pointers
  //
  Link_node* head_d;                     // head of the filled link list
  Link_node* curr_d;                     // current position of the list

  // memory manager
  //
  static Memory_manager* manager_d;      // memory manager for the list

  //---------------------------------------------------------------------------
  //
  // public methods
  //
  //---------------------------------------------------------------------------
public:

  // required methods
  //
  char_1* name_cc();
  volatile void error_handler_cc(char_1* mname, char_1* msg);
  logical_1 debug_cc(FILE* fp, char_1* message);
  int_4 size_cc();
  
  // destructors/constructors
  //
  ~Link_list();
  Link_list();                                  // default
  Link_list(const Link_list& list);             // copy

  // methods to access memory manager
  //
  static logical_1 set_manager_cc(Memory_manager* manager) {
    manager_d = manager;
    return ISIP_TRUE;
  }
  
  static Memory_manager* get_manager_cc() {
    return manager_d;
  }

  // methods to set link pointers
  //
  logical_1 set_head_cc(Link_node* node);       // head link
  logical_1 set_curr_cc(Link_node* node);       // current link
  
  // methods to get link pointers
  //
  Link_node* get_head_cc() {
    return head_d;
  }
  
  Link_node* get_curr_cc() {
    return curr_d;
  }

  // methods to treat the list like a stack
  //
  logical_1 push_cc(Link_node* node);
  Link_node* pop_cc();
  
  // methods to manipulate links
  //
  logical_1 insert_cc(Link_node* node);
  logical_1 remove_cc(Link_node* node);         // remove node

  logical_1 insert_cc(void_p item)  {
    Link_node* node = manager_d->new_node_cc();
    node->set_item_cc(item);
    return insert_cc(node);
  }

  logical_1 remove_cc(void_p item);             // remove node with item

  // methods to traverse links
  //
  Link_node* get_prev_cc() {
    return curr_d->get_prev_cc();
  }
  
  Link_node* get_next_cc() {
    return head_d->get_next_cc();
  }

  Link_node* get_prev_cc(Link_node* node) {
    return node->get_prev_cc();
  }
  
  Link_node* get_next_cc(Link_node* node) {
    return node->get_next_cc();
  }

  //---------------------------------------------------------------------------
  //
  // private methods
  //
  //---------------------------------------------------------------------------
private:
  
};

// end of include file
//
#endif
