#include "trav.h"
#include "err.h"
#include <string>
using namespace hub;
//---------------------------------------------------------------------------
void Traverser :: operator () (void) {
    client_->haveUnit ();
    Hub :: LibIter li;
    if (theLib_) {
	travLib (theLib_);
    } else {
	for (li = theHub_->LibBeg(); li != theHub_->LibEnd(); li++) {
	    travLib (li->second);
	}
	Hub::DesignIter di;
	for (di = theHub_->DesignBeg(); di != theHub_->DesignEnd(); di++) {
	    client_->haveDesign (di->second);
	    client_->endDesign (di->second);
	}
    }
    client_->endUnit  ();
}
//---------------------------------------------------------------------------
void  Traverser :: travLib (hub::Library* lib) {
    Library :: EntIter ei;
    client_->haveLibrary (lib);
    if (theEntity_) {
	travEnt (theEntity_);
    } else {
	for (ei = lib->EntBeg(); ei != lib->EntEnd(); ei++) {
	    travEnt (ei->second);
	}
    }	    
    client_->endLibrary (lib);
}
//---------------------------------------------------------------------------
void  Traverser :: travEnt (hub::Entity* ent) {
    Entity :: PortProtoIter ppi;
    Entity :: ArchIter ai;
    client_->haveEntity (ent);
    for (ppi = ent->PortProtoBeg(); ppi != ent->PortProtoEnd(); ppi++) {
	client_->havePortProto (ppi->second);
    }
    if (theArch_) {
	client_->haveArch (theArch_);
	client_->endArch  (theArch_);
    } else {
	for (ai = ent->ArchBeg(); ai != ent->ArchEnd(); ai++) {
	    client_->haveArch (ai->second);
	    client_->endArch (ai->second);
	}
    }
    client_->endEntity (ent);
}
//---------------------------------------------------------------------------
void TraverserClient :: haveUnit (void) {}
void TraverserClient :: endUnit  (void) {}
void TraverserClient :: haveLibrary (Library*) {}
void TraverserClient :: endLibrary  (Library*) {}
void TraverserClient :: haveDesign (Design*) {}
void TraverserClient :: endDesign  (Design*) {}
void TraverserClient :: haveEntity (Entity*) {}
void TraverserClient :: endEntity  (Entity*) {}
void TraverserClient :: havePortProto (PortProto*) {}
void TraverserClient :: haveArch (Architecture*) {}
void TraverserClient :: endArch  (Architecture*) {}
//---------------------------------------------------------------------------
TraverserClient :: ~TraverserClient () { }
// ==========================================================================
void StructArchTraverser :: travNets (void) {
    StructArch :: NetIter ni;
    Net :: JoinIter ji;
    for (ni = archImpl_->NetBeg(); ni != archImpl_->NetEnd(); ni++) {
	client_->haveNet (ni->second);
	for (ji = ni->second->JoinBeg(); ji != ni->second->JoinEnd(); ji++) {
	    client_->haveJoined (*ji);
	}
	client_->endNet (ni->second);
    }
}
//---------------------------------------------------------------------------
void StructArchTraverser :: travPorts (void) {
    StructArch :: PortIter pi;
    for (pi = archImpl_->PortBeg(); pi != archImpl_->PortEnd(); pi++) {
	client_->havePort (*pi);
    }
}
//---------------------------------------------------------------------------
void StructArchTraverser :: travPorts (const PortProto::flagsType&) {
}
//---------------------------------------------------------------------------
void StructArchTraverser :: travInsts (void) {
    StructArch :: InstIter ii;
    for (ii = archImpl_->InstBeg(); ii != archImpl_->InstEnd(); ii++) {
	client_->haveInst (ii->second);
    }
}
//---------------------------------------------------------------------------
void StructArchTravClient :: haveNet (hub::Net*) {}
void StructArchTravClient :: endNet  (hub::Net*) {}
void StructArchTravClient :: haveJoined (hub::Joinable*) {}
void StructArchTravClient :: havePort (hub::Port <StructArch>*) {}
void StructArchTravClient :: haveInst (hub::Instance*) {}
//---------------------------------------------------------------------------
StructArchTravClient :: ~StructArchTravClient () {}
