package jp;

import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.mortbay.HTML.*;

/**
 * A class that lets a servlet incrementally build a response by
 * tweaking the parameters that appeared in a request.
 */

public class StateRef {
	Map map;
	HttpServletRequest request;

	/**
	 * Create the StateRef, supplying an HTTP request as a prototype.
	 */
	StateRef(HttpServletRequest request) {
		this.map = new Hashtable();
		this.request = request;
		Enumeration enum = request.getParameterNames();
		while (enum.hasMoreElements()) {
			String param = (String) enum.nextElement();
			map.put(param, request.getParameter(param));
		}
	}

	/**
	 * Return the name--value mappings as a Hashtable.
	 */
	Hashtable getMapAsHashtable() {
		return (Hashtable) map;
	}

	/**
	 * Clear all parameters in the new request. (Other parameters
	 * of the request, such as the base resource URL, are preserved.)
	 */
	StateRef deleteAll() {
		map.clear();
		return this;
	}

	/**
	 * Change a parameter's value.
	 */
	StateRef change(String param, String value) {
		if (value==null) {
			map.remove(param);	// remember to remove this parameter
		} else {
			map.put(param, value);
		}
		return this;
	}

	/**
	 * Extract the parameter state as a URL, suitable for redirection.
	 */
	String asUrl() {
		boolean question = true;
		StringBuffer url = new StringBuffer(request.getPathInfo());
		Iterator iter = map.keySet().iterator();
		while (iter.hasNext()) {
			String param = (String) iter.next();
			url.append(
				(question
					? "?"
					: "&")
				+URLEncoder.encode(param)
				+"="+URLEncoder.encode((String) map.get(param))
			);
			question = false;
		}
		return url.toString();
	}

	/**
	 * Extract the parameter state as a link.
	 *
	 * @param name the text that labels the link
	 */
	String asLink(String name) {
		return "<a href=\""+asUrl()+"\">"+name+"</a>";
	}

	/**
	 * Extract the parameter state as the beginning of an HTML
	 * <FORM> element, with the known parameters set as hidden input
	 * fields.
	 */
	TableForm asForm() {
		TableForm tableForm = new TableForm(request.getPathInfo());
		Iterator iter = map.keySet().iterator();
		while (iter.hasNext()) {
			String param = (String) iter.next();
			tableForm.addHiddenField(param, (String) map.get(param));
		}
		return tableForm;
	}

	/**
	 * Assumes caller doesn't continue to tweak this StateRef object.
	 * If we wanted, we could clone this object and pass the clone off
	 * to the TweakedServletRequest.
	 */
	HttpServletRequest asRequest() {
		return new TweakedServletRequest(request, this);
	}
}
