import java.util.ArrayList;
import java.util.Scanner;


// Define a "lowest common denominator"
interface AbsBallot {
  public void doVote();   // select yes/no on item
  public void tellVote(int lev);
  public String getIdentifier();
}

// Item implements the "lowest common denominator"
// on ballot it is a single issue to vote yes/no on
class Issue implements AbsBallot {
  Scanner keybd = new Scanner(System.in);

  static int num=0;
  private int id;
  private String text = "issue";
  private String identifier = "issue";
  private boolean choice=false;
  
  public Issue(String nm) { id=++num; text=nm; }
  
  public void doVote() { 
    String x;
    System.out.print("issue: " + text + "? y/n "); 
    x = keybd.nextLine().toLowerCase(); 
    choice = (x.equals("y") || x.equals("yes") );
  }
  
  public void tellVote(int lev) { 
    for (int i=0; i<lev; i++) { System.out.print("   "); }
    System.out.println("issue: " + text + ", choice: "+choice); 
  }
  
  public boolean getVote()
  {
	  return choice;	  
  }

  public String getIdentifier()
  {
	  	  return identifier;
  }

}


// Ballot implements the "lowest common denominator"
// collection of items, a single level of election
class Ballot implements AbsBallot {

  private static int num=0;
  private int id;
  private String text = "collection";
  private String identifier = "collection";
  private ArrayList issues = new ArrayList();

  public Ballot(String nm) { id=++num; text=nm; }
  
  public void add(Object obj) { issues.add(obj); }
  public void remove(int  i) {issues.remove(i);}
  public void doVote() { 
    System.out.println("voting ballot: "+ text);
    for (int i = 0; i < issues.size(); ++i) {
      // Leverage the "lowest common denominator"
      AbsBallot bobj = (AbsBallot)issues.get(i); 
      bobj.doVote();
    }
  }  
  
  public ArrayList getIssues()
  {
	  return issues;
  }

  public void tellVote(int lev) {
    AbsBallot cobj;
    for (int i=0; i<lev; i++) { System.out.print("   "); }
    System.out.println("\nreporting ballot: " + text);
    for (int i = 0; i < issues.size(); ++i) {
      // Leverage the "lowest common denominator"
      cobj = (AbsBallot)issues.get(i);
      cobj.tellVote(lev+1);
    }
    System.out.println(" ");
  }
  
  public String getIdentifier()
  {
	  	  return identifier;
  }
  
}
 
class BallotFactory {
  // singleton pattern
  private static BallotFactory theOne=null; 
  
  private BallotFactory() { }
  
  public static BallotFactory makeTheOne() {  
    if (theOne==null) { theOne = new BallotFactory(); } 
    return theOne;
  }
  
  public AbsBallot genBallot(String type, String msg) {
    if (type=="leaf") {  return new Issue(msg); } 
    else { return new Ballot(msg); }
  }
  
  
}
