package com.wizzardo.tools.evaluation;

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

/**
 * @author: moxa
 * Date: 11/19/13
 */
public class TemplateBuilder extends Expression {
    private List<Expression> parts = new ArrayList<Expression>();

    @Override
    public void setVariable(Variable v) {
        for (Expression e : parts)
            e.setVariable(v);
    }

    @Override
    public Expression clone() {
        TemplateBuilder tb = new TemplateBuilder();
        for (Expression e : parts) {
            tb.parts.add(e.clone());
        }
        return tb;
    }

    @Override
    public Object get(Map<String, Object> model) {
        if (hardcoded)
            return result;

        if (parts.isEmpty())
            return "";

        StringBuilder sb = new StringBuilder();
        boolean hardcoded = true;
        for (Expression e : parts) {
            sb.append(e.get(model));
            hardcoded &= e.hardcoded;
        }
        String result = sb.toString();
        if (hardcoded) {
            super.hardcoded = hardcoded;
            super.result = result;
        }

        return result;
    }

    public TemplateBuilder append(Expression e) {
        parts.add(e);
        return this;
    }

    public TemplateBuilder append(String s) {
        parts.add(new Holder(s, true));
        return this;
    }
}

@@ -33,16 +33,58 @@
 ation;%0A%0A
+import com.wizzardo.tools.misc.Supplier;%0A%0A
 import j
@@ -773,99 +773,65 @@
     
-if (parts.isEmpty())%0A            return %22%22;%0A%0A        StringBuilder sb = new StringBuilder
+Supplier%3CString%3E%5B%5D suppliers = new Supplier%5Bparts.size
 ()
+%5D
 ;%0A  
@@ -840,16 +840,8 @@
     
-boolean 
 hard
@@ -859,32 +859,80 @@
 e;%0A        for (
+int i = 0; i %3C parts.size(); i++) %7B%0A            
 Expression e : p
@@ -924,34 +924,39 @@
 xpression e 
-:
+=
  parts
-) %7B
+.get(i);
 %0A           
@@ -960,18 +960,25 @@
     
-sb.append(
+final Object o = 
 e.ge
@@ -985,17 +985,16 @@
 t(model)
-)
 ;%0A      
@@ -1037,397 +1037,1697 @@
     
-%7D%0A        String result = sb.toString();%0A        if (hardcoded) %7B%0A            super.hardcoded = hardcoded;%0A            super.result = result;%0A        %7D%0A%0A        return result;%0A    %7D%0A%0A    public TemplateBuilder append(Expression e) %7B%0A        parts.add(e);%0A        return this;%0A    %7D%0A%0A    public TemplateBuilder append(String s) %7B%0A        parts.add(new Holder(s, true));%0A        return this;
+    if (e.hardcoded) %7B%0A                final String s = String.valueOf(o);%0A                suppliers%5Bi%5D = new Supplier%3CString%3E() %7B%0A                    @Override%0A                    public String supply() %7B%0A                        return s;%0A                    %7D%0A                %7D;%0A            %7D else if (o instanceof ClosureExpression) %7B%0A                final ClosureExpression expression = (ClosureExpression) o;%0A                suppliers%5Bi%5D = new Supplier%3CString%3E() %7B%0A                    @Override%0A                    public String supply() %7B%0A                        return String.valueOf(expression.get());%0A                    %7D%0A                %7D;%0A            %7D else %7B%0A                suppliers%5Bi%5D = new Supplier%3CString%3E() %7B%0A                    @Override%0A                    public String supply() %7B%0A                        return String.valueOf(o);%0A                    %7D%0A                %7D;%0A            %7D%0A        %7D%0A        GString gString = new GString(suppliers);%0A        if (hardcoded)%0A            result = gString;%0A        return gString;%0A    %7D%0A%0A    public TemplateBuilder append(Expression e) %7B%0A        parts.add(e);%0A        return this;%0A    %7D%0A%0A    public TemplateBuilder append(String s) %7B%0A        parts.add(new Holder(s, true));%0A        return this;%0A    %7D%0A%0A    public static class GString %7B%0A        final Supplier%3CString%3E%5B%5D parts;%0A%0A        public GString(Supplier%3CString%3E%5B%5D parts) %7B%0A            this.parts = parts;%0A        %7D%0A%0A        @Override%0A        public String toString() %7B%0A            StringBuilder sb = new StringBuilder();%0A            for (Supplier%3CString%3E part : parts) %7B%0A                sb.append(part.supply());%0A            %7D%0A            return sb.toString();%0A        %7D
 %0A   

add GString