package org.reactfx.inhibeans.demo;

import java.util.function.Predicate;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableBooleanValue;

import org.reactfx.Hold;
import org.reactfx.inhibeans.binding.BooleanBinding;

public class AndGateDemo {

    interface AndGate {
        void setInputs(boolean a, boolean b);
        ObservableBooleanValue a();
        ObservableBooleanValue b();
        ObservableBooleanValue output();
    }

    static void test(AndGate gate) {
        class Counter {
            int count = 0;
            public void inc() { count += 1; }
            public int get() { return count; }
        }

        Predicate<AndGate> consistent = g ->
            g.output().get() == (g.a().get() && g.b().get());

        gate.setInputs(false, false);
        assert gate.output().get() == false;

        Counter na = new Counter();
        Counter nb = new Counter();
        Counter no = new Counter();

        gate.a().addListener(observable -> {
            assert consistent.test(gate);
            na.inc();
        });
        gate.b().addListener(observable -> {
            assert consistent.test(gate);
            nb.inc();
        });
        gate.output().addListener(observable -> {
            assert consistent.test(gate);
            no.inc();
        });

        gate.setInputs(true, true);
        assert gate.output().get() == true;

        assert na.get() == 1;
        assert nb.get() == 1;
        assert no.get() == 1;
    }

    static class AndGateImpl implements AndGate {
        private final BooleanProperty a = new SimpleBooleanProperty();
        private final BooleanProperty b = new SimpleBooleanProperty();
        private final BooleanBinding output = BooleanBinding.wrap(a.and(b));

        @Override
        public void setInputs(boolean a, boolean b) {
            Hold hold = output.block();
            this.a.set(a);
            this.b.set(b);
            hold.close();
        }

        @Override public ObservableBooleanValue a() { return a; }
        @Override public ObservableBooleanValue b() { return b; }
        @Override public ObservableBooleanValue output() { return output; }
    }

    public static void main(String[] args) {
        test(new AndGateImpl());
        System.out.println("AndGate implementation passed the test.");
    }
}

@@ -236,19 +236,20 @@
 reactfx.
-Hol
+Guar
 d;%0Aimpor
@@ -1913,16 +1913,18 @@
     
-Hold hol
+Guard guar
 d = 
@@ -2009,11 +2009,12 @@
     
-hol
+guar
 d.cl

Replace Hold with Guard in the demo.