/*Implementation of PStep_TreeNode.h

It contains the member functions of PStep_TreeNode

*/

#include "PStep_TreeNode.h"
#include "iostream"
#include "iomanip"

//Constructor functions:
//------------------------------------------------------------------------------------

//Default Constructor
PStep_TreeNode::PStep_TreeNode(){

	//Set all settings to their default
	ID = -1;
	ParentID = -1;
	Depth = -1;
	ParentLB = -1;
	NumberOfLocations;
	EdgeInUse = 0;

}

//Copy Constructor
PStep_TreeNode::PStep_TreeNode(const PStep_TreeNode &OriginalPStep_TreeNode){

	CopyEmptyAssumed(OriginalPStep_TreeNode);

}

//Constructor used for basic initialization.
//It sets the parameters equal to the input and initializes edge usage array as true for all entries.
PStep_TreeNode::PStep_TreeNode(int NewID, int NewParentID, int NewDepth, double NewParentLB, short int NewNumberOfLocations){

	//Set parameters
	ID = NewID;
	ParentID = NewParentID;
	Depth = NewDepth;
	ParentLB = NewParentLB;
	NumberOfLocations = NewNumberOfLocations;
	//Initialize the EdgeInUse array as true for all entries
	EdgeInUse = new bool[NumberOfLocations*(NumberOfLocations - 1) / 2];
	for (short int i = 0; i < NumberOfLocations*(NumberOfLocations - 1) / 2; ++i){
		EdgeInUse[i] = true;
	}

}

//Operator functions:
//------------------------------------------------------------------------------------

//Assignment operator
PStep_TreeNode PStep_TreeNode::operator =(PStep_TreeNode OriginalPStep_TreeNode){

	EmptyNode();
	CopyEmptyAssumed(OriginalPStep_TreeNode);
	return *this;

}

//Destructor functions
//------------------------------------------------------------------------------------

//Default destructor
PStep_TreeNode::~PStep_TreeNode(){

	EmptyNode();

}

//Print functions
//-----------------------------------------------------------------------------------

//Print EdgeInUse
void PStep_TreeNode::PrintEdgeInUse(){

	//Check whether the current print function is sufficient
	if (NumberOfLocations > 9999){
		std::cout << "Too many Locations to print" << std::endl;
		return;
	}

	//Print Table Header
	std::cout << "     ";
	for (short int i = 0; i < NumberOfLocations; ++i){
		std::cout << " " << std::setw(4) << i;
	}
	std::cout << std::endl;

	//Support
	//Print EdgeFractions
	for (short int i = 0; i < NumberOfLocations; ++i){
		std::cout << std::setw(4) << i << " ";
		for (short int j = 0; j <= i; ++j){
			std::cout << "-----";
		}

		for (short int j = i + 1; j < NumberOfLocations; ++j){
			std::cout << " " << std::setw(4) << EdgeInUse[(j - 1)*j / 2 + i];
		}
		std::cout << std::endl;
	}

}

//Auxiliary functions
//------------------------------------------------------------------------------------

//Empty all entries
void PStep_TreeNode::EmptyNode(){

	//Set all settings to there default
	ID = -1;
	ParentID = -1;
	Depth = -1;
	ParentLB = -1;
	if (!(EdgeInUse == 0 || NumberOfLocations == 0)){
		delete[]EdgeInUse;
	}
	EdgeInUse = 0;
	EdgeFlowCuts_ByNodes_LB.clear();
	EdgeFlowCuts_ByNodes_EQ.clear();
	EdgeFlowCuts_ByNodes_UB.clear();
	EdgeFlowCuts_ByEdges_LB.clear();
	EdgeFlowCuts_ByEdges_EQ.clear();
	EdgeFlowCuts_ByEdges_UB.clear();

}

//Copy all entries
//IMPORTANT: it is assumed that the current instance is empty!
//It is also assumed that NumberOfCustomers and NumberOfScenarios correspond to the array lengths
void PStep_TreeNode::CopyEmptyAssumed(const PStep_TreeNode &OriginalPStep_TreeNode){

	//Copy
	ID = OriginalPStep_TreeNode.ID;
	ParentID = OriginalPStep_TreeNode.ParentID;
	Depth = OriginalPStep_TreeNode.Depth;
	ParentLB = OriginalPStep_TreeNode.ParentLB;
	NumberOfLocations = OriginalPStep_TreeNode.NumberOfLocations;
	if (!(OriginalPStep_TreeNode.EdgeInUse == 0 || NumberOfLocations == 0)){
		EdgeInUse = new bool[NumberOfLocations*(NumberOfLocations - 1) / 2];
		for (short int i = 0; i<NumberOfLocations*(NumberOfLocations - 1) / 2; ++i){
			EdgeInUse[i] = OriginalPStep_TreeNode.EdgeInUse[i];
		}
	}
	else{
		EdgeInUse = 0;
	}
	EdgeFlowCuts_ByNodes_LB = OriginalPStep_TreeNode.EdgeFlowCuts_ByNodes_LB;
	EdgeFlowCuts_ByNodes_EQ = OriginalPStep_TreeNode.EdgeFlowCuts_ByNodes_EQ;
	EdgeFlowCuts_ByNodes_UB = OriginalPStep_TreeNode.EdgeFlowCuts_ByNodes_UB;
	EdgeFlowCuts_ByEdges_LB = OriginalPStep_TreeNode.EdgeFlowCuts_ByEdges_LB;
	EdgeFlowCuts_ByEdges_EQ = OriginalPStep_TreeNode.EdgeFlowCuts_ByEdges_EQ;
	EdgeFlowCuts_ByEdges_UB = OriginalPStep_TreeNode.EdgeFlowCuts_ByEdges_UB;

}