/*
   * Generate initializers for any declared states, as well as any event
   * initializers for states.
   */
  private void genStateInitializers(StatesModel model, CodeFragmentList list, String indent) {
    Set<String> states = model.info.getStateNames();
    int count = 0;
    for (Iterator<String> iter = states.iterator(); iter.hasNext(); ) {
      State state = (State) model.stateByName((String) iter.next());
      if (state != null) {
        // Declaration initializer
        if (state.isDeclared()) {
          list.add(indent, state.getId() + "= states[" + count + "];", 0);
        }

        // Event handlers
        for (Iterator<Initializer> initializers = state.getEvents(); initializers.hasNext(); ) {
          EventInitializer ei = (EventInitializer) initializers.next();
          list.add(
              indent,
              "states["
                  + count
                  + "].addEventListener(\""
                  + ei.getName()
                  + "\", "
                  + ei.getValueExpr()
                  + " );",
              0);
        }
      }
      count++;
    }
  }
  /*
   * Generates the code to initialize all states and overrides for our
   * component instance.
   */
  public CodeFragmentList getStatesInitializerFragments(StatesModel model) {
    CodeFragmentList list = new CodeFragmentList();

    String indent = "\t\t";
    genSharedFactories(model, list, indent);
    list.add("\n", 0);
    genStates(model, list, indent);
    list.add("\n", 0);
    genBindingInitializers(list, indent);
    list.add("\n", 0);
    genStateInitializers(model, list, indent);
    list.add("\n", 0);
    genImmediateInits(model, list, indent);
    return list;
  }
  /*
   * Generates the initializers for all values that are shared between states (e.g. all instance factories
   * shared by AddItems overrides).
   */
  private void genSharedFactories(StatesModel model, CodeFragmentList list, String indent) {
    Map<String, SharedObject> shared = model.sharedObjects;

    for (Iterator<String> iter = shared.keySet().iterator(); iter.hasNext(); ) {
      SharedObject symbol = shared.get(iter.next());
      String lval =
          indent
              + "var "
              + symbol.name
              + "_factory:"
              + NameFormatter.retrieveClassName(standardDefs.CLASS_DEFERREDINSTANCEFROMFUNCTION)
              + " = \n";
      indent += StatesGenerator.INDENT;
      String suffix = symbol.model.isDeclared() ? "_i" : "_c";
      Boolean isTransient = symbol.model.getIsTransient();
      String rval =
          indent
              + "new "
              + NameFormatter.toDot(standardDefs.CLASS_DEFERREDINSTANCEFROMFUNCTION)
              + "("
              + symbol.name
              + suffix
              + (isTransient ? ", " + symbol.name + "_r" : "")
              + ");";
      indent = indent.substring(0, indent.length() - INDENT.length());
      list.add(lval, rval, 0);
    }
  }
  /*
   * Generate the states array.
   */
  private void genStates(StatesModel model, CodeFragmentList list, String indent) {
    Set<String> states = model.info.getStateNames();

    if (!states.isEmpty()) {
      list.add(indent, "states = [", 0);

      indent += StatesGenerator.INDENT;
      for (Iterator<String> iter = states.iterator(); iter.hasNext(); ) {
        State state = (State) model.stateByName((String) iter.next());
        if (state != null) {
          state.getDefinitionBody(list, indent, bindingsQueue);
          if (iter.hasNext()) list.add(indent, ",", 0);
        }
      }
      indent = indent.substring(0, indent.length() - INDENT.length());
      list.add(indent, "];", 0);
    }
  }
  /*
   * Generate all calls to instantiate itemCreationPolicy='immediate' nodes.
   */
  private void genImmediateInits(StatesModel model, CodeFragmentList list, String indent) {
    List<String> objects = model.earlyInitObjects;

    for (Iterator<String> iter = objects.iterator(); iter.hasNext(); ) {
      String symbol = iter.next();
      String lval = indent + symbol + "_factory.getInstance();\n";
      indent += StatesGenerator.INDENT;
      list.add(lval, 0);
    }
  }
 /*
  * Generate all necessary binding instance initializers for any data bound overrides.
  */
 private void genBindingInitializers(CodeFragmentList list, String indent) {
   for (Iterator<StatesModel.Override> iter = bindingsQueue.iterator(); iter.hasNext(); ) {
     StatesModel.Override symbol = (StatesModel.Override) iter.next();
     list.add(
         indent,
         NameFormatter.toDot(standardDefs.CLASS_BINDINGMANAGER),
         ".executeBindings(this, \"" + symbol.declaration + "\", " + symbol.declaration + ");",
         0);
   }
 }