#ifndef HUB_H
#define HUB_H
// =====================================================================
//	Base data structure for gate-level circuit description
//	J Schmidt CTU Prague
//	Based on refactored code by J Kozak CTU Prague
// =====================================================================

#include "named.h"
#include "attr.h"
#include "entity.h"
#include "behavioral.h"
namespace hub {
#ifdef __BCPLUSPLUS__
template <> int AttrUnique <Architecture> :: base=0;
#endif

// =====================================================================
//	Library
//	a named collection of entities
//----------------------------------------------------------------------
class Hub;
class Library: public NameHaving {
    NameSpace <Entity> entities_;
    Hub* parent_;
// ---------------------------------------    
// 	the library shall work with EXTERNAL heuristics
// 	for comparison and creation and be therefore able 
//	to serach for a cell with given functionality
//	or even create it given any data that the external heuristics can use
// --------------------------------------------
    
public:
    Library (const std::string& name): NameHaving (name) {}
    virtual ~Library () {}
    Hub* Parent (void) { return parent_; }
    void Parent (Hub* h) { parent_=h; }

// -------------- find by name ----------------
    Entity* FindOrCreateEntity (const std::string& entn);
    Entity* FindEntity (const std::string& entn) 
		{ return  entities_.Find (entn); }

// -------------- find by function ------------
	Architecture* FindArch (BehavAgent&, const std::string kind);

// -------------- create ----------------------
	Entity* CreateEntity (const std::string& entn);
	Entity* CreateUniqueEntity (const std::string& entn); 

// --------------------------------------------
//	iterator support
//	very weak encapsulation
// --------------------------------------------	
    typedef NameSpace <Entity> :: const_iterator EntIter;
    EntIter EntBeg (void) { return entities_.begin (); }
    EntIter EntEnd (void) { return entities_.end (); }
};
// =====================================================================
//	design is a named entity reference
//	design name is not! an entity name
//---------------------------------------------------------------------
class Design: public NameHaving {
protected:
    Entity* entity_;
public:
    Design (const std::string& name, Entity* ent): NameHaving (name), entity_ (ent) {}
    virtual ~Design () {}
    Entity* DesignEntity (void) { return entity_; }
    void DesignEntity (Entity* e) { entity_ = e; }
};
// =====================================================================
//	a data base, or a Hub, is a collection of designs and libraries
//---------------------------------------------------------------------
class Hub: public NameHaving {
    typedef NameSpace <Library> LibSpace;
    typedef NameSpace <Design>  DesignSpace;

    LibSpace libs_;
    DesignSpace  designs_;	// references to existing cells

public:

    Hub (const std::string& name = std::string ("")): NameHaving (name) {}
    virtual ~Hub () {}
    Library* FindOrCreateLib (const std::string& libn) { 
	Library* lib = libs_.FindOrCreate <Library>(libn);
	if (lib) lib->Parent(this); 
        return lib;
    }
    Library* FindLib         (const std::string& libn) { return libs_.Find (libn); }
    Design*  CreateDesign    (const std::string& desn, Entity*, Library*);
    Design*  FindDesign      (const std::string& desn) { return designs_.Find (desn); }

    typedef LibSpace :: const_iterator LibIter;
    LibIter LibBeg (void) { return libs_.begin (); }
    LibIter LibEnd (void) { return libs_.end (); }

    typedef DesignSpace :: const_iterator DesignIter;
    DesignIter DesignBeg (void) { return designs_.begin (); }
    DesignIter DesignEnd (void) { return designs_.end (); }
};

}

#endif
