package com.wizzardo.http.framework.template;

import com.wizzardo.tools.evaluation.EvalTools;
import com.wizzardo.tools.evaluation.Expression;
import com.wizzardo.tools.misc.Unchecked;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author: moxa
 * Date: 2/11/13
 */
public class ExpressionHolder<T> implements Renderable {
    private volatile boolean prepared = false;
    private String string;
    private Expression expression;

    public ExpressionHolder(String s) {
        string = s;
    }

    protected ExpressionHolder() {
    }

    public RenderResult get(Map<String, Object> model) {
        return new RenderResult(String.valueOf(getRaw(model)));
    }

    private static Pattern p = Pattern.compile("\\$\\{([^\\{\\}]+)\\}|\\$([^\\., -]+)|(\\[.+\\])");

    public T getRaw(Map<String, Object> model) {
        if (!prepared) {
            synchronized (this) {
                if (!prepared) {
                    Unchecked.run(() -> {
                        Matcher m = p.matcher(string);
                        if (m.find()) {
                            String exp = m.group(1);
                            if (exp == null) {
                                exp = m.group(2);
                            }
                            if (exp == null) {
                                exp = m.group(3);
                            }
                            expression = EvalTools.prepare(exp, model);
                        } else
                            expression = EvalTools.prepare(string, model);
                    });
                    prepared = true;
                }
            }
        }
        return Unchecked.call(() -> (T) expression.get(model));
    }

    @Override
    public String toString() {
        return string;
    }
}
@@ -474,16 +474,54 @@
 ression;
+%0A    protected boolean stringTemplate;
 %0A%0A    pu
@@ -566,18 +566,159 @@
     
-string = s
+this(s, false);%0A    %7D%0A%0A    public ExpressionHolder(String s, boolean stringTemplate) %7B%0A        string = s;%0A        this.stringTemplate = stringTemplate
 ;%0A  
@@ -1176,16 +1176,184 @@
 () -%3E %7B%0A
+                        if (stringTemplate)%0A                            expression = EvalTools.prepare(%22%5C%22%22 + string + %22%5C%22%22, model);%0A                        else %7B%0A    
         
@@ -1399,16 +1399,20 @@
 tring);%0A
+    
         
@@ -1471,16 +1471,20 @@
         
+    
 String e
@@ -1520,32 +1520,36 @@
                 
+   
+ 
 if (exp == null)
@@ -1575,32 +1575,36 @@
                 
+    
 exp = m.group(2)
@@ -1625,34 +1625,42 @@
                 
+   
+ 
 %7D%0A
+    
                 
@@ -1714,32 +1714,36 @@
                 
+  
+  
 exp = m.group(3)
@@ -1764,34 +1764,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -1878,16 +1878,20 @@
         
+    
 %7D else%0A 
@@ -1909,32 +1909,36 @@
                 
+ 
+   
 expression = Eva
@@ -1960,32 +1960,58 @@
 string, model);%0A
+                        %7D%0A
                 

add support for String templates