#ifndef cmHashTbl_h
#define cmHashTbl_h

#ifdef __cplusplus
extern "C" {
#endif

  enum
  {
    kOkHtRC,
    kLHeapFailHtRC,
    kHashFaultHtRC,
    kInvalidIdHtRC
  };

  typedef cmRC_t cmHtRC_t;
  typedef cmHandle_t cmHashTblH_t;
  extern cmHashTblH_t cmHashTblNullHandle;
  
  cmHtRC_t cmHashTblCreate( cmCtx_t* ctx, cmHashTblH_t* hp, unsigned bucketCnt );

  cmHtRC_t cmHashTblDestroy( cmHashTblH_t* hp );

  bool cmHashTblIsValid( cmHashTblH_t h );

  // cmhashTblStoreBase() is the canonical store function.
  // Set 'staticFl' to true if the value does not need to be reallocated
  // and copied into the internal storage space.
  // Returns a value which uniquely identifies the value.  If a unique
  // identifier cannot be generated then the function returns cmInvalidId
  // and sets the hash table error code to kHashFaultRC.
  unsigned cmHashTblStoreBase(      cmHashTblH_t h, void* v, unsigned byteCnt, bool staticFl );
  
  unsigned cmHashTblStore(          cmHashTblH_t h, void* v, unsigned byteCnt );
  unsigned cmHashTblStoreStatic(    cmHashTblH_t h, void* v, unsigned byteCnt );
  unsigned cmHashTblStoreStr(       cmHashTblH_t h, const cmChar_t* s );
  unsigned cmhashTblStoreStaticStr( cmHashTblH_t h, const cmChar_t* s );
  unsigned cmHashTblStoreV(         cmHashTblH_t h, const cmChar_t* fmt, va_list vl );
  unsigned cmHashTblStoreF(         cmHashTblH_t h, const cmChar_t* fmt, ... );
  
  // Given a value find an id.
  unsigned cmHashTblId( cmHashTblH_t h, const void* value, unsigned byteCnt );
  unsigned cmHashTblStrToId( cmHashTblH_t h, const cmChar_t* str );

  // Returns NULL if no value is associated with 'id'.
  // 'byteCntRef' is optional.
  const void* cmHashTblValue( cmHashTblH_t h, unsigned id, unsigned* byteCntRef );

  // Wrapper around cmHashTblValue() which assumes that the stored value is a 
  // zero terminated string.
  const cmChar_t* cmHashTblStr( cmHashTblH_t h, unsigned id );

  // Remove a value.
  cmHtRC_t cmHashTblRemove( cmHashTblH_t h, unsigned id );

  // Return the last error id generated by the cmHashTbl object.
  cmHtRC_t cmHashTblLastRC( cmHashTblH_t h );
  
  void cmHashTblReport( cmHashTblH_t h, cmRpt_t* rpt );

  cmHtRC_t cmHashTblTest( cmCtx_t* ctx );

#ifdef __cplusplus
}
#endif

#endif
