/*****************************************************************//**
 * \file   ColumnGenerationMediator.h
 * \brief  THe concrete mediator that communicates the values of the dual variables from RMP to PSP so that the PSP updates rmp_dual_variables when RMP notifies.
 *  And comunicates columns from PSP to RMP to trigger insert_columns in RMP.
 * 
 * \author talmefta
 * \date   June 2022
 *********************************************************************/
#ifndef COLUMNGENERATIONMEDIATOR_H
#define COLUMNGENERATIONMEDIATOR_H

#include "Header.h"
#include "RmpPspMediator.h"
#include "BaseComponent.h"
#include "RestrictedMasterProblemInterface.h"
#include "PricingSubProblem.h"

/**
 * \class ColumnGenerationMediator.
 * \brief  THe concrete mediator that communicates the values of the dual variables from RMP to PSP so that the PSP updates rmp_dual_variables when RMP notifies.
 *  And comunicates columns from PSP to RMP to trigger insert_columns in RMP.
 */
template<class Instance, class SolutionType, class DualVariables, class ColumnsType, class Constraint>
class ColumnGenerationMediator: public RmpPspMediator {

protected:
	RestrictedMasterProblemInterface<Instance, SolutionType, DualVariables, ColumnsType, Constraint>* restricted_master_problem;
	PricingSubProblem<Instance, ColumnsType, DualVariables, Constraint>*									 pricing_subproblem;

public:
	ColumnGenerationMediator(RestrictedMasterProblemInterface<Instance, SolutionType, DualVariables, ColumnsType, Constraint>* restricted_master_problem,
		PricingSubProblem<Instance, ColumnsType, DualVariables, Constraint>* pricing_subproblem) : restricted_master_problem(restricted_master_problem),
		pricing_subproblem(pricing_subproblem) {
		this->restricted_master_problem->set_mediator(this);
		this->pricing_subproblem->set_mediator(this);
	}

	void notify(BaseComponent* sender, const string& event) const override {
		if (event == "NEWDUALVARIABLES") {
			this->pricing_subproblem->set_rmp_dual_variables(&this->restricted_master_problem->get_dual_variables());
			this->pricing_subproblem->set_existing_rmp_columns(&this->restricted_master_problem->get_columns());
			this->pricing_subproblem->set_branching_constraints(&this->restricted_master_problem->get_branching_constraints());
		}
		if (event == "NEWCOLUMNS") {
			this->restricted_master_problem->insert_columns(this->pricing_subproblem->get_columns());
		}
	}
};
#endif // !COLUMNGENERATIONMEDIATOR_H

