// File: compList.h
//
// This class was designed by Chris Orth for testing the WFD readout.
// Lists of wfd channels requested by erp, tohm, etc are easily checked
// against lists of wfd channels in the event with the routines here.
// These routines also make the reverse checks easier.
//
// These routines are general enough to be used anywhere that Lists of
// integers need to be combined and searched
//
// member functions:
// size()             : return the number of elements in a list
// get(n)             : get the nth member, between 0 and size()-1 
// append(int)        : add an integer to the end of the list
// append(compList)   : add a List to the end of the list
// exAppend(int)      : add int to list if not already there
// exAppend(compList) : add members of list that aren't already there
// insert(int)        : add an integer to the beginning of the list
// insert(compList)   : add a list to the beginning of a list
// sort()             : sort a list lowest to highest
// contains(int)      : returns true if int is in list
// contains(compList) : returns true if entire argument list is in base list
//

struct dList { 
  int val;
  dList *next;
  dList *last;
  ~dList(){ delete next;}
};

class compList {
  dList* top;
  dList* bottom;
  
public:
  compList()
  {
    top=bottom=0;
  }
  ~compList(){delete top;}

  // routines to let the user navigate the list
  int size()
  {
    dList* temp;
    int length=0;
    for(temp=top; temp!=0 ;temp=temp->next)length++;
    return length;
  }
  int get(int num)
  {
    dList* temp;
    int i=0;
    for(temp=top; temp!=0 ;temp=temp->next)
    {
      if(i==num)return temp->val;
      i++;
    }
    cout << "compList.cc: attempted to access beyond list bound" << endl;
  }

// routines to let the user add to the list
  void insert(int b)
  {
    dList* c= new dList; 
    if(top!=0)
    {
      c->next=top;
      c->last=0;
      c->val=b;
      top->last=c;
      top=c;
    }
    else
    {
      bottom=top=c;
      top->last=0;
      top->next=0;
      top->val=b;
    }
  }

  void append(int b)
  {
    dList* c = new dList;
    if(bottom!=0)
    {
      c->val=b;
      c->next=0;
      c->last=bottom;
      bottom->next=c;
      bottom=c;
      c=0;
    }
    else
    {
      bottom=top=c;
      top->last=0;
      top->next=0;
      top->val=b;
      c=0;
    }
  }

  void append(compList& b)
  {
    int length=b.size();
    for(int listNum=0; listNum<length ; listNum++)append(b.get(listNum));
  }    
  void exAppend(int b)
  {
    if(!contains(b))append(b);
  }

  void exAppend(compList& b)
  {
    int length=b.size();
    for(int listNum=0; listNum<length ; listNum++)
      if(!contains(b.get(listNum)))append(b.get(listNum));
  }    
  
  // routines to tell the user something about the list
  bool contains(int b)
  {
    dList* temp=top;
    while(temp!=0)
    {
      if(temp->val==b)return true;
      temp=temp->next;
    }
    return false;
  }

  bool contains(compList& b)
  {
    int length=b.size();
    for(int listNum=0; listNum<length ; listNum++)
    {
      if(!contains(b.get(listNum)))return false;
    }
    return true;
  }

  void diff(compList& b, compList& c)
  {
    dList* temp=top;
    while(temp!=0)
    {
      if(!(b.contains(temp->val)))c.append(temp->val);
      temp=temp->next;
    }
  }

  void sort()
  {
    int i;
    int store;
    dList* temp;
    for(i=0; i<size(); i++)
    {
      temp=top;
      while(temp!=0)
      {
	if(temp->next!=0)
	{
	  if(temp->val>temp->next->val)
	  {
	    store=temp->val;
	    temp->val=temp->next->val;
	    temp->next->val=store;
	  }
	}
	temp=temp->next;
      }
    }
  }
//  compList* diff(compList* b);
//  compList* sumdiff(compList* b);
//  void sort();

  virtual inline void print(ostream& o)
  {
    dList* temp=top;
    while(temp!=0)
    {
      o << temp->val << endl;
      temp=temp->next;
    }
  }
      
};
