/*****************************************************************************
* 	Project 	: Network Based Message Queue System		    **
*	Course		: CIS 650 - Software Engineering		    **
*	Location 	: /research/paraducks3/courses/cis650/proj/rt	    **
*	File		: rtwl.cc					    **
*	Description 	: Wait list description				    **
*****************************************************************************/
#include <rtincl.h>

WaitItem::WaitItem(int ty,int sockId) 
{
  type=ty;
  sockFd=sockId;
}

WaitItem::WaitItem(int ty) 
{
  type=ty;
}


WaitListItem:: WaitListItem(int ty, int sfd) 
{
  waitItemPtr=new WaitItem(ty,sfd);
  next=0;
}



WaitListItem:: WaitListItem(int ty) 
{ 
  waitItemPtr=new WaitItem(ty);
  next=0;
}

WaitListItem::WaitListItem() {
  next=0;
}
WaitList::WaitList() 
{
  counter=first=last=0;countItem=0;
}

void WaitList::add_item(int key,int sockId) /* add an item of type key and 
                                            and socket descriptor sockID */
{ 
  WaitListItem *waitListItem=new WaitListItem(key,sockId);
  /* if the list is empty then add the item to the list and adjust counter
  to point to the head of the list */
  if (is_empty()) {         
    first=last=waitListItem;
    counter=first;
  }
  else       /* list is not empty */
    {
      last->next=waitListItem; /* add the item to the tail of the list */
      last=waitListItem;    /* set tail to the last item addded */
    }
  countItem++;
  return;
}

void WaitList::reset()  /* reset the counter to the head so that 
                     another iteration can be done */
{
  counter=first;
}

int WaitList::get_count_of_waiting_processes() 
{
  return countItem;
} 
void WaitList::check_and_delete(int sockId) 
{
 /* temp points to an element of the list and prev points to 
  a previous element */
  WaitListItem* temp=first,*prev=0;
  while (temp!=0)   /* while we are not at the end of the list */
    {
      if (temp->waitItemPtr->sockFd==sockId) /* if we have found the item */
	{ if (prev==0)    /* if the first element is what we are looking for*/
            first=temp->next;  /* make first point to the next element of the*/
	else                   /* list*/
	  prev->next=temp->next; /* else make prev point to temp's successor*/
        if (temp==last) last=prev ;/* if the last element is the target */
	  delete (temp);           /* update last and delete temp anyway */
            countItem--;           /* update the count */
        	  return;
	}
      else
        temp=temp->next;
    }
  return;
} 
  
WaitItem* WaitList::delete_item(int key)    /* delete an item of key type */
{ if (first==0) return 0;    /* if list is empty return null */
 /* if the first element has type =key then return the waitItem
   and reset first */
  if ((first->waitItemPtr)->type==key) 
    { WaitItem* waitPtr=first->waitItemPtr; /* store the item required*/
      if (last==first)  /* list has only one element */
	{      
	  first=first->next;
	  last=first;
        }
      else first=first->next;  /* else check the next element */
       countItem--;    
        return waitPtr;       /* return the item */
    }
  else /* the first element is not what we are looking for */
    {
      WaitListItem  *prev,*temp;
      temp=first;prev=0; /* prev points to the item immediately before temp*/
      while (temp!=0)       /* while we are not at the end of the list */
	{
      /* if we find the item then  set prev's successor to the successor 
     of temp and remove temp from the list */
	  if ((temp->waitItemPtr)->type==key)  
	    { WaitItem* waitPtr=temp->waitItemPtr;
	      prev->next=temp->next;
	      if (last==temp) last=prev;
              countItem--;
	      return waitPtr;
	    }
	  else 
	    { /* move on to the next item on the list */
	      prev=temp;
              temp=temp->next;
            }
	}
    }
  return 0;                         
}

int WaitList::is_empty() 
{
  return (first==0);
}             
                       
WaitItem*  WaitList::next() 
{                         /* return the next socket descriptor */
  if (first=0) { /* list os empty */
    return 0;}
  if (counter==0) 
    { 
      counter=first ;return 0;
    }
  WaitItem* temp= counter->waitItemPtr;
  counter=counter->next;

  return temp;
}
         


