package org.seasar.jsf.render.html;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.seasar.framework.exception.EmptyRuntimeException;
import org.seasar.jsf.JsfConstants;

public class HtmlOutputLinkRenderer extends HtmlTagRenderer {

	public boolean getRendersChildren() {
		return true;
	}

	public void encodeBegin(FacesContext context, UIComponent component)
			throws IOException {

		ResponseWriter writer = context.getResponseWriter();
		String href = getValue(component, JsfConstants.VALUE_ATTR).toString();
		if (component.getChildCount() > 0) {
			StringBuffer hrefBuf = new StringBuffer(href);
			addChildParametersToHref(component, hrefBuf,
					(href.indexOf('?') == -1), writer.getCharacterEncoding());
			href = hrefBuf.toString();
		}
		href = context.getExternalContext().encodeResourceURL(href);
		writer.startElement(JsfConstants.ANCHOR_ELEM, component);
		writer.writeAttribute(JsfConstants.ID_ATTR, component
				.getClientId(context), null);
		writer.writeURIAttribute(JsfConstants.HREF_ATTR, href, null);
		renderPathThroughAttributes(writer, component);
	}

	protected void addChildParametersToHref(UIComponent component,
			StringBuffer hrefBuf, boolean firstParameter,
			String encoding) throws UnsupportedEncodingException {

		for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
			UIComponent child = (UIComponent) it.next();
			if (child instanceof UIParameter) {
				String name = ((UIParameter) child).getName();
				Object value = ((UIParameter) child).getValue();
				addChildParameterToHref(name, value, hrefBuf, firstParameter, encoding);
				firstParameter = false;
			}
		}
	}

	protected void addChildParameterToHref(String name, Object value,
			StringBuffer hrefBuf, boolean firstParameter, String encoding) throws UnsupportedEncodingException {

		if (name == null) {
			throw new EmptyRuntimeException("name");
		}
		hrefBuf.append(firstParameter ? '?' : '&');
		hrefBuf.append(URLEncoder.encode(name, encoding));
		hrefBuf.append('=');
		if (value != null) {
			hrefBuf.append(URLEncoder.encode(value.toString(), encoding));
		}
	}

	public void encodeEnd(FacesContext context, UIComponent component)
			throws IOException {

		ResponseWriter writer = context.getResponseWriter();
		writer.endElement(JsfConstants.ANCHOR_ELEM);
	}
}