/*
 * This file is part of Nuts Framework.
 * Copyright(C) 2009-2012 Nuts Develop Team.
 *
 * Nuts Framework is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License any later version.
 *
 * Nuts Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Nuts Framework. If not, see <http://www.gnu.org/licenses/>.
 */
package nuts.exts.struts2.views.java.nthtml;

import nuts.core.lang.Collections;
import nuts.core.lang.Strings;
import nuts.exts.struts2.views.java.Attributes;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.struts2.components.template.TemplateRenderingContext;

@SuppressWarnings("unchecked")
public class FieldWrapper extends NthtmlTemplateRenderer {
	/**
	 * @param context context
	 */
	public FieldWrapper(TemplateRenderingContext context) {
		super(context);
	}

	protected void writeRequired() throws IOException {
		write("<span class=\"n-required\">");
		write(defs((String)params.get("requiredstring"), "*"));
		write("</span>");
	}

	protected void renderHeader() throws Exception {
		String name = (String)params.get("name");

		Map<String, List<String>> fieldErrors = (Map<String, List<String>>)findValue("fieldErrors");

		boolean hasFieldErrors = (name != null
			&& Collections.isNotEmpty(fieldErrors)
			&& fieldErrors.get(name) != null);

		Object required = params.get("required");
		String requiredposition = (String)params.get("requiredposition");
		
		String nthtml_group = (String)findInContext("nthtml_group");
		if (Strings.isEmpty(nthtml_group)) {
			write("<tr class=\"n-tr-input\"><td class=\"n-td-label\">");

			String label = (String)params.get("label");
			if (Strings.isNotEmpty(label)) {
				Attributes al = new Attributes();
				al.addIfExists("for", params.get("id"))
				  .add("class", hasFieldErrors ? "n-label-error" : "n-label");
				stag("label", al);
				
				if (Attributes.isTrue(required)
						&& "left".equals(defs(requiredposition, "left"))) {
					writeRequired();
				}
	
				write(html(label));
	
				if (Attributes.isTrue(required)
						&& "right".equals(requiredposition)) {
					write("<span class=\"n-required\">*</span>");
				}
				write(defs((String)params.get("labelseparator"), ":"));
				etag("label");
			}
			etag("td");
			
			Attributes a = new Attributes();
			a.add("class", "n-td-input")
			 .addIfExists("align", params.get("align"));
			stag("td", a);
		}
		write(before);
		
		if ("start".equals(group)) {
			putInContext("nthtml_group", defs((String)params.get("name"), "-"));
		}
		else if (Strings.isNotEmpty(nthtml_group)) {
			putInContext("nthtml_group", nthtml_group + "," + defs((String)params.get("name"), "-"));
		}
	}
	
	protected void renderFooter() throws Exception {
		Map<String, List<String>> fieldErrors = (Map<String, List<String>>)findValue("fieldErrors");

		Object required = params.get("required");
		String requiredposition = (String)params.get("requiredposition");
		
		String nthtml_group = (String)findInContext("nthtml_group");

        write(after);

		if (Strings.isEmpty(nthtml_group) || "end".equals(group)) {
			if (Attributes.isTrue(required)
					&& "side".equals(requiredposition)) {
				writeRequired();
			}
			
			if (Collections.isNotEmpty(fieldErrors)) {
				String[] fns;
				if (Strings.isEmpty(nthtml_group)) {
					fns = new String[] { defs((String)params.get("name")) };
				}
				else {
					fns = Strings.split(nthtml_group, ',');
				}
				
				for (String fn : fns) {
					List<String> fes = fieldErrors.get(fn);
					if (Strings.isNotEmpty(fn) && Collections.isNotEmpty(fes)) {
						boolean ul = false;
						for (String fe : fes) {
							if (Strings.isNotEmpty(fe)) {
								if (!ul) {
									Attributes aul = new Attributes();
									aul.add("errorFor", fn)
										.add("class", "n-field-errors");
									stag("ul", aul);
									ul = true;
								}
								write("<li class=\"n-field-error\">");
								write(icon("n-icon n-icon-error n-field-error"));
								write(phtml(fe));
								write("</li>");
							}
						}
						if (ul) {
							etag("ul");
						}
					}
				}
			}
			etag("td");
			etag("tr");
		}

		if ("end".equals(group)) {
			putInContext("nthtml_group", "");
		}
	}
	
	public void render() throws Exception {
		renderHeader();
		renderSimple();
		renderFooter();
	}

}
