#include "location.h"
using namespace hub;
// ----------------------------------------------------------------------------
Location :: Location (Architecture * arch) :
theArch_  	(arch),			fixedArch_(true),
theEntity_ 	(theArch_->Parent()),	fixedEntity_(true),
theLib_ 	(theEntity_->Parent()), fixedLib_(true),
theHub_ 	(theLib_->Parent())
{}
Location :: Location (Entity* ent) :
theArch_  	(NULL),			fixedArch_(false),
theEntity_ 	(ent),			fixedEntity_(true),
theLib_ 	(theEntity_->Parent()), fixedLib_(true),
theHub_ 	(theLib_->Parent())
{}
Location :: Location (Library* lib) :
theArch_  	(NULL),			fixedArch_(false),
theEntity_ 	(NULL),			fixedEntity_(false),
theLib_ 	(lib),			fixedLib_(true),
theHub_ 	(theLib_->Parent())
{}
Location :: Location (Hub* h) :
theArch_  	(NULL),			fixedArch_(false),
theEntity_ 	(NULL),			fixedEntity_(false),
theLib_ 	(NULL),			fixedLib_(false),
theHub_ 	(h)
{}
// ----------------------------------------------------------------------------
//	in FindOrCreate, existing values (from ctor or previous FindOrCreate) take precedence
// ----------------------------------------------------------------------------
InconsReason Location :: FindOrCreate (const std::string& libn, const std::string& entn, const std::string& archn) {
    if (!theLib_ && !libn.empty()) theLib_ = theHub_->FindOrCreateLib (libn);
    if (theLib_) {
	if (!theEntity_ && !entn.empty())  theEntity_ = theLib_->FindOrCreateEntity (entn);
	if (theEntity_) {
	    if (!theArch_ && !archn.empty()) theArch_ = theEntity_->FindOrCreateArch (archn);
	} else {
	    if (!archn.empty()) return InconsReason ("Architecture name given but entity unknown");
	}
    } else {
	if (!entn.empty()) return InconsReason ("Entity name given but library unknown");
	if (!archn.empty()) return InconsReason ("Architecture name given but library unknown");
    }
    return InconsReason (0);
}
// ----------------------------------------------------------------------------
InconsReason Location :: FindOrCreate (const LocationNames& nm) {
    return FindOrCreate (nm.libName(), nm.entityName(), nm.archName());
}
// ----------------------------------------------------------------------------
InconsReason Location :: Find (const std::string& libn, const std::string& entn, const std::string& archn) {
    if (!theLib_ && !libn.empty()) theLib_ = theHub_->FindLib (libn);
    if (theLib_) {
	if (!theEntity_ && !entn.empty())  theEntity_ = theLib_->FindEntity (entn);
	if (theEntity_) {
	    if (!theArch_ && !archn.empty()) theArch_ = theEntity_->FindArch (archn);
	} else {
	    if (!archn.empty()) return InconsReason ("Architecture name given but entity unknown");
	}
    } else {
	if (!entn.empty()) return InconsReason ("Entity name given but library unknown");
	if (!archn.empty()) return InconsReason ("Architecture name given but library unknown");
    }
    return InconsReason (0);
}
// ----------------------------------------------------------------------------
InconsReason Location :: Find (const LocationNames& nm) {
    return Find (nm.libName(), nm.entityName(), nm.archName());
}
// ----------------------------------------------------------------------------
void Location :: Set (Library* lib) {
    theArch_   = NULL;			fixedArch_ = false;
    theEntity_ = NULL;			fixedEntity_ = false;
    theLib_    = lib;			fixedLib_ = true;
}
// ----------------------------------------------------------------------------
void Location :: Set (Entity* ent) {
    theArch_   = NULL;			fixedArch_ = false;
    theEntity_ = ent;			fixedEntity_ = true;
    theLib_    = theEntity_->Parent();	fixedLib_ = true;
}
// ----------------------------------------------------------------------------
void Location :: Set (Architecture* arch) {
    theArch_   = arch;			fixedArch_ = true;
    theEntity_ = theArch_->Parent();	fixedEntity_ = true;
    theLib_    = theEntity_->Parent();	fixedLib_ = true;
}
// ----------------------------------------------------------------------------
void Location :: FindOrCreateDesign (const std::string& dsgnname) {
    Design* design = theHub_->FindDesign (dsgnname);
    if (!design) return;	// ----------- !!!!!!
    fixedArch_ = false;
    theEntity_ = design->DesignEntity(); fixedEntity_ = true;
    theLib_ = theEntity_->Parent(); fixedLib_ = true;
}
