/* "Product" */
class Burger {
  private String name = "";
  private String bun = "";
  private String sauce = "";
  private String patty = "";

  public void setName(String name) {this.name = name;}
  public void setBun(String bun)     { this.bun = bun; }
  public void setSauce(String sauce)     { this.sauce = sauce; }
  public void setPatty(String patty) { this.patty = patty; }

  public String getName(){return name;}
  public String getBun(){return bun;}
  public String getSauce(){return sauce;}
  public String getPatty(){return patty;}
}

/* "Abstract Builder" */
abstract class BurgerBuilder {
  protected Burger burger;

  public Burger getBurger() { return burger; }
  public void createNewBurgerProduct() { burger = new Burger(); }

  public abstract void buildName();
  public abstract void buildBun();
  public abstract void buildSauce();
  public abstract void buildPatty();
}

/* "ConcreteBuilder" */
class VeganBurgerBuilder extends BurgerBuilder {
  public void buildName() {burger.setName("Vegan Burger");}
  public void buildBun()   { burger.setBun("rice bun"); }
  public void buildSauce()   { burger.setSauce("mild"); }
  public void buildPatty() { burger.setPatty("Tofu"); }
}

/* "ConcreteBuilder" */
class SpicyBurgerBuilder extends BurgerBuilder {
  public void buildName() {burger.setName("Spicy Burger");}
  public void buildBun()   { burger.setBun("burger bun"); }
  public void buildSauce()   { burger.setSauce("hot"); }
  public void buildPatty() { burger.setPatty("Beef"); }

}

/* "Director" */
class Waiter {
  private BurgerBuilder burgerBuilder;

  public void setBurgerBuilder(BurgerBuilder pb) { burgerBuilder = pb; }
  public Burger getBurger() { return burgerBuilder.getBurger(); }

  public void constructBurger() {
    burgerBuilder.createNewBurgerProduct();
    burgerBuilder.buildName();
    burgerBuilder.buildBun();
    burgerBuilder.buildSauce();
    burgerBuilder.buildPatty();
  }
}

/* A customer ordering a burger. */
class BuilderExample1 {
  public static void main(String[] args) {
    //case1
    Waiter waiter = new Waiter();
    BurgerBuilder vegan_burgerbuilder = new VeganBurgerBuilder();
    BurgerBuilder spicy_burgerbuilder = new SpicyBurgerBuilder();

    waiter.setBurgerBuilder( vegan_burgerbuilder );
    waiter.constructBurger();

    Burger burger = waiter.getBurger();

    System.out.println("What does the client get: ");
    System.out.println(burger.getName() + " , it has: " + burger.getBun() + ", "+ burger.getSauce()+ ", "+ burger.getPatty());

    //case2
    System.out.println("");

    Waiter waiter2 = new Waiter();

    waiter2.setBurgerBuilder( vegan_burgerbuilder );
    waiter2.constructBurger();
    Burger burger2 = waiter2.getBurger();

    System.out.println("What does the client get: ");
    System.out.println(burger.getName() + " , it has: " + burger2.getBun() + ", "+ burger2.getSauce()+ ", "+ burger2.getPatty());

    waiter2.setBurgerBuilder( spicy_burgerbuilder );
    waiter2.constructBurger();
    burger2 = waiter2.getBurger();

    System.out.println(burger2.getName() + " , it has: " + burger2.getBun() + ", "+ burger2.getSauce()+ ", "+ burger2.getPatty());

  }
}
