#ifndef _REGISTRY_H
#define _REGISTRY_H

/*
* NIST STEP Core Class Library
* clstepcore/Registry.h
* April 1997
* K. C. Morris
* David Sauder

* Development of this software was funded by the United States Government,
* and is not subject to copyright.
*/

#include <sc_export.h>
#include "clstepcore/sdai.h"
#include "clutils/errordesc.h"
#include "clutils/sc_hash.h"
#include "clutils/Str.h"
#include "clstepcore/complexSupport.h"


// defined and created in Registry.cc
extern SC_CORE_EXPORT const TypeDescriptor * const  t_sdaiINTEGER;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiREAL;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiNUMBER;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiSTRING;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiBINARY;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiBOOLEAN;
extern SC_CORE_EXPORT const TypeDescriptor * const t_sdaiLOGICAL;

typedef struct Hash_Table * HashTable;

class Registry;
typedef void ( * CF_init )( Registry & ); //  pointer to creation initialization

class SC_CORE_EXPORT Registry {
    protected:
        HashTable primordialSwamp;    //  dictionary of EntityDescriptors
        HashTable active_schemas;     //  dictionary of Schemas
        HashTable active_types;       //  dictionary of TypeDescriptors
        ComplexCollect * col;         //  struct containing all complex entity info

        int entity_cnt,
            all_ents_cnt;
        HashEntry   cur_entity;
        HashEntry   cur_schema;
        HashEntry   cur_type;

        // used by AddEntity() and RemoveEntity() to deal with renamings of an
        // entity done in a USE or REFERENCE clause - see header comments in
        // file Registry.inline.cc
        void        AddClones( const EntityDescriptor & );
        void        RemoveClones( const EntityDescriptor & );

    public:
        Registry( CF_init initFunct );
        ~Registry();
        void DeleteContents();   // CAUTION: calls delete on all the descriptors

        const EntityDescriptor * FindEntity( const char *, const char * = 0,
                                             int check_case = 0 ) const;
        const Schema * FindSchema( const char *, int check_case = 0 ) const;
        const TypeDescriptor  * FindType( const char *, int check_case = 0 ) const;

        void    AddEntity( const EntityDescriptor & );
        void    AddSchema( const Schema & );
        void    AddType( const TypeDescriptor & );

        void    RemoveEntity( const char * );
        void    RemoveSchema( const char * );
        void    RemoveType( const char * );

        int    GetEntityCnt();
        int    GetFullEntCnt() {
            return all_ents_cnt;
        }

        void    ResetEntities();
        const EntityDescriptor   *  NextEntity();

        void    ResetSchemas();
        const Schema   *  NextSchema();

        void        ResetTypes();
        const TypeDescriptor    *   NextType();

        const ComplexCollect * CompCol() {
            return col;
        }
        void        SetCompCollect( ComplexCollect * c ) {
            col = c;
        }

        SDAI_Application_instance * ObjCreate( const char * nm, const char * = 0,
                                               int check_case = 0 ) const;
};

#endif  /*  _REGISTRY_H  */
