// Path: src/main/java/org/dynaform/xml/form/Form.java
// public interface Form {
//   
//   String HL_CHILD = "/";
//   String HL_DESCENDANT_OR_SELF = "//";
//   String LL_CHILD = "!";
//   String LL_DESCENDANT_OR_SELF = "!!";
//   String INDEX_START = "[";
//   String INDEX_END = "]";
//   String OPERATOR_SEQUENCE = "sequence";
//   String OPERATOR_CHOICE = "choice";
//   String OPERATOR_ALL = "all";
//   
//   // Identity and parent
//   String getDescendantOrSelfSelector();         // "//element"
//   String getFullSelector();                     // "/aa/bb/cc!selector[0]"
//   String getHighLevelFullSelectorForChildren(); // "/aa/bb/cc"
// 
//   String getHighLevelId();  // cc
//   String getLowLevelId();   // selector[0]
//   
//   Form getParent();
//   void _setParent(Form parent);
//   
//   // Sequence
//   String nextCounterValue();
//   
//   // Visitors
// 	void accept(FormVisitor visitor);
// 	<T> T apply(FormFunction<T> function);
// 
// }
// 
// Path: src/main/java/org/dynaform/xml/form/FormFunction.java
// public interface FormFunction<T> {
// 	
// 	<E> T element(FormElement<E> element);
// 	
// 	<F extends Form> T section(FormSection<F> section);
// 	
// 	<F extends Form> T repeat(FormRepeat<F> sequence);
// 	
// 	T sequence(FormSequence composite);
// 	
// 	T choice(FormChoice choice);
// 	
// 	T all(FormAll all);
// 
// }
// 
// Path: src/main/java/org/dynaform/xml/form/FormVisitor.java
// public interface FormVisitor {
// 
// 	<E> void element(FormElement<E> element);
// 	
// 	<F extends Form> void section(FormSection<F> section);
// 	
// 	<F extends Form> void repeat(FormRepeat<F> sequence);
// 	
// 	void sequence(FormSequence composite);
// 	
// 	void choice(FormChoice choice);
// 	
// 	void all(FormAll all);
// 	
// }


import org.dynaform.xml.form.Form;
import org.dynaform.xml.form.FormChoice;
import org.dynaform.xml.form.FormFunction;
import org.dynaform.xml.form.FormVisitor;
import org.dynaform.xml.form.ToggleFormVisitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

package org.dynaform.xml.form.impl;



/**
 * @author Rein Raudjärv
 *
 * @see FormChoice
 */
public class FormChoiceImpl extends BaseForm implements FormChoice, FormChoice.ChoiceChangeListener {

  private String id;
  
  private final List<Form> children;
  private int selectedIndex;
  
  private final Collection<ChoiceChangeListener> listeners = new ArrayList<ChoiceChangeListener>();

  public FormChoiceImpl(List<Form> children) {
    if (children == null || children.size() <= 1)
      throw new IllegalArgumentException("Children: " + children);
    
    this.children = Collections.unmodifiableList(children);
    
    // Select first child by default
    this.selectedIndex = 0;
    
    // Register myself as parent of all the children
    int i = 0;
    for (Form child : children) {
      child._setParent(this);
      
      // Disable all children except the first one
      if (i > 0)
        child.accept(ToggleFormVisitor.DISABLER);
      i++;
    }
  }
  
  public void _setParent(Form parent) {
    super._setParent(parent);
    
    if (id == null)
      id = OPERATOR_CHOICE + INDEX_START + parent.nextCounterValue() + INDEX_END;
  }

  public String getHighLevelId() {
    return null;
  }
  
  public String getLowLevelId() {
    return id;
  }
  

// Path: src/main/java/org/dynaform/xml/form/Form.java
// public interface Form {
//   
//   String HL_CHILD = "/";
//   String HL_DESCENDANT_OR_SELF = "//";
//   String LL_CHILD = "!";
//   String LL_DESCENDANT_OR_SELF = "!!";
//   String INDEX_START = "[";
//   String INDEX_END = "]";
//   String OPERATOR_SEQUENCE = "sequence";
//   String OPERATOR_CHOICE = "choice";
//   String OPERATOR_ALL = "all";
//   
//   // Identity and parent
//   String getDescendantOrSelfSelector();         // "//element"
//   String getFullSelector();                     // "/aa/bb/cc!selector[0]"
//   String getHighLevelFullSelectorForChildren(); // "/aa/bb/cc"
// 
//   String getHighLevelId();  // cc
//   String getLowLevelId();   // selector[0]
//   
//   Form getParent();
//   void _setParent(Form parent);
//   
//   // Sequence
//   String nextCounterValue();
//   
//   // Visitors
// 	void accept(FormVisitor visitor);
// 	<T> T apply(FormFunction<T> function);
// 
// }
// 
// Path: src/main/java/org/dynaform/xml/form/FormFunction.java
// public interface FormFunction<T> {
// 	
// 	<E> T element(FormElement<E> element);
// 	
// 	<F extends Form> T section(FormSection<F> section);
// 	
// 	<F extends Form> T repeat(FormRepeat<F> sequence);
// 	
// 	T sequence(FormSequence composite);
// 	
// 	T choice(FormChoice choice);
// 	
// 	T all(FormAll all);
// 
// }
// 
// Path: src/main/java/org/dynaform/xml/form/FormVisitor.java
// public interface FormVisitor {
// 
// 	<E> void element(FormElement<E> element);
// 	
// 	<F extends Form> void section(FormSection<F> section);
// 	
// 	<F extends Form> void repeat(FormRepeat<F> sequence);
// 	
// 	void sequence(FormSequence composite);
// 	
// 	void choice(FormChoice choice);
// 	
// 	void all(FormAll all);
// 	
// }


// Path: src/main/java/org/dynaform/xml/form/impl/FormChoiceImpl.java
import org.dynaform.xml.form.Form;
import org.dynaform.xml.form.FormChoice;
import org.dynaform.xml.form.FormFunction;
import org.dynaform.xml.form.FormVisitor;
import org.dynaform.xml.form.ToggleFormVisitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

package org.dynaform.xml.form.impl;



/**
 * @author Rein Raudjärv
 *
 * @see FormChoice
 */
public class FormChoiceImpl extends BaseForm implements FormChoice, FormChoice.ChoiceChangeListener {

  private String id;
  
  private final List<Form> children;
  private int selectedIndex;
  
  private final Collection<ChoiceChangeListener> listeners = new ArrayList<ChoiceChangeListener>();

  public FormChoiceImpl(List<Form> children) {
    if (children == null || children.size() <= 1)
      throw new IllegalArgumentException("Children: " + children);
    
    this.children = Collections.unmodifiableList(children);
    
    // Select first child by default
    this.selectedIndex = 0;
    
    // Register myself as parent of all the children
    int i = 0;
    for (Form child : children) {
      child._setParent(this);
      
      // Disable all children except the first one
      if (i > 0)
        child.accept(ToggleFormVisitor.DISABLER);
      i++;
    }
  }
  
  public void _setParent(Form parent) {
    super._setParent(parent);
    
    if (id == null)
      id = OPERATOR_CHOICE + INDEX_START + parent.nextCounterValue() + INDEX_END;
  }

  public String getHighLevelId() {
    return null;
  }
  
  public String getLowLevelId() {
    return id;
  }
  

  public List<Form> getChildren() {
