package org.docksidestage.app.application;

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

import org.thymeleaf.context.ITemplateContext;
import org.thymeleaf.model.IModel;
import org.thymeleaf.model.IModelFactory;
import org.thymeleaf.model.IOpenElementTag;
import org.thymeleaf.model.IProcessableElementTag;
import org.thymeleaf.processor.element.AbstractElementTagProcessor;
import org.thymeleaf.processor.element.IElementTagStructureHandler;
import org.thymeleaf.templatemode.TemplateMode;

/**
 * Example:
 * if you put below element,
 * # <p ex:ferrors="*{xxx}"></p>
 *
 * next elements be rendered.
 * # <ul>
 * #     <li th:each="e : ${#fields.detailedErrors('xxx')}" th:class="errors">
 * #         <span th:text="${e.message}"></span>
 * #     </li>
 * # </ul>
 *
 * type of element you specify be ignored, this processor just focuses on attribute, 'ex:error'
 *
 * @author subaru
 */
public class FieldErrorsDialectProcessor extends AbstractElementTagProcessor {

    // ===================================================================================
    //                                                                          Definition
    //                                                                          ==========
    private static Pattern pattern = Pattern.compile("\\*\\{(.*)\\}");

    // ===================================================================================
    //                                                                         Constructor
    //                                                                         ===========
    protected FieldErrorsDialectProcessor() {
        super(TemplateMode.HTML, "ex", null, false, "ferrors", true, 100000);
    }

    // ===================================================================================
    //                                                                             Process
    //                                                                             =======
    @Override
    protected void doProcess(ITemplateContext context, IProcessableElementTag tag, IElementTagStructureHandler structureHandler) {
        String attrValue = tag.getAttribute("ex:ferrors").getValue();
        Matcher matcher = pattern.matcher(attrValue);
        if (!matcher.find()) {
            return;
        }
        String fieldValue = matcher.group(1);

        IModelFactory modelFactory = context.getModelFactory();
        IModel model = modelFactory.createModel();
        model.add(modelFactory.createOpenElementTag("ul", "th:if", String.format("${#fields.hasErrors('%s')}", fieldValue)));
        model.add(createLiTag(modelFactory, fieldValue));
        model.add(modelFactory.createOpenElementTag("span", "th:text", "${e.message}"));
        model.add(modelFactory.createCloseElementTag("span"));
        model.add(modelFactory.createCloseElementTag("li"));
        model.add(modelFactory.createCloseElementTag("ul"));

        structureHandler.replaceWith(model, true);
    }

    private IOpenElementTag createLiTag(IModelFactory modelFactory, String fieldValue) {
        IOpenElementTag liTag = modelFactory.createOpenElementTag("li");
        liTag = modelFactory.setAttribute(liTag, "th:each", String.format("e : ${#fields.detailedErrors('%s')}", fieldValue));
        liTag = modelFactory.setAttribute(liTag, "class", "errors");
        return liTag;
    }
}

@@ -149,16 +149,59 @@
 ontext;%0A
+import org.thymeleaf.engine.AttributeName;%0A
 import o
@@ -227,16 +227,16 @@
 IModel;%0A
-
 import o
@@ -403,39 +403,41 @@
 element.Abstract
-Element
+Attribute
 TagProcessor;%0Aim
@@ -1008,23 +1008,25 @@
 Abstract
-Element
+Attribute
 TagProce
@@ -1370,18 +1370,16 @@
 *%5C%5C%7B(.*)
-%5C%5C
 %7D%22);%0A%0A  
@@ -1770,16 +1770,22 @@
 , 100000
+, true
 );%0A    %7D
@@ -2160,125 +2160,119 @@
 ag, 
-IElementTagStructureHandler structureHandler) %7B%0A        String attrValue = tag.getAttribute(%22ex:ferrors%22).getValue();
+AttributeName attributeName, String attributeValue,%0A            IElementTagStructureHandler structureHandler) %7B
 %0A   
@@ -2314,16 +2314,21 @@
 her(attr
+ibute
 Value);%0A

refactor field error dialect processor