package algorithms;

import basics.VehicleRoutingProblem;
import basics.route.TourActivity;

public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint{

	private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
	
	private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
	
	private VehicleRoutingProblem vrp;
	
	private StateManager stateManager;
	
	private boolean loadConstraintsSet = false;
	
	private boolean timeWindowConstraintsSet = false;
	
	public ConstraintManager(VehicleRoutingProblem vrp, StateManager stateManager) {
		this.vrp = vrp;
		this.stateManager = stateManager;
	}
	
	public void addTimeWindowConstraint(){
		if(!timeWindowConstraintsSet){
			addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
			stateManager.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
			timeWindowConstraintsSet = true;
		}
	}

	public void addLoadConstraint(){
		if(!loadConstraintsSet){
			addConstraint(new ServiceLoadRouteLevelConstraint(stateManager));
			addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
			UpdateLoads updateLoads = new UpdateLoads(stateManager);
			stateManager.addActivityVisitor(updateLoads);
			stateManager.addListener(updateLoads);
			stateManager.addActivityVisitor(new UpdateFuturePickups(stateManager));
			stateManager.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
			loadConstraintsSet=true;
		}
	}
	
	public void addConstraint(HardActivityStateLevelConstraint actLevelConstraint){
		actLevelConstraintManager.addConstraint(actLevelConstraint);
	}
	
	public void addConstraint(HardRouteStateLevelConstraint routeLevelConstraint){
		routeLevelConstraintManager.addConstraint(routeLevelConstraint);
	}
	
	@Override
	public boolean fulfilled(InsertionContext insertionContext) {
		return routeLevelConstraintManager.fulfilled(insertionContext);
	}

	@Override
	public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
		return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
	}
	
}
@@ -51,16 +51,64 @@
 roblem;%0A
+import basics.VehicleRoutingProblem.Constraint;%0A
 import b
@@ -242,16 +242,74 @@
 raint%7B%0A%0A
+%09public static enum Priority %7B%0A%09%09CRITICAL, HIGH, LOW%0A%09%7D%0A%09%0A
 %09private
@@ -994,24 +994,38 @@
 portCosts())
+,Priority.HIGH
 );%0A%09%09%09stateM
@@ -1210,32 +1210,284 @@
 onstraintsSet)%7B%0A
+%09%09%09if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST))%7B%0A%09%09%09%09addConstraint(new ServiceBackhaulConstraint(),Priority.HIGH);%0A%09%09%09%7D%0A%09%09%09addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager),Priority.CRITICAL);%0A
 %09%09%09addConstraint
@@ -1604,24 +1604,37 @@
 tateManager)
+,Priority.LOW
 );%0A%09%09%09Update
@@ -2040,24 +2040,43 @@
 elConstraint
+, Priority priority
 )%7B%0A%09%09actLeve
@@ -2118,32 +2118,41 @@
 tLevelConstraint
+,priority
 );%0A%09%7D%0A%09%0A%09public 

add priorities to constraints