package to.etc.domui.util;

import javax.annotation.*;

import to.etc.domui.component.misc.*;
import to.etc.domui.dom.html.*;
import to.etc.domui.server.*;
import to.etc.domui.state.*;
import to.etc.util.*;
import to.etc.webapp.mailer.*;
import to.etc.webapp.query.*;

/**
 * Helps with rendering a log message as DomUI linked text. Uses TextLinkInfo as factory
 * to find DomUI pages belonging to links.
 *
 * @author <a href="mailto:jal@etc.to">Frits Jalvingh</a>
 * Created on Oct 29, 2010
 */
final public class DomUILinkedTextRenderer implements ITextLinkRenderer {
	private NodeContainer m_c;

	public DomUILinkedTextRenderer() {}

	public void setContainer(@Nonnull NodeContainer c) {
		m_c = c;
	}

	@Override
	public void appendLink(@Nonnull String rurl, @Nonnull String text) {
		//-- Is this a DomUI url?
		String page, query;
		int pos = rurl.indexOf('?');
		if(pos == -1) {
			page = rurl;
			query = null;
		} else {
			page = rurl.substring(0, pos);
			query = rurl.substring(pos);
		}

		ALink link;
		String ext = DomApplication.get().getUrlExtension();

		if(!page.endsWith("." + ext)) {
			//-- Non-DomUI link.
			rurl = UIContext.getRequestContext().getRelativePath(rurl);
			link = new ALink(rurl, null, null);
		} else {
			//-- DomUI page. Extract the class
			page = page.substring(0, page.length() - ext.length() - 1);
			Class< ? > clz;
			try {
				clz = m_c.getClass().getClassLoader().loadClass(page);
			} catch(Exception x) {
				throw WrappedException.wrap(x);
			}
			if(!(UrlPage.class.isAssignableFrom(clz)))
				throw new IllegalStateException("Class " + clz + " is not a DomUI class");
			Class< ? extends UrlPage> pageClz = (Class< ? extends UrlPage>) clz;

			PageParameters pp = new PageParameters();
			if(null != query) {
				String[] ar = query.substring(1).split("&");
				for(String param : ar) {
					String name, val;
					pos = param.indexOf('=');
					if(pos != -1) {
						name = param.substring(0, pos);
						val = param.substring(pos + 1);
					} else {
						name = param;
						val = "";
					}
					pp.addParameter(name, val);
				}
			}
			link = new ALink(pageClz, pp);
		}

		m_c.add(link);
		link.add(text);
	}

	@Override
	public void appendText(@Nonnull String text) {
		int pos = 0;
		int len = text.length();
		while(pos < len) {
			int nl = text.indexOf("\n", pos);
			if(nl == -1) {
				DomUtil.renderHtmlString(m_c, text.substring(pos));
				return;
			}
			if(nl > pos) {
				DomUtil.renderHtmlString(m_c, text.substring(pos, nl));
			}
			pos = nl + 1;
			m_c.add(new BR());
		}
	}

	static public void register(@Nonnull Class< ? extends IIdentifyable< ? >> dataClass, @Nonnull Class< ? extends UrlPage> page, String paramName) {
		TextLinkInfo.register(dataClass, DomUtil.createPageRURL(page, null) + "?" + paramName + "={id}");
	}

	static public void register(@Nonnull String linkName, @Nonnull Class< ? extends UrlPage> page, @Nonnull String paramName) {
		TextLinkInfo.register(linkName, DomUtil.createPageRURL(page, null) + "?" + paramName + "={id}");
	}

}

@@ -32,28 +32,42 @@
 ort 
-javax.annotation.*;%0A
+to.etc.domui.component.misc.ALink;
 %0Aimp
@@ -87,24 +87,63 @@
 mui.
-component.misc.*
+dom.html.BR;%0Aimport to.etc.domui.dom.html.NodeContainer
 ;%0Aim
@@ -169,17 +169,23 @@
 om.html.
-*
+UrlPage
 ;%0Aimport
@@ -205,17 +205,72 @@
 .server.
-*
+DomApplication;%0Aimport to.etc.domui.state.PageParameters
 ;%0Aimport
@@ -289,17 +289,25 @@
 i.state.
-*
+UIContext
 ;%0Aimport
@@ -319,17 +319,79 @@
 tc.util.
-*
+WrappedException;%0Aimport to.etc.webapp.mailer.ITextLinkRenderer
 ;%0Aimport
@@ -412,17 +412,28 @@
 .mailer.
-*
+TextLinkInfo
 ;%0Aimport
@@ -453,17 +453,63 @@
 p.query.
-*
+IIdentifyable;%0A%0Aimport javax.annotation.Nonnull
 ;%0A%0A/**%0A 
@@ -1228,16 +1228,20 @@
 ring(pos
+ + 1
 );%0A%09%09%7D%0A%0A
@@ -1934,16 +1934,17 @@
 ) clz;%0A%0A
+%0A
 %09%09%09PageP
@@ -2011,328 +2011,52 @@
 %09%09%09%09
-String%5B%5D ar = query.substring(1).split(%22&%22);%0A%09%09%09%09for(String param : ar) %7B%0A%09%09%09%09%09String name, val;%0A%09%09%09%09%09pos = param.indexOf('=');%0A%09%09%09%09%09if(pos != -1) %7B%0A%09%09%09%09%09%09name = param.substring(0, pos);%0A%09%09%09%09%09%09val = param.substring(pos + 1);%0A%09%09%09%09%09%7D else %7B%0A%09%09%09%09%09%09name = param;%0A%09%09%09%09%09%09val = %22%22;%0A%09%09%09%09%09%7D%0A%09%09%09%09%09pp.addParameter(name, val);%0A%09%09%09%09%7D
+pp = PageParameters.decodeParameters(query);
 %0A%09%09%09

Fix environment links display in all log pages.