//------------------------------------------------------------------------------
// Copyright (c) 1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//------------------------------------------------------------------------------
//
// description: cdevTagTable.h
//	cdevTagTable class manages tags within the cdev system.
//
// Author:  Danjin Wu & Walt Akers
//
// Revision History:
//   cdevTagTable.h,v
// Revision 1.12  1997/08/01  19:06:30  akers
// Added addTag and tagExists feature to the library
//
// Revision 1.11  1996/10/25  20:10:02  chen
// add asciiDump
//
// Revision 1.10  1996/08/26  19:14:07  akers
// Adding cdevData.inserttag callback capabilities
//
// Revision 1.9  1996/07/17  13:57:56  chen
// using CDEVTAGTABLE to find tags
//
// Revision 1.8  1995/10/03  19:37:11  chen
// Change back to object instead of pointers
//
// Revision 1.7  1995/09/29  15:25:55  danjin
// declare hash entry as pointer
//
// Revision 1.6  1995/09/28  19:01:48  danjin
// change: declare a ptr to list -> declare a list
//
// Revision 1.5  1995/08/21  18:02:48  danjin
//  empty message
//
// Revision 1.3  1995/08/21  16:40:23  danjin
// modify comment
//
// Revision 1.2  1995/08/21  16:38:10  danjin
//  modified big partion of this file
//
// Revision 1.1  1995/08/21  15:47:24  danjin
// merge Slist and hash into one for cdev
//
//
//                                       
#ifndef _CDEV_TAG_TABLE_H
#define _CDEV_TAG_TABLE_H

#include <stdlib.h>
#include <cdevSpec.h>
#include <cdevIntHash.h>
#include <cdevStrHash.h>


// *****************************************************************************
// * class cdevTagTableCallback :
// *	This class is used by the caller to post a callback to be notified 
// *	when changes are posted to a cdevTagTable.  The class also has 
// *	a next pointer to allow it to be placed in a linked list within the
// *    cdevTagTable... 
// *
// *	Note: Since this is a abstract base class, the caller must create a 
// *	class based on this class that has the callback method defined...
// *	Also the destructor here is defined as virtual to force the delete
// *	mechanism to work its way up the class hierarchy to the top level 
// *	before calling the destructor...
// *****************************************************************************
class CDEV_CLASS_SPEC cdevTagTableCallback
{
friend class cdevTagTable;
private:
	cdevTagTableCallback *next_;
public:
	cdevTagTableCallback ( void ) : next_(NULL) {}
	virtual ~cdevTagTableCallback (void) {}
	virtual void callback (int newTag, char *newName) = 0;
};


struct cdevTagEle {
  char *tagName;
  int  tagId;
};
typedef struct cdevTagEle cdevTagEle;

class CDEV_CLASS_SPEC cdevTagTable 
{
public:
  cdevTagTable ( void );
  
  ~cdevTagTable ( void )
    {
      freeMemory ();
#ifdef _CDEV_DEBUG
      printf("Destroying a cdevTagTable object\n");
#endif
    }
  
  int  tagC2I    (char* ctag, int*  tag);  
  int  tagI2C    (int    tag, char* &ctag);  
  void insertTag (int    tag, char* ctag);
  int  tagExists (char *ctag);
  int  tagExists (int    tag);  
  int  addTag    (char *ctag);
  
  // *************************************************
  // * addTagCallback :
  // *	This method will add a cdevTagTableCallback
  // *	object to the list of classes that should be 
  // *	notified each time a tag is added to the
  // *	cdevTagTable.
  // *************************************************
  void addTagCallback ( cdevTagTableCallback * cb );

  // *************************************************
  // * delTagCallback :
  // *	This method will remote a cdevTagTableCallback
  // *	object that was previously added to the list
  // *	of callback classes.
  // *
  // *	Note:	This method does not actually delete 
  // *		the cdevTagTableCallback object, it 
  // *		merely removes it from the list.  It 
  // *		is the responsibility of the owner to 
  // *		delete the object when it is no longer 
  // *		needed.
  // *************************************************
  void delTagCallback ( cdevTagTableCallback * cb );

  // *************************************************
  // * readTagTable :
  // *	This method allows the caller to obtain a list
  // *	of tag names and integers that are currently
  // *	stored in this tag table.  
  // *
  // *	Note:	This method will allocate an array of
  // *		integers and an array of character 
  // *		string pointers.  The strings that 
  // *		are stored in the string array will be 
  // *		the actual strings from within the
  // *		tag table and should not be deleted...
  // *
  // *		The data allocated becomes the property
  // *		of the caller and must be deleted when 
  // *		it is no longer needed... the correct 
  // *		syntax to delete these items is...
  // *
  // *			delete tags;
  // *			delete ctags;
  // *
  // *		This will delete the array, however, 
  // *		it will leave the individual array 
  // *		elements intact.
  // *************************************************
  int  readTagTable   ( int * &tags, char ** &ctags, int &ntags );      

  // *************************************************
  // * asciiDump (FILE* fp = stdout);
  // * dump information of tag table to a file with two columns
  // * left column is tag value, right column is tag string
  // *************************************************
  void asciiDump (FILE* fp = stdout);
    
protected:
  void freeMemory (void);
  void initialize ( void ); 
  // data area
  cdevIntHash            itagList_;
  cdevStrHash            stagList_;
  cdevTagTableCallback * callbacks_;
  int                    highestTag;

private:
  // default tag name if there is no tag file
  static char*         defaultTags[];
  static unsigned int  numberDefTags;
  static char*         defaultTagTableLocation;
  static char*         tagTableEnv;
  
  // parse tag table file, return 0: failure, return 1: success
  // caller free all memory upon success
  static int           parseTagTable (char* file, char** &tags, int* &tagvalues,
				      unsigned int &numTags);
};
#endif	/* _CDEV_TAG_TABLE_H */

