#include "EthernetSubNetwork.h"

namespace cosi {

namespace library {

namespace wiredbas {

EthernetSubNetwork::EthernetSubNetwork(cosi::rules::wiredbas::WiringRule* Wr,
		cosi::rules::wiredbas::EthernetNetworkRule* Er,
		cosi::models::wiredbas::WireCost* Wc,
		cosi::models::wiredbas::EthernetNetworkCost* Nc,
		cosi::models::wiredbas::LinkDelayModel* Ld,
		cosi::models::wiredbas::EthernetNetworkDelay* Nd,
		std::map<std::string, cosi::library::wiredbas::InstantiableNode*> N,
		std::map<std::string, cosi::library::wiredbas::InstantiableLink*> L) :
	SubNetwork(N, L) {
	mWiringRule = Wr;
	mEthernetRule = Er;
	mWireCost = Wc;
	mNetCost = Nc;
	mLinkDelay = Ld;
	mNetDelay = Nd;
}

EthernetSubNetwork::~EthernetSubNetwork() {

}

double EthernetSubNetwork::LatencyValue(
		cosi::commstruct::wiredbas::Implementation* pNet, Vertex Src,
		std::string Dest, Vertex SrcId, Vertex DestId) {
	return mNetDelay->GetValue(pNet, Src, Dest, SrcId, DestId);
}

bool EthernetSubNetwork::Satisfies(cosi::commstruct::wiredbas::Specification* pSpec,
		cosi::commstruct::wiredbas::Implementation* pNet) {
	return mEthernetRule->Satisfies(pSpec,pNet);
}

double EthernetSubNetwork::GetCost(
		cosi::commstruct::wiredbas::Implementation* pNet) {
	return mNetCost->GetValue(pNet) ;
}

void EthernetSubNetwork::AddNode(string Name, Vertex V, Position pP,
		ThreadSet pThreads, TransferTable pT) {
	cosi::commstruct::wiredbas::Implementation
			* N = mNodes[Name]->GetImplementationInstance(V, pP, pThreads, pT) ;
	(*mI) = (*mI) + (*N);
	delete N;
}

void EthernetSubNetwork::AddLink(string Name, Vertex U, Vertex V,
		WiringPath pPath) {
	//Find availalbe ports on U and V
	string Out = (*mI)[U].PRJ(Ports)GetInputOutputPortNotBound();
	string In = (*mI)[V].PRJ(Ports)GetInputOutputPortNotBound();
	cosi::commstruct::wiredbas::Implementation
			* L =mLinks[Name]->GetImplementationInstance(U, Out, V, In, pPath) ;
	(*mI) = (*mI) + (*L);
	delete L;
}

}

}

}
