/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2014 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.ProbabilityDistributions;

import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.basicsim.Entity;
import com.jaamsim.input.InputAgent;
import com.jaamsim.input.IntegerInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.ValueInput;
import com.jaamsim.rng.MRG1999a;
import com.jaamsim.ui.EditBox;
import com.jaamsim.units.DimensionlessUnit;

public class BooleanSelector extends DisplayEntity {
	@Keyword(description = "Seed for the random number generator.  Must be an integer >= 0.",
	         exampleList = {"547"})
	private IntegerInput randomSeedInput;

	@Keyword(description = "The probability of the Selector returning true.",
	         exampleList = {"0.5"})
	private ValueInput trueProbInput;

	private final MRG1999a rng = new MRG1999a();

	{
		randomSeedInput = new IntegerInput("RandomSeed", "Key Inputs", -1);
		randomSeedInput.setValidRange(0, Integer.MAX_VALUE);
		randomSeedInput.setRequired(true);
		randomSeedInput.setDefaultText(EditBox.NONE);
		this.addInput(randomSeedInput);

		trueProbInput = new ValueInput("TrueProbability", "Key Inputs", 1.0d);
		trueProbInput.setUnitType(DimensionlessUnit.class);
		trueProbInput.setValidRange(0.0d, 1.0d);
		this.addInput(trueProbInput);
	}

	public BooleanSelector() {}

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

		// Find the largest seed used so far
		int seed = 0;
		for (Distribution dist : Entity.getClonesOfIterator(Distribution.class)) {
			seed = Math.max(seed, dist.getStreamNumber());
		}
		for (BooleanSelector bs : Entity.getClonesOfIterator(BooleanSelector.class)) {
			seed = Math.max(seed, bs.getStreamNumber());
		}

		// Set the random number seed next unused value
		InputAgent.applyArgs(this, "RandomSeed", String.format("%s", seed+1));
	}

	@Override
	public void earlyInit() {
		super.earlyInit();
		rng.setSeedStream(getStreamNumber(), Distribution.getSubstreamNumber());
	}

	protected int getStreamNumber() {
		return randomSeedInput.getValue();
	}

	public boolean getNextValue() {
		double samp = rng.nextUniform();
		if (samp < trueProbInput.getValue())
			return true;
		else
			return false;
	}
}

@@ -767,32 +767,72 @@
 asicsim.Entity;%0A
+import com.jaamsim.events.EventManager;%0A
 import com.jaams
@@ -852,16 +852,16 @@
 tAgent;%0A
-
 import c
@@ -925,16 +925,49 @@
 eyword;%0A
+import com.jaamsim.input.Output;%0A
 import c
@@ -1510,16 +1510,44 @@
 1999a();
+%0A%09private boolean lastValue;
 %0A%0A%09%7B%0A%09%09r
@@ -2689,24 +2689,45 @@
 mNumber());%0A
+%09%09lastValue = false;%0A
 %09%7D%0A%0A%09protect
@@ -2868,12 +2868,20 @@
 ;%0A%09%09
-if (
+lastValue = 
 samp
@@ -2911,48 +2911,563 @@
 ue()
-)%0A%09%09%09return true;%0A%09%09else%0A%09%09%09return false
+;%0A%09%09return lastValue;%0A%09%7D%0A%0A%09@Output(name = %22Value%22,%0A%09 description = %22The last value sampled from the distribution. When used in an %22%0A%09             + %22expression, this output returns a new sample every time the expression %22%0A%09             + %22is evaluated.%22)%0A%09public boolean getNextValue(double simTime) %7B%0A%0A%09%09// If we are not in a model context, do not perturb the distribution by sampling,%0A%09%09// instead simply return the last sampled value%0A%09%09if (!EventManager.hasCurrent()) %7B%0A%09%09%09return lastValue;%0A%09%09%7D%0A%0A%09%09// Select the next sample%0A%09%09return this.getNextValue()
 ;%0A%09%7D

add "Value" output for BooleanSelector