#pragma once



#include "Customer.h"
#include <vector>

using namespace std;

class Label
{
public:
	Label(long _id, int _currentNodeId, vector<Customer> _sequence, vector<bool> _visited, double _priceWithoutWage, double _priceWithWage, int _time, int _cargoWeight);
	Label(long _id, int _currentNodeId, vector<bool> _visitedCustomer);
	Label();
	~Label();

	inline long getId() const {
		return id;
	}

	inline void setId(int _id)
	{
		id = _id;
	}

	inline int getCurrentNodeId() {
		return currentNodeId;
	}

	inline vector<Customer>* getSequence() {
		return &sequence;
	}

	inline vector<bool>* getVisitedCustomer()
	{
		return &customerVisited;
	}

	inline void setCustomerVisited(int id)
	{
		customerVisited[id] = true;
	}

	inline void addACustomer(Customer c) {
		sequence.push_back(c);
	}


	inline void addACustomerBWLabelingAndUpdateIndexOnBound(Customer c)
	{

		sequence.insert(sequence.begin(), c);
		if (indexOnBound != -1 && c.getCompletionTime() != c.getUpperTW())
		{
			indexOnBound++;
		}
		else
		{
			indexOnBound = 0;
		}
	}

	inline double getDualVariableCost() {
		return dualVariables;
	}

	inline void setDualVariableCost(double _dualVariables) {
		dualVariables = _dualVariables;
	}

	inline double getOptCost() {
		return optCost;
	}

	inline void setOptCost(double _optCost) {
		optCost = _optCost;
	}

	inline double getPriceMinSpeed() {
		return priceMinSpeed;
	}

	inline void setPriceMinSpeed(double _price) {
		priceMinSpeed = _price;
	}

	inline double getReducedCostLabel() {
		return reducedCost;
	}

	inline void setReducedCostLabel(double _reducedCost) {
		reducedCost = _reducedCost;
	}

	inline int getTime()
	{
		return time;
	}

	inline vector<double>* getSpeeds()
	{
		return &speeds;
	}

	inline vector<double>* getCompletionTimes()
	{
		return &completionTimes;
	}

	inline vector<int>* getWorkLoads()
	{
		return &workloads;
	}

	inline void setIndexInSequenceOnBound(int _indexAtLowerBound)
	{
		indexOnBound = _indexAtLowerBound;
	}

	inline int getIndexInSequenceOnBound()
	{
		return indexOnBound;
	}

	inline vector<long double>* getPrices() {
		return &prices;
	}
	inline bool isDominated()
	{
		return dominated;
	}
	inline void setDominated()
	{
		dominated = true;
	}
	inline void setCargoWeight(int _cargoWeight)
	{
		cargoWeight = _cargoWeight;
	}
	inline void addCargoWeight(int _cargoWeight)
	{
		cargoWeight += _cargoWeight;
	}
	inline int getCargoWeight()
	{
		return cargoWeight;
	}
	const std::vector<uint64_t>& getVisitedMask() const { return visitedMask; }
	void setVisitedMask(const std::vector<uint64_t>& mask) { visitedMask = mask; }
protected:

	long				id;
	int					currentNodeId;
	vector<Customer>	sequence;
	vector<bool>		customerVisited;
	std::vector<uint64_t> visitedMask;
	double				priceMinSpeed;
	int					time;
	vector<double>		speeds;			// this vector contains the different speeds of the last job in the sequence, while speeding up a given sequence
	vector<double>		completionTimes;// this vector contains the different completion times of the last job in the sequence, while speeding up a given sequence
	vector<int>			workloads;		// this vector describes the sum of workloads of jobs, which have the same speed as the last job in the sequence and are consecutive, starting from the last job. 
	vector<long double>	prices;
	int					indexOnBound;	// Corresponds to the index in the sequence of a customer that is supplied on the bound of his tw. For forward labeling this is always a customer
	bool				dominated;
	int					cargoWeight;
	double				dualVariables;
	double				optCost;
	double				reducedCost;

};

