#ifndef _DMGROUP_H
#define _DMGROUP_H

#include "DataManager.h"
#include "ErrorHandler.h"
#include "array.h"

#define MaxDmGroupSize 32

/*
CLASS 
DmGroup

DESCRIPTION
DmGroup keeps track of which consumed DmObjects out of a group have been
written to. Unlike the DM_Group implementation, there is no upper limit
to the number of items in a DmGroup.

AUTHOR
Tom O'Reilly
*/
class DmGroup : public ErrorHandler
{
  public:

  ///////////////////////////////////////////////////////////////////
  // Constructor
  DmGroup();

  ~DmGroup();
  
  ///////////////////////////////////////////////////////////////////
  // Add item to group
  // [input] dmObject:  DmObject to be added to group
  Errno addItem(DmObject *dmObject);

  ///////////////////////////////////////////////////////////////////
  // Add item to group
  // [input] dmItem:  DM_Item to be added to group
  Errno addItem(DM_Item dmItem);

  ///////////////////////////////////////////////////////////////////
  // Delete item from group
  // [input] dmObject: dmObject to remove from group
  Errno deleteItem(DmObject *dmObject);

  ///////////////////////////////////////////////////////////////////
  // Delete item from group
  // [input] dmItem: dmItem to remove from group
  Errno deleteItem(DM_Item dmItem);

  ///////////////////////////////////////////////////////////////////
  // Load group changes. Returns TRUE if any items have changed. 
  // Must be called once before subsequent calls
  // calls to itemsChanged() or itemChanged().
  MBool getChanges();  

  ///////////////////////////////////////////////////////////////////
  // Returns TRUE if any items have changed
  MBool itemsChanged();

  ///////////////////////////////////////////////////////////////////
  // Returns TRUE if specified item has changed
  // [input] dmObject: DmObject to be checked 
  MBool itemChanged(DmObject *dmObject);

  ///////////////////////////////////////////////////////////////////
  // Returns TRUE if specified item has changed
  // [input] dmItem: DM_Item to be checked 
  MBool itemChanged(DM_Item dmItem);

  ///////////////////////////////////////////////////////////////////
  // Returns total number of items in group
  int nItems();

  ///////////////////////////////////////////////////////////////////
  // Returns nth DM_Item from group
  // [input] n: Index of DM_Item to get
  DM_Item item(unsigned n);

  // Get # of dm_groups (for debugging)
  int nSubGroups();

  
  protected:

  // SubGroup corresponds to an individual data manager group
  struct SubGroup
  {
    SubGroup();
    DM_Group id;
    int nItems;
    DM_Item items[MaxDmGroupSize];
    DWord changedBits;
  };
  
  SubGroup *newSubGroup();
  SubGroup *availableSubGroup();
  
  DynArray<SubGroup *> _subGroups;
};


#endif
