/*Header file of the PStep_ReachabilitySetter class

Implementation can be found in PStep_ReachabilitySetter.cpp

This class represents a function for setting reachability of labels.

This file also includes derived classes of PStep_ReachabilitySetter.

*/

#ifndef _PSTEP_REACHABILITYSETTER_H
#define _PSTEP_REACHABILITYSETTER_H

#include "Label.h"
#include "BiDirectionalLabels.h"
#include <forward_list>
#include <vector>

//Class used to represent a function for setting reachability of labels.
class PStep_ReachabilitySetter{
public:
	
	//Pointer to demand
	//Demand[i] is the demand of customer i, i=0 is the first customer.
	double* Demand;

	//Capacity on the partial path
	//It is advisable to set this parameter to the actual capacity plus some numerical tolerance.
	double CapacityPlusTolerance;


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

	//Set demand, capacity and tolerance.
	PStep_ReachabilitySetter(double *NewDemand, double NewCapacityPlusTolerance)
		: Demand(NewDemand), CapacityPlusTolerance(NewCapacityPlusTolerance)
	{};

	//Reachability setter:
	//------------------------------------------------------------------------------------
	//This function will be called during extension, it is assumed that the
	//load of the new label is already updated, but Reachability has not yet been initialized.
	//This function sets reachability to true for all locations that were
	//currently reachable, are not the CurrentCustomer and extending would not
	//cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const Label& PreviousLabel, Label& NewLabel, short int CurrentCustomer);

	//This function will be called during extension, it is assumed that the
	//load of the new ForwardLabel is already updated, but Reachability
	//has not yet been initialized.
	//This function sets reachability to true for all locations that were
	//currently reachable, are not the CurrentCustomer and extending would not
	//cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const ForwardLabel &PreviousLabel, ForwardLabel &NewForwardLabel, short int CurrentCustomer);

	//This function will be called during extension, it is assumed that the
	//load of the new BackwardLabel is already updated, but Reachability
	//has not yet been initialized.
	//This function sets reachability to true for all locations that were
	//currently reachable, are not the CurrentCustomer and extending would not
	//cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const BackwardLabel &NextLabel, BackwardLabel &NewBackwardLabel, short int CurrentCustomer);

};

//Class used to represent a function for setting reachability of labels in case ng-path relaxation is applied.
class PStep_NGReachabilitySetter : public PStep_ReachabilitySetter{
public:

	//Not in neighborhood indicates whether a customer is not in the neighborhoud.
	//NotInNeighbourhood.[i][j]=true if customer j is not a neighbor of customer i (0 is the first customer).
	bool** (&NotInNeighbourhood);

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

	//Set demand, capacity, tolerance and NotInNeighbourhood
	PStep_NGReachabilitySetter(double *NewDemand, double NewCapacityPlusTolerance, bool** (&NewNotInNeighbourhood))
		: PStep_ReachabilitySetter(NewDemand, NewCapacityPlusTolerance), NotInNeighbourhood(NewNotInNeighbourhood)
	{};

	//Reachability setter:
	//------------------------------------------------------------------------------------
	//This function will be called during extension, it is assumed that the
	//load of the new label is already updated, but Reachability has not yet been initialized.
	//This function sets reachability to false for the CurrentCustomer, all customers in the neighbourhood 
	//that were currently not reachable or extension would cause a capacity violation,
	//and all customer that for which extension would cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const Label& PreviousLabel, Label& NewLabel, short int CurrentCustomer);

	//This function will be called during extension, it is assumed that the
	//load of the new ForwardLabel is already updated, but Reachability
	//has not yet been initialized.
	//This function sets reachability to false for the CurrentCustomer, all customers in the neighbourhood 
	//that were currently not reachable or extension would cause a capacity violation,
	//and all customer that for which extension would cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const ForwardLabel &PreviousLabel, ForwardLabel &NewForwardLabel, short int CurrentCustomer);

	//This function will be called during extension, it is assumed that the
	//load of the new BackwardLabel is already updated, but Reachability
	//has not yet been initialized.
	//This function sets reachability to false for the CurrentCustomer, all customers in the neighbourhood 
	//that were currently not reachable or extension would cause a capacity violation,
	//and all customer that for which extension would cause a capacity violation.
	//The input CurrentCustomer=0 represents the first customer.
	virtual void SetReachability(const BackwardLabel &NextLabel, BackwardLabel &NewBackwardLabel, short int CurrentCustomer);

};

#endif