#include "CommoditySet.h"

namespace cosi {

CommoditySet::CommoditySet() {

}

CommoditySet::~CommoditySet() {

}

CommoditySet::iterator CommoditySet::Begin() const {
	std::set<Commodity>::const_iterator ci = mCommoditySet.begin();
	std::set<Commodity>::iterator temp;//=reinterpret_cast<std::set<Commodity>::iterator>(mCommoditySet.begin());
	//std::advance(temp,std::distance<std::set<Commodity>::const_iterator>(temp,ci));
	return temp;
	//std::set<Commodity>::iterator it = mCommoditySet.begin();
	//return it;
}

CommoditySet::iterator CommoditySet::End() const {
	//return mCommoditySet.end() ;
	std::set<Commodity>::const_iterator ci = mCommoditySet.end();
	std::set<Commodity>::iterator temp;//(mCommoditySet.begin());
	std::advance(temp,std::distance<std::set<Commodity>::const_iterator>(temp,ci));
	return temp;
}

int CommoditySet::Size() {
	return mCommoditySet.size();
}

CommoditySet CommoditySet::Get() const {
	return (*this);
}

void CommoditySet::Set(CommoditySet pSet) {
	IsBot(false);
	if (IsAny() )
		IsAny(false) ;
	(*this) = pSet ;
}

std::set<Commodity> CommoditySet::GetValue() const {
	return mCommoditySet ;
}

void CommoditySet::SetValue(std::set<Commodity> pSet) {
	IsBot(false);
	if (IsAny() )
		IsAny(false) ;
	mCommoditySet = pSet ;
}

double CommoditySet::GetAggregateBandwidthValue() {
	return (GetAggregateBandwidth().GetValue());
}

Bandwidth CommoditySet::GetAggregateBandwidth() {
	iterator It;
	Bandwidth B(0);
	for (It = mCommoditySet.begin() ; It != mCommoditySet.end() ; It++) {
		B = B + It->GetAverageBandwidth();
	}
	return B ;

}

void CommoditySet::Add(Commodity pC) {
	IsBot(false) ;
	if (IsAny() )
		IsAny(false) ;
	mCommoditySet.insert(pC) ;
}

bool CommoditySet::operator<(const CommoditySet &pSet) const {
	//containement
	return (std::includes(pSet.mCommoditySet.begin() , pSet.mCommoditySet.end(),mCommoditySet.begin(),mCommoditySet.end()));
}

bool CommoditySet::operator==(const CommoditySet &pSet) const {
	return ( pSet.GetValue() == GetValue() );
}

CommoditySet CommoditySet::operator+(CommoditySet pSet) {
	//take union
	std::set<Commodity> S;
	S.insert(mCommoditySet.begin(),mCommoditySet.end());
	S.insert(pSet.mCommoditySet.begin(),mCommoditySet.end());
	CommoditySet RetVal;
	RetVal.SetValue(S);
	return RetVal;
}

std::ostream& operator <<(std::ostream &pOs, const CommoditySet &pC) {
	std::set<Commodity> S = pC.GetValue();
	std::set<Commodity>::iterator It;
	for(It = S.begin(); It != S.end(); It++ ) {
		pOs << *It << std::endl;
	}
	return pOs;
}

std::string CommoditySet::sQuantityName="CommoditySet";
std::string CommoditySet::sQuantityType="Set of Commodity";

}
