package template.dom;

import context.JustContext;

import java.util.ArrayList;
import java.util.List;

/**
 * Dom fixed structure Component Binder.
 * We bind structure use static method in this class.
 * Usage:
 * <code>
 * private static final DomCom classGen = DomCom.rule()
 *                                  .sep("public class")
 *                                  .bind("${className}")
 *                                  .sep("implement Expression")
 *                                  .sep("{")
 *                                  .append(functionGen)
 *                                  .sep("}");
 * </code>
 * @see template.TemplateImpl to get more usages
 * Created by liufengkai on 2017/7/18.
 */
public class DomCom {

    /**
     * a set of components
     */
    private List<DomComponent> components;

    private DomCom() {
        this.components = new ArrayList<>();
    }

    public static DomCom rule() {
        return new DomCom();
    }

    /**
     * return all components
     *
     * @return list of subDom
     */
    private List<DomComponent> getComponents() {
        return components;
    }

    /**
     * Add Ignore-Component
     * Ignore-Component will not check exchange Vars
     *
     * @param comString a set of ignore-string
     * @return bind ignore DomCom
     */
    public DomCom sep(String... comString) {
        components.add(new IgnoreDomComponent(comString));
        return this;
    }

    /**
     * Bind Single-Vars Dom Component In Components.
     *
     * @param bindVar vars-exchange-code
     * @return bind vars-DomCom
     */
    public DomCom bind(String bindVar) {
        components.add(new SingleDomComponent(bindVar));
        return this;
    }

    /**
     * Bind one Component to DomCom
     *
     * @param component new component
     * @return binder-DomCom
     */
    public DomCom ast(DomComponent component) {
        components.add(component);
        return this;
    }

    /**
     * Bind a sequence of Components at the last of DomCom
     *
     * @param component a set of components
     * @return return binder-DomCom
     */
    public DomCom seq(DomComponent... component) {
        components.add(new SequenceDomComponent(component));
        return this;
    }

    /**
     * Append a DomCom to self
     *
     * @param domCom new-domCom
     * @return return binder-DomCom
     */
    public DomCom append(DomCom domCom) {
        components.addAll(domCom.getComponents());
        return this;
    }

    /**
     * Return Fake Generate Component.
     *
     * @return return a set of sequence dom.
     */
    public DomComponent fakeGenerateComponent() {
        return new SequenceDomComponent(components);
    }

    /**
     * Return Fake Generate String.
     *
     * @param context Vars Context.
     * @return return fake generateCode string.
     */
    public String fakeGenerateString(JustContext context) {
        return fakeGenerateComponent()
                .generateCode(context, new StringBuilder())
                .toString();
    }
}

@@ -279,323 +279,125 @@
 %0A * 
-                                 .sep(%22public class%22)%0A *                                  .bind(%22$%7BclassName%7D%22)%0A *                                  .sep(%22implement Expression%22)%0A *                                  .sep(%22%7B%22)%0A *                                  .append(functionGen)%0A *                                 
+.sep(%22public class%22)%0A * .bind(%22$%7BclassName%7D%22)%0A * .sep(%22implement Expression%22)%0A * .sep(%22%7B%22)%0A * .append(functionGen)%0A *
  .se
@@ -415,16 +415,19 @@
 %3C/code%3E%0A
+ *%0A
  * @see 
@@ -2296,32 +2296,242 @@
 rn this;%0A    %7D%0A%0A
+    public DomCom nop(String... nopStrings) %7B%0A        return this;%0A    %7D%0A%0A    public DomCom des(String... desStrings) %7B%0A        components.add(new DescriptionComponent(desStrings));%0A        return this;%0A    %7D%0A%0A
     /**%0A     * R

update dom com string