package pizzavolumecalculator.actor;

import static java.lang.Math.PI;

import java.util.function.Consumer;
import java.util.function.Supplier;

import org.requirementsascode.AbstractActor;
import org.requirementsascode.Condition;
import org.requirementsascode.Model;

import pizzavolumecalculator.actor.command.CalculateVolume;
import pizzavolumecalculator.actor.command.EnterHeight;
import pizzavolumecalculator.actor.command.EnterRadius;

public class PizzaVolumeCalculator extends AbstractActor{
  private int z;
  private int a;
  
  private Consumer<EnterRadius> saveRadius;
  private Consumer<EnterHeight> saveHeight;
  private Supplier<Double> calculateVolume;
  private Runnable throwIllegalRadiusException;
  private Runnable throwIllegalHeightException;
  private Condition isNegativeRadius;
  private Condition isNegativeHeight;

  public PizzaVolumeCalculator() {
    this.saveRadius = this::saveRadius;
    this.saveHeight = this::saveHeight;
    this.calculateVolume = this::calculateVolume;
    this.throwIllegalRadiusException = this::throwIllegalRadiusException;
    this.throwIllegalHeightException = this::throwIllegalHeightException;
    this.isNegativeRadius = this::isNegativeRadius;
    this.isNegativeHeight = this::isNegativeHeight;
  }
  
  @Override
  public Model behavior() {
		Model model = Model.builder()
			.useCase("Calculate Pizza Volume")
				.basicFlow()
					.step("S1").user(EnterRadius.class).system(saveRadius)
	        .step("S2").user(EnterHeight.class).system(saveHeight)
	        .step("S3").user(CalculateVolume.class).systemPublish(calculateVolume)
	        .step("S4").continuesAt("S1")
	      
	      .flow("Negative radius").after("S1").condition(isNegativeRadius)
	        .step("S1a_1").system(throwIllegalRadiusException)

	      .flow("Negative height").after("S2").condition(isNegativeHeight)
          .step("S2a_1").system(throwIllegalHeightException)
          
			  .build();
		
		return model;
  }
  
  // system reactions
  private void saveRadius(EnterRadius enterRadius) {
    this.z = enterRadius.getRadius();
  }
  
  private void saveHeight(EnterHeight enterHeight) {
    this.a = enterHeight.getHeight();
  }
  
  private Double calculateVolume() {
    return PI * z * z * a;
  }
  
  private void throwIllegalRadiusException() {
    throw new IllegalArgumentException("Please specify a non-negative radius!");
  }
  
  private void throwIllegalHeightException() {
    throw new IllegalArgumentException("Please specify a non-negative height!");
  }
  
  // conditions
  private boolean isNegativeRadius() {
    return z < 0;
  }
  
  private boolean isNegativeHeight() {
    return a < 0;
  }
}
@@ -491,16 +491,17 @@
 actActor
+ 
 %7B%0A  priv
@@ -528,18 +528,16 @@
  int a;%0A
-  
 %0A  priva
@@ -1255,18 +1255,16 @@
 ht;%0A  %7D%0A
-  
 %0A  @Over
@@ -1296,18 +1296,20 @@
 ior() %7B%0A
-%09%09
+    
 Model mo
@@ -1330,19 +1330,22 @@
 ilder()%0A
-%09%09%09
+      
 .useCase
@@ -1370,21 +1370,16 @@
 Volume%22)
-%0A%09%09%09%09
 .basicFl
@@ -1387,13 +1387,16 @@
 w()%0A
-%09%09%09%09%09
+        
 .ste
@@ -1438,33 +1438,32 @@
 tem(saveRadius)%0A
-%09
         .step(%22S
@@ -1509,17 +1509,16 @@
 Height)%0A
-%09
         
@@ -1588,17 +1588,16 @@
 Volume)%0A
-%09
         
@@ -1630,17 +1630,9 @@
 1%22)%0A
-%09      %0A%09
+%0A
     
@@ -1698,17 +1698,16 @@
 Radius)%0A
-%09
         
@@ -1758,17 +1758,16 @@
 ption)%0A%0A
-%09
       .f
@@ -1833,26 +1833,24 @@
 ht)%0A        
- 
- 
 .step(%22S2a_1
@@ -1892,24 +1892,15 @@
 on)%0A
-  
+%0A
       
-  %0A%09%09%09  
 .bui
@@ -1909,13 +1909,13 @@
 ();%0A
-%09%09%0A%09%09
+%0A    
 retu
@@ -1924,26 +1924,24 @@
  model;%0A  %7D%0A
-  
 %0A  // system
@@ -2038,34 +2038,32 @@
 etRadius();%0A  %7D%0A
-  
 %0A  private void 
@@ -2138,26 +2138,24 @@
 ight();%0A  %7D%0A
-  
 %0A  private D
@@ -2207,26 +2207,24 @@
  z * a;%0A  %7D%0A
-  
 %0A  private v
@@ -2340,26 +2340,24 @@
 ius!%22);%0A  %7D%0A
-  
 %0A  private v
@@ -2477,18 +2477,16 @@
 %22);%0A  %7D%0A
-  
 %0A  // co
@@ -2555,18 +2555,16 @@
  0;%0A  %7D%0A
-  
 %0A  priva

Improve layout