/***********************************************************************
**
**   limitedlist.h
**
**   This file is part of Cumulus.
**
************************************************************************
**
**   Copyright (c):  2002 by André Somers
**
**   This file is distributed under the terms of the General Public
**   Licence. See the file COPYING for more information.
**
**   $Id: limitedlist.h,v 1.7 2004/02/28 23:04:57 andre Exp $
**
***********************************************************************/

#ifndef LIMITEDLIST_H
#define LIMITEDLIST_H

#include <qlist.h>

/**
  *@author André Somers
  * @short Template for a list which limits the number of items it contains.
  *
  * The LimitedList template class implements a QList-based list with a
  * limited number of items. If more items are added, the least important
  * item will be deleted automaticly. The item to delete it determined by
  * the getLeastImportantItem() memberfuntion, wich may be overridden by
  * child classes if needed. The default implementation removes the oldest
  * item from the list.
  */

template <class type>
class LimitedList : public QList <type> {

public:  
  LimitedList(uint limit=10);
  virtual ~LimitedList();
  /**
    * add should be used to add items to the list. It automaticly checks if
    * it needs to delete an item afterwards.
    */
  void add( const type *d );
  void setLimit(uint limit);     
  
protected:
  /**
   * getLeastImportantItem is called to identify the item that should be
   * removed if the list is too full. It may be overridden if you need
   * another criteria than simply deleting the oldest item in the list.
   */
  virtual uint getLeastImportantItem();
  
  
private:
  uint _limit;
};


/**
  * IMPLEMENTATION
  * ====================================================================
  *
  * The implementation is stored in the header file because that's the
  * only way it will compile without linkererrors. This has to do with
  * the fact that it's a template. See:
  *  http://www.ecs.fullerton.edu/~sowell/cs331/TemplateClasses.html
  * for information on the how and why.
  */
  


template <class type>
LimitedList<type>::LimitedList(uint limit){
  _limit=limit;
  QList<type>::setAutoDelete(true);
}

template <class type>
LimitedList<type>::~LimitedList(){
}

template <class type>
void LimitedList<type>::add( const type *d ){
  QList<type>::prepend(d);
  if (QList<type>::count()>_limit) {
    uint o = getLeastImportantItem();
    if (o<QList<type>::count())
      QList<type>::remove(o);
  }
}

template <class type>
uint LimitedList<type>::getLeastImportantItem(){
  return QList<type>::count()-1;
}

template <class type>
void LimitedList<type>::setLimit(uint limit){
  //set new limit
  _limit=limit;

  //make sure the list is not longer than the new limit
  while (QList<type>::count()>_limit) {
    uint o=getLeastImportantItem();
    if (o>QList<type>::count())
      break;  //make sure we don't end up in an endless loop
    QList<type>::remove(o);
  }
}

#endif

