/*
 * Copyright (c) 2003, Morpho Project.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *	  this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *	  this list of conditions and the following disclaimer in the documentation
 *	  and/or other materials provided with the distribution.
 * 3. Neither the name of the Morpho Project nor the names of its contributors
 *	  may be used to endorse or promote products derived from this software
 *	  without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package jp.morpho.webapp.servlet.jsp.tagext.html;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;

import jp.morpho.util.ConversionMap;
import jp.morpho.webapp.servlet.http.HttpActionRequest;
import jp.morpho.webapp.servlet.http.impl.HttpActionRequestImpl;

/**
 * <P>
 * SELECT 要素によって作成されたメニューの選択肢です。
 * </P>
 * <P>
 * OPTION の HTML 4 定義は次のとおりです。
 * <PRE>
 * &lt;!ELEMENT OPTION - O (#PCDATA)         -- selectable choice --&gt;
 * &lt;!ATTLIST OPTION
 *   %attrs;                              -- %coreattrs, %i18n, %events --
 *   selected    (selected)     #IMPLIED
 *   disabled    (disabled)     #IMPLIED  -- unavailable in this context --
 *   label       %Text;         #IMPLIED  -- for use in hierarchical menus --
 *   value       CDATA          #IMPLIED  -- defaults to element content --
 *   &gt;
 * </PRE>
 * </P>
 * @author Kumiko Hiroi
 */
public class OptionTag extends ControlTagSupport
{

	/**
	 * <P>
	 * OptionTag を作成します。
	 * </P>
	 */
	public OptionTag()
	{
		super();
	}

	/**
	 * <P>
	 * disabled 属性を返します。
	 * </P>
	 * @return disabled 属性
	 */
	public boolean getDisabled()
	{
		return getAttributeMap().getBoolean("disabled");
	}

	/**
	 * <P>
	 * label 属性を返します。
	 * </P>
	 * @return label 属性
	 */
	public String getLabel()
	{
		return getAttributeMap().getString("label");
	}

	/**
	 * <P>
	 * selected 属性を返します。
	 * </P>
	 * @return selected 属性
	 */
	public boolean getSelected()
	{
		return getAttributeMap().getBoolean("selected");
	}

	/**
	 * <P>
	 * value 属性を返します。
	 * </P>
	 * @return value 属性
	 */
	public String getValue()
	{
		return getAttributeMap().getString("value");
	}

	/**
	 * <P>
	 * disabled 属性を設定します。
	 * </P>
	 * @param disabled disabled 属性
	 */
	public void setDisabled(boolean disabled)
	{
		getAttributeMap().putBoolean("disabled", disabled);
	}

	/**
	 * <P>
	 * label 属性を設定します。
	 * </P>
	 * @param label label 属性
	 */
	public void setLabel(String label)
	{
		getAttributeMap().putString("label", label);
	}

	/**
	 * <P>
	 * selected 属性を設定します。
	 * </P>
	 * @param selected selected 属性
	 */
	public void setSelected(boolean selected)
	{
		getAttributeMap().putBoolean("selected", selected);
	}

	/**
	 * <P>
	 * value 属性を設定します。
	 * </P>
	 * @param value value 属性
	 */
	public void setValue(String value)
	{
		getAttributeMap().putString("value", value);
	}

	/**
	 * <P>
	 * 終了タグの処理です。
	 * </P>
	 * @return EVAL_PAGE
	 * @see javax.servlet.jsp.tagext.Tag#doEndTag()
	 */
	public int doEndTag() throws JspException
	{
		StringBuffer buf = new StringBuffer();

		buf.append("</option>");

		try
		{
			JspWriter out = pageContext.getOut();
			out.print(buf.toString());
		}
		catch (IOException e)
		{
			throw new JspException(e.getMessage());
		}

		return super.doEndTag();
	}

	/**
	 * <P>
	 * 開始タグの処理です。
	 * </P>
	 * @return EVAL_BODY_BUFFERED
	 * @see javax.servlet.jsp.tagext.Tag#doStartTag()
	 */
	public int doStartTag() throws JspException
	{
		//SELECTタグのインスタンスを取得する
		Tag tag = this.getParent();
		while (!(tag instanceof SelectTag))
		{
			if (tag == null)
			{
				throw new JspException("Parent Tag is not found.");
			}
			tag = tag.getParent();
		}
		SelectTag parent = (SelectTag)tag;

		if (!this.getAttributeMap().containsKey("selected"))
		{
			HttpActionRequest req = new HttpActionRequestImpl((HttpServletRequest)pageContext.getRequest());
			ConversionMap param = ConversionMap.valueOf(req.getParameterMap());
			if (!param.isNull(parent.getName()))
			{
				if (param.isArray(parent.getName()))
				{
					String values[] = (String[])param.getObject(parent.getName());
					String val = this.getValue();
					for (int i = 0; i < values.length; i++)
					{
						if (val.equals(values[i]))
						{
							this.setSelected(true);
							break;
						}
					}
				}
				else
				{
					if (this.getValue().equals(param.getString(parent.getName())))
					{
						this.setSelected(true);
					}
				}
			}
		}

		//OPTIONタグを作成する
		StringBuffer buf = new StringBuffer();
		buf.append("<option");

		String keys[] = new String[this.getAttributeMap().size()];
		keys = (String[])this.getAttributeMap().keySet().toArray(keys);
		for (int i = 0; i < keys.length; i++)
		{
			if (keys[i].equals("disabled") ||
					keys[i].equals("selected"))
			{
				if (this.getAttributeMap().getBoolean(keys[i]))
				{
					buf.append(" ").append(keys[i]);
				}
			}
			else if (keys[i].equals("value"))
			{
				buf.append(" ").append(keys[i]).append("=\"").append(this.getAttributeMap().getString(keys[i])).append("\"");
			}
			else
			{
				buf.append(" ").append(keys[i]).append("=\"").append(this.getAttributeMap().getString(keys[i])).append("\"");
			}
		}
		buf.append(">");

		try
		{
			JspWriter out = pageContext.getOut();
			out.print(buf.toString());
		}
		catch (IOException e)
		{
			throw new JspException(e.getMessage());
		}

		return super.doStartTag();
	}

}
