/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2013 Ausenco Engineering Canada Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaamsim.CalculationObjects;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.basicsim.Entity;
import com.jaamsim.basicsim.EntityTarget;
import com.jaamsim.events.ProcessTarget;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.ValueInput;
import com.jaamsim.units.TimeUnit;

/**
 * The Controller object simulates the operation of a Programmable Logic Controller
 * @author Harry King
 *
 */
public class Controller extends DisplayEntity {

	@Keyword(description = "The sampling time for the Controller.",
	         exampleList = {"100 ms"})
	private final ValueInput samplingTime;

	private final ArrayList<CalculationEntity> calculationEntityList;  // List of the CalculationEntities controller by this Controller.
	private int count;  // Number of times that the controller has initiated its calculations.

	private final ProcessTarget doUpdate = new DoUpdateTarget(this);

	{
		samplingTime = new ValueInput("SamplingTime", KEY_INPUTS, 1.0d);
		samplingTime.setUnitType(TimeUnit.class);
		samplingTime.setValidRange(0.0, Double.POSITIVE_INFINITY);
		this.addInput(samplingTime);
	}

	public Controller() {
		calculationEntityList = new ArrayList<>();
	}

	@Override
	public void earlyInit() {
		super.earlyInit();
		count = 0;

		// Prepare a list of the calculation entities managed by this controller
		calculationEntityList.clear();
		for (CalculationEntity ent : Entity.getClonesOfIterator(CalculationEntity.class)) {
			if (ent.getController() == this)
				calculationEntityList.add(ent);
		}

		// Sort the calculation entities into the correct sequence
		Collections.sort(calculationEntityList, new SequenceCompare());
	}

	// Sorts by increasing sequence number
	private static class SequenceCompare implements Comparator<CalculationEntity> {
		@Override
		public int compare(CalculationEntity c1, CalculationEntity c2) {
			return Double.compare(c1.getSequenceNumber(), c2.getSequenceNumber());
		}
	}

	@Override
	public void startUp() {
		super.startUp();

		// Schedule the first update
		this.scheduleProcess(samplingTime.getValue(), 5, doUpdate);
	}

	private static class DoUpdateTarget extends EntityTarget<Controller> {
		DoUpdateTarget(Controller ent) {
			super(ent, "doUpdate");
		}

		@Override
		public void process() {
			ent.doUpdate();
		}
	}

	public void doUpdate() {

		// Update the last value for each entity
		double simTime = this.getSimTime();
		for (CalculationEntity ent : calculationEntityList) {
			ent.update(simTime);
		}

		// Increment the number of cycles
		count++;

		// Schedule the next update
		this.scheduleProcess(samplingTime.getValue(), 5, doUpdate);
	}

	public int getCount() {
		return count;
	}
}

@@ -87,16 +87,60 @@
 da Inc.%0A
+ * Copyright (C) 2018 JaamSim Software Inc.%0A
  *%0A * Li
@@ -1425,32 +1425,27 @@
 ayList%3CC
-alculationEntity
+ontrollable
 %3E calcul
@@ -2154,35 +2154,24 @@
 r();%0A%09%09for (
-Calculation
 Entity ent :
@@ -2198,27 +2198,16 @@
 terator(
-Calculation
 Entity.c
@@ -2214,23 +2214,85 @@
 lass
-)) %7B%0A%09%09%09if (ent
+, Controllable.class)) %7B%0A%09%09%09Controllable con = (Controllable) ent;%0A%09%09%09if (con
 .get
@@ -2343,19 +2343,19 @@
 ist.add(
-ent
+con
 );%0A%09%09%7D%0A%0A
@@ -2586,32 +2586,27 @@
 arator%3CC
-alculationEntity
+ontrollable
 %3E %7B%0A%09%09@O
@@ -2639,46 +2639,36 @@
 re(C
-alculationEntity c1, CalculationEntity
+ontrollable c1, Controllable
  c2)
@@ -3225,32 +3225,27 @@
 %09%09for (C
-alculationEntity
+ontrollable
  ent : c
@@ -3485,10 +3485,11 @@
 unt;%0A%09%7D%0A
+%0A
 %7D%0A

replace the use of CalculationEntity with Controllable in Controller