/*
 * 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.events.EventManager;
import com.jaamsim.input.InputAgent;
import com.jaamsim.input.IntegerInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
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();
	private boolean lastValue;

	{
		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());
		lastValue = false;
	}

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

	public boolean getNextValue() {
		double samp = rng.nextUniform();
		lastValue = samp < trueProbInput.getValue();
		return lastValue;
	}

	@Output(name = "Value",
	 description = "The last value sampled from the distribution. When used in an "
	             + "expression, this output returns a new sample every time the expression "
	             + "is evaluated.")
	public boolean getNextValue(double simTime) {

		// If we are not in a model context, do not perturb the distribution by sampling,
		// instead simply return the last sampled value
		if (!EventManager.hasCurrent()) {
			return lastValue;
		}

		// Select the next sample
		return this.getNextValue();
	}
}

@@ -87,19 +87,63 @@
 da Inc.%0A
+ * Copyright (C) 2016 JaamSim Software Inc.%0A
  *%0A
-
  * Licen
@@ -775,32 +775,115 @@
 .DisplayEntity;%0A
+import com.jaamsim.Samples.SampleConstant;%0Aimport com.jaamsim.Samples.SampleInput;%0A
 import com.jaams
@@ -1089,45 +1089,8 @@
 ut;%0A
-import com.jaamsim.input.ValueInput;%0A
 impo
@@ -1516,16 +1516,60 @@
 = %7B%220.5%22
+, %22InputValue1%22, %22'2 * %5BInputValue1%5D.Value'%22
 %7D)%0A%09priv
@@ -1572,20 +1572,21 @@
 private 
-Valu
+Sampl
 eInput t
@@ -1945,20 +1945,21 @@
 t = new 
-Valu
+Sampl
 eInput(%22
@@ -1990,21 +1990,41 @@
 nputs%22, 
+new SampleConstant(
 1.0d)
+)
 ;%0A%09%09true
@@ -2114,16 +2114,49 @@
  1.0d);%0A
+%09%09trueProbInput.setEntity(this);%0A
 %09%09this.a
@@ -3057,26 +3057,21 @@
 ;%0A%09%09
-lastValue = samp %3C
+double prob =
  tru
@@ -3091,16 +3091,60 @@
 tValue()
+.getNextSample(0);%0A%09%09lastValue = samp %3C prob
 ;%0A%09%09retu
@@ -3668,34 +3668,151 @@
 e%0A%09%09
-return this.getNextValue()
+double samp = rng.nextUniform();%0A%09%09double prob = trueProbInput.getValue().getNextSample(simTime);%0A%09%09lastValue = samp %3C prob;%0A%09%09return lastValue
 ;%0A%09%7D

convert BooleanSelector keywords to SampleInput