package de.brightbyte.yates;

import java.util.Map;

import de.brightbyte.xml.XmlUtil;


public class DumpRenderer implements YatesMacro {
	public static final DumpRenderer instance = new DumpRenderer();
	
	public String render(YatesParameters parameters) throws YatesException {
		StringBuilder s = new StringBuilder();
		
		s.append("\n<div class='yates-dump'>");
		
		YatesScope p = parameters;
		int i = 1;
		while (p!=null) {
			if (p instanceof YatesParameters) {
				s.append("\n\n<h4>SCOPE #"+i+"</h4>\n\n");
				
				s.append("\n<h5>PARAMETERS</h5>\n");
				dump(((YatesParameters)p).parameters, s);

				s.append("\n<h5>SUBJECT</h5>\n");
				dump(((YatesParameters)p).subject, s);
				
				p = ((YatesParameters)p).parent;
			}
			else {
				s.append("\n\n<h4>ROOT CONTEXT</h4>\n\n");
				dump(((YatesContext)p).data, s);
				p = null;
			}
			
			i++;
		}
		
		return s.toString();
	}

	protected void dump(Object x, StringBuilder s) {
		if (x == null) {
			s.append("<div>NULL</div>\n");
		}
		else if (x instanceof Map) {
			s.append("<dl>");
			for (Map.Entry e: (Iterable<Map.Entry>)((Map)x).entrySet()) {
				s.append("<dt>\n");
				dump(e.getKey(), s);
				s.append("</dt>\n");
				s.append("<dd>\n");
				dump(e.getValue(), s);
				s.append("</dd>\n");
			}
			s.append("</dl>\n");
		}
		
		else if (x instanceof Iterable) {
			s.append("<ul>\n");
			for (Object xx: (Iterable)x) {
				s.append("<li>\n");
				dump(xx, s);
				s.append("</li>\n");
			}
			s.append("</ul>");
		}
		else if (x instanceof String) {
			s.append("<div>\""+XmlUtil.escape((String)x)+"\"</div>\n");
		}
		else if (x instanceof Number) {
			s.append("<div>"+XmlUtil.escape(x.toString())+"</div>\n");
		}
		else {
			s.append("<div>("+x.getClass().getName()+") "+XmlUtil.escape(x.toString())+"</div>\n");
		}
	}

}
