#ifndef VHDL_EXPORT_H
#define VHDL_EXPORT_H

#include <map>

#include "vhdl_export_trav.h"
#include "export.h"
#include "hub/hub.h"
#include "util/indent.h"
#include "hub/attr.h"
#include "hub/symfunc.h"

class VhdlExport: 
public VhdlExpTravClient,
public VhdlStructTravClient,
public Export {
    VhdlExpTrav traverser_;
	bool firstPort_;
	bool firstComponent_;

    static std::map < hub::AttrIndex <hub::PortProto>, std::string > portAttrMap;

    void initPortAttrMap (void);
    void havePortAttr (hub::PortProto*);

public:
    virtual void haveUnit (void);
    virtual void endUnit  (void);
    virtual void haveLibrary (hub::Library*);
    virtual void endLibrary  (hub::Library*);
    virtual void haveDesign (hub::Design*);
    virtual void endDesign  (hub::Design*);
    virtual void haveEntity (hub::Entity*);
    virtual void endEntity  (hub::Entity*);
    virtual void havePortProto (hub::PortProto*);
    virtual void haveArch (hub::Architecture*);
    virtual void endArch  (hub::Architecture*);
	virtual void havePortClause(void);
	virtual void endPortClause(void);

	virtual void haveNet (hub::Net*);
	virtual void haveNet (hub::StructArch* arch,hub::Net*);
    virtual void endNet  (hub::Net*);
    virtual void haveJoined (hub::Joinable*);
    virtual void havePort (hub::Port <hub::StructArch>*);
    virtual void haveInst (hub::Instance*);
	virtual void havePrimInst(hub::Instance*);

	virtual void haveComponent( hub::Entity* component );
	virtual void endComponent(void);

	hub::Name augmentNetName(hub::StructArch* arch,hub::Net* net);
	hub::Name generateNetName(hub::StructArch* arch,hub::Net* net);
	bool isPort(hub::Net* net);


public:
    virtual void operator() (std::ostream*, Export::Source*);

    VhdlExport (hub::Hub*);
    ~VhdlExport () {}
};
// ========== wrappers that introduce repr functions into exportMap =======
class VhdlSymFunc {
public:
	static const char* ftab [hub::SymFunc::fNull+1];
	static bool Represent (VhdlExport&, hub::SymFunc&);
	static int wantInit;
};
// ======================================================================================
class VhdlExpLang: public ExportLang {
public:
    static void enregister (void);
    VhdlExpLang (const std::string& n): ExportLang(n) {}
    Export* getExporter (hub::Hub& theHub) { return new VhdlExport (&theHub); }
    void getDefaults (hub::Hub* h, const std::string& fn, Export::Source&);
};

#endif
