#ifndef VHDL_IMPORT_H
#define VHDL_IMPORT_H

#include <string>
#include <list>

#include "hub/hub.h"
#include "hub/structural.h"
#include "hub/attr.h"
#include "vhdl_bison_parser.hpp"
#include "hub/named.h"
#include "import.h"
#include "hub/location.h"
#include "hub/symfunc.h"
#include "hub/named.h"

class VhdlImport: public VhdlParserClient, public Import {
    
    VhdlParser parser_;
    // ---------------- locations ----------------------------------------------------
    hub::Location dest_;
    hub::Location synth_;
    hub::Location* toplevel_;

	// ---------------- other context ------------------------------------------------
	hub::StructArch*    theArchImpl_;		    // current structure
	hub::Entity*		theComponent_;		    // current component (declaration)
	hub::number_t		compPortsCount_;		// port count of current component 
    hub::Instance*      theInstance_;
	hub::Joinable* lastPort_;
			      
protected:
    // ---- interface to semantic classes
	virtual void haveUnit(void);
	virtual void endUnit(void);
	virtual void haveEntity( const StringToken& entName );
	virtual void endEntity(void);
	virtual void havePort(InterfaceDecl& intDecl );
	virtual void haveArch(const StringToken& archName,const StringToken& entName );
	virtual void endArch(const StringToken& archName ="" );
		//signal declaration
	virtual void haveSignalDeclar( InterfaceDecl intDecl );
		//component declaration
	virtual void haveComponent(const StringToken& compName);
	virtual void endComponent(const StringToken& compName);
	virtual void haveComponentPort(InterfaceDecl& intDecl );
		// component instantion
	virtual void haveComponentInst(const StringToken& label, const StringToken& compName,const StringToken& archName);
	virtual void havePortAssoc(const StringToken& compPortName,const StringToken& NetName);
	virtual void havePosPortAssoc(int portPosition, const StringToken& NetName);
	virtual void endComponentInst(void);
		//signal_assignment
	virtual StringToken* haveSymFunc(const std::list<StringToken> listInputNames,
		const std::string& func, bool createNet = true);
	virtual void haveOperand(const StringToken& portName ); 
	virtual void haveSignalAssignment(StringToken targetName, Expr* waveform );
	void paramsCheck (void);
	const hub::PortProto::flagsType&  DecodeDir( const Mode m ); 
	static hub::SymFunc::Func decodeFunc ( const std::string& func); 


public:
    // ---- import method
    virtual void operator() (std::istream*, const std::string&, Import::Destinations&);
    VhdlImport (hub::Hub* h): parser_(this), dest_(h), synth_(h)  {}
   ~VhdlImport () {}
};
// ==========================================================================
class VhdlImpLang: public ImportLang {
public:
    static void enregister (void);
    VhdlImpLang (const std::string& n): ImportLang(n) {}
    Import* getImporter (hub::Hub* theHub) { return new VhdlImport (theHub); }
    void getDefaults (hub::Hub*, const std::string&, Import::Destinations&);
};

#endif
