/************************************************************************/
/* File   : llist.c				                        */
/* Purpose: linked list  module             	                        */
/* By     : Keith R. Davis				                */
/* Date   : 12/27/95				                        */
/* Notes  : Copyright(c) 1996 White River Software		        */
/************************************************************************/

#include <Xm/Xm.h>			/* motif lib header		*/
#include <Xm/MessageB.h>		/* message box header		*/
#include <Xm/Text.h>	          	/* text widget header		*/
#include <string.h>			/* string header		*/
#include <stdio.h>                      /* stdio header                 */

#include "mquel.h"                      /* mquel header                 */
#include "llist.h"                      /* linked list header           */
#include "db.h"                         /* db header                    */

LLISTbuffer *buffer_head;   /* buffer list head                     */
LLISTbuffer *buffer_tail;   /* buffer list tail                     */
LLISTbuffer *buffer_curr;   /* current pos in buffer list           */

/************************************************************************/
/* Function: LLIST_Init                                                 */
/* Purpose : inits the linked list of buffers                           */
/* Params  :                                                            */
/* Returns : ptr to list tail  on SUCCESS / NULL on FAILURE             */
/* Notes   :                                                            */
/************************************************************************/

LLISTbuffer* LLIST_Init(void)
{
  if((buffer_head = (LLISTbuffer*)XtMalloc(sizeof(LLISTbuffer))) == NULL)
     return NULL;

  if((buffer_tail = (LLISTbuffer*)XtMalloc(sizeof(LLISTbuffer))) == NULL){
    XtFree((char*)buffer_head); 
    return NULL;
  }

  buffer_head->buffer = XmCreateText(AppWidgetsPtr->shell, NULL, NULL, 0);
  buffer_head->next = buffer_tail;
  buffer_head->prev = buffer_head;
  buffer_tail->next = buffer_tail;
  buffer_tail->prev = buffer_head;

  buffer_curr = buffer_tail;

  return buffer_curr;
}

/************************************************************************/
/* Function: LLIST_Delete                                               */
/* Purpose : deletes a buffer node from the linked list                 */
/* Params  : node : ptr to node to delete                               */
/* Returns :                                                            */
/* Notes   :                                                            */
/************************************************************************/

void LLIST_Delete(LLISTbuffer *node)
{
  if(((node == buffer_head) && (node->next != buffer_tail)) ||
     ((node == buffer_tail) && (node->prev != buffer_head))){
    return;
  }
  else if(((node == buffer_head) && (node->next == buffer_tail)) ||
	  ((node == buffer_tail) && (node->prev == buffer_head))){
    return;
  }
  else {
    if(buffer_curr == node)
      buffer_curr = node->prev;
    node->next->prev = node->prev;
    node->prev->next = node->next;
    XtDestroyWidget(node->buffer);
    XtFree(node->filename);
    XtFree((char*)node);
  }
}

/************************************************************************/
/* Function: LLIST_Insert                                               */
/* Purpose : inserts a buffer node into the linked list                 */
/* Params  : mod : modified flag 0=FALSE / 1=TRUE                       */
/*           file: buffer's associated filename                         */ 
/*           node : ptr to node to insert before                        */
/* Returns : ptr to inserted node                                       */
/* Notes   :                                                            */
/************************************************************************/

LLISTbuffer* LLIST_Insert(int mod, char *file, LLISTbuffer *node)
{
  LLISTbuffer *insert;

  if((insert = (LLISTbuffer*)XtMalloc(sizeof(LLISTbuffer))) == NULL)
    return NULL;

  if((insert->filename = (char*)XtMalloc(sizeof(char)*MAX_PATH_LEN)) == NULL){
    XtFree((char*)insert);
    return NULL;
  }

  insert->buffer = XmCreateText(AppWidgetsPtr->shell, NULL, NULL, 0);
  
  insert->modified = mod;
  strcpy(insert->filename, file);
  insert->next = node;
  insert->prev = node->prev;
  node->prev->next = insert;
  node->prev = insert;
  return insert;
}

/************************************************************************/
/* Function: LLIST_Remove                                               */
/* Purpose : destroys the linked list                                   */
/* Params  :                                                            */
/* Returns :                                                            */
/* Notes   :                                                            */
/************************************************************************/

void LLIST_Remove(void)
{
  while(buffer_head->next != buffer_tail)
    LLIST_Delete(buffer_head->next);
  
  buffer_curr = NULL;

  XtFree((char*)buffer_head);
  XtFree((char*)buffer_tail); 
}

/************************************************************************/
/* Function: LLIST_Count                                                */
/* Purpose : returns the count of nodes in the linked list              */
/* Params  :                                                            */
/* Returns : count of nodes in the list                                 */
/* Notes   :                                                            */
/************************************************************************/

int LLIST_Count(void)
{
  int count = 0;
  LLISTbuffer *trav_ptr = buffer_head->next;

  while(trav_ptr != buffer_tail){
    count++;
    trav_ptr = trav_ptr->next;
  }
  return count;
}

/************************************************************************/
/* Function: LLIST_Get                                                  */
/* Purpose : returns a list node by index                               */
/* Params  : index : position of node in list rel to the head           */
/* Returns : ptr to the node                                            */
/* Notes   :                                                            */
/************************************************************************/

LLISTbuffer* LLIST_Get(int index)
{
  int count = LLIST_Count();
  int i = 1;
  LLISTbuffer *node = buffer_head->next;

  if(index > count)
    return NULL;

  while(i < index){
    i++;
    node = node->next;
  }
  return node;
}




