package bdi4jade.examples.undo;

import bdi4jade.annotation.Belief;
import bdi4jade.belief.PredicateBelief;
import bdi4jade.belief.TransientPredicate;
import bdi4jade.examples.undo.domain.Alarm;
import bdi4jade.examples.undo.domain.CO;
import bdi4jade.examples.undo.domain.Door;
import bdi4jade.examples.undo.domain.Fan;
import bdi4jade.examples.undo.domain.Light;
import bdi4jade.examples.undo.domain.Valve;
import bdi4jade.examples.undo.domain.WaterHeater;
import bdi4jade.examples.undo.domain.Window;
import bdi4jade.examples.undo.domain.predicate.Abnormal;
import bdi4jade.examples.undo.domain.predicate.Leak;
import bdi4jade.examples.undo.domain.predicate.Locked;
import bdi4jade.examples.undo.domain.predicate.On;
import bdi4jade.examples.undo.domain.predicate.Open;
import bdi4jade.examples.undo.domain.predicate.TakeOff;
import bdi4jade.examples.undo.goal.AlarmShutdownGoal;
import bdi4jade.examples.undo.goal.AlarmTakeOffGoal;
import bdi4jade.examples.undo.goal.DoorsLockGoal;
import bdi4jade.examples.undo.goal.DoorsUnlockGoal;
import bdi4jade.examples.undo.goal.FansOffGoal;
import bdi4jade.examples.undo.goal.FansOnGoal;
import bdi4jade.examples.undo.goal.LightsOffGoal;
import bdi4jade.examples.undo.goal.LightsOnGoal;
import bdi4jade.examples.undo.goal.NormalizeCOGoal;
import bdi4jade.examples.undo.goal.ValveCloseGoal;
import bdi4jade.examples.undo.goal.WindowsCloseGoal;
import bdi4jade.examples.undo.goal.WindowsOpenGoal;
import bdi4jade.examples.undo.plan.EvacuateAndVentilatePlanBody;
import bdi4jade.examples.undo.plan.request.RequestAlarmShutdownPlanBody;
import bdi4jade.examples.undo.plan.request.RequestAlarmTakeOffPlanBody;
import bdi4jade.examples.undo.plan.request.RequestDoorsLockPlanBody;
import bdi4jade.examples.undo.plan.request.RequestDoorsUnlockPlanBody;
import bdi4jade.examples.undo.plan.request.RequestFansOffPlanBody;
import bdi4jade.examples.undo.plan.request.RequestFansOnPlanBody;
import bdi4jade.examples.undo.plan.request.RequestLightsOffPlanBody;
import bdi4jade.examples.undo.plan.request.RequestLightsOnPlanBody;
import bdi4jade.examples.undo.plan.request.RequestValveClosePlanBody;
import bdi4jade.examples.undo.plan.request.RequestWindowsClosePlanBody;
import bdi4jade.examples.undo.plan.request.RequestWindowsOpenPlanBody;
import bdi4jade.extension.undo.RevertingCapability;
import bdi4jade.plan.DefaultPlan;
import bdi4jade.plan.Plan;

/**
 * @author jgfaccin
 *
 */
public class ManagementCapability extends RevertingCapability {

	private static final long serialVersionUID = -1971498055603790248L;

	// Devices
	public static final Alarm ALARM = new Alarm("ALARM");
	public static final Door DOORS = new Door("DOORS");
	public static final Fan FANS = new Fan("FANS");
	public static final Light LIGHTS = new Light("LIGHTS");
	public static final Valve VALVE = new Valve("VALVE");
	public static final WaterHeater WATER_HEATER = new WaterHeater("WATER_HEATER");
	public static final Window WINDOWS = new Window("WINDOWS");

	// Neighbours
	@Belief
	String alarmAgent;
	@Belief
	String doorsAgent;
	@Belief
	String fansAgent;
	@Belief
	String lightsAgent;
	@Belief
	String valveAgent;
	@Belief
	String windowsAgent;

	// Device Predicates
	PredicateBelief<TakeOff> alarmTakeOff = new TransientPredicate<>(new TakeOff(ALARM), false);
	PredicateBelief<Locked> doorsUnlock = new TransientPredicate<>(new Locked(DOORS), true);
	PredicateBelief<On> fansOn = new TransientPredicate<On>(new On(FANS), false);
	PredicateBelief<Leak> leakingWaterHeater = new TransientPredicate<Leak>(new Leak(WATER_HEATER), false);
	PredicateBelief<On> lightsOn = new TransientPredicate<>(new On(LIGHTS), false);
	PredicateBelief<Open> valveClose = new TransientPredicate<Open>(new Open(VALVE), false);
	PredicateBelief<Open> windowsOpen = new TransientPredicate<Open>(new Open(WINDOWS), false);
	PredicateBelief<Abnormal> abnormalCO = new TransientPredicate<Abnormal>(new Abnormal(CO.getInstance()), false);

	// Plans
	@bdi4jade.annotation.Plan
	private Plan lightsOnPlan;
	@bdi4jade.annotation.Plan
	private Plan lightsOffPlan;
	@bdi4jade.annotation.Plan
	private Plan alarmTakeOffPlan;
	@bdi4jade.annotation.Plan
	private Plan alarmShutdownPlan;
	@bdi4jade.annotation.Plan
	private Plan doorsUnlockPlan;
	@bdi4jade.annotation.Plan
	private Plan doorsLockPlan;
	@bdi4jade.annotation.Plan
	private Plan fansOnPlan;
	@bdi4jade.annotation.Plan
	private Plan fansOffPlan;
	@bdi4jade.annotation.Plan
	private Plan windowsOpenPlan;
	@bdi4jade.annotation.Plan
	private Plan windowsClosePlan;
	@bdi4jade.annotation.Plan
	private Plan valveClosePlan;
	@bdi4jade.annotation.Plan
	private Plan evacuateAndVentilatePlan;

	public ManagementCapability(String alarmAgent, String valveAgent, String doorsAgent, String fansAgent,
			String lightsAgent, String windowsAgent) {
		this.alarmAgent = alarmAgent;
		this.valveAgent = valveAgent;
		this.doorsAgent = doorsAgent;
		this.fansAgent = fansAgent;
		this.lightsAgent = lightsAgent;
		this.windowsAgent = windowsAgent;

		initializePlans();
		initializeCauseEffectRelationship();
	}

	private void initializePlans() {
		this.lightsOnPlan = new DefaultPlan(LightsOnGoal.class, RequestLightsOnPlanBody.class);
		this.lightsOffPlan = new DefaultPlan(LightsOffGoal.class, RequestLightsOffPlanBody.class);
		this.alarmTakeOffPlan = new DefaultPlan(AlarmTakeOffGoal.class, RequestAlarmTakeOffPlanBody.class);
		this.alarmShutdownPlan = new DefaultPlan(AlarmShutdownGoal.class, RequestAlarmShutdownPlanBody.class);
		this.doorsUnlockPlan = new DefaultPlan(DoorsUnlockGoal.class, RequestDoorsUnlockPlanBody.class);
		this.doorsLockPlan = new DefaultPlan(DoorsLockGoal.class, RequestDoorsLockPlanBody.class);
		this.fansOnPlan = new DefaultPlan(FansOnGoal.class, RequestFansOnPlanBody.class);
		this.fansOffPlan = new DefaultPlan(FansOffGoal.class, RequestFansOffPlanBody.class);
		this.windowsOpenPlan = new DefaultPlan(WindowsOpenGoal.class, RequestWindowsOpenPlanBody.class);
		this.windowsClosePlan = new DefaultPlan(WindowsCloseGoal.class, RequestWindowsClosePlanBody.class);
		this.valveClosePlan = new DefaultPlan(ValveCloseGoal.class, RequestValveClosePlanBody.class);
		this.evacuateAndVentilatePlan = new DefaultPlan(NormalizeCOGoal.class, EvacuateAndVentilatePlanBody.class);
	}

	private void initializeCauseEffectRelationship() {
		
	}
}
