/*
 * 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.jsp.JspException;
import javax.servlet.jsp.JspWriter;

import jp.morpho.util.ConversionMap;
import jp.morpho.webapp.servlet.jsp.tagext.TagManager;
import jp.morpho.webapp.servlet.jsp.tagext.TagTemplate;

/**
 * <P>
 * SELECT 要素はメニューを作成します。
 * メニュー中の各選択肢は OPTION 要素によって提示されます。
 * 1 つの SELECT 要素には最低 1 つの OPTION 要素が含まれている必要があります。
 * </P>
 * <P>
 * SELECT の HTML 4 定義は次のとおりです。
 * <PRE>
 * &lt;!ELEMENT SELECT - - (OPTGROUP|OPTION)+ -- option selector --&gt;
 * &lt;!ATTLIST SELECT
 *   %attrs;                              -- %coreattrs, %i18n, %events --
 *   name        CDATA          #IMPLIED  -- field name --
 *   size        NUMBER         #IMPLIED  -- rows visible --
 *   multiple    (multiple)     #IMPLIED  -- default is single selection --
 *   disabled    (disabled)     #IMPLIED  -- unavailable in this context --
 *   tabindex    NUMBER         #IMPLIED  -- position in tabbing order --
 *   onfocus     %Script;       #IMPLIED  -- the element got the focus --
 *   onblur      %Script;       #IMPLIED  -- the element lost the focus --
 *   onchange    %Script;       #IMPLIED  -- the element value was changed --
 *   &gt;
 * </PRE>
 * </P>
 * @author Kumiko Hiroi
 */
public class SelectTag
	extends ControlTagSupport
	implements TagTemplate
{
	/**
	 * <P>
	 * SelectTag を作成します。
	 * </P>
	 */
	public SelectTag()
	{
		super();
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	/**
	 * <P>
	 * このタグのタイプを返します。
	 * </P>
	 * @return このタグのタイプ
	 * @see jp.morpho.webapp.servlet.jsp.tagext.TagTemplate#getTagType()
	 */
	public String getTagType()
	{
		return "jp.morpho.webapp.servlet.jsp.tagext.html.SelectTag";
	}

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

		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タグを作成します
		StringBuffer buf = new StringBuffer();
		buf.append("<select");

		//TagTemplateを取得します
		TagManager tm = this.getTagManager();
		TagTemplate ttmp = null;
		if (this.getAttributeMap().containsKey("template"))
		{
			ttmp = tm.getTagTemplate(this.getTagType(), this.getTemplate());
		}
		else
		{
			ttmp = tm.getTagTemplate(this.getTagType(), this.getName());
		}

		ConversionMap attr = new ConversionMap();
		if (ttmp != null)
		{
			attr.putAll(ttmp.getAttributeMap());
		}
		attr.putAll(this.getAttributeMap());
		
		String keys[] = new String[attr.size()];
		keys = (String[])attr.keySet().toArray(keys);
		for (int i = 0; i < keys.length; i++)
		{
			if (keys[i].equals("template"))
			{
				//何もしない
			}
			else if (keys[i].equals("disabled") ||
					keys[i].equals("readonly") ||
					keys[i].equals("checked") ||
					keys[i].equals("ismap"))
			{
				if (attr.getBoolean(keys[i]))
				{
					buf.append(" ").append(keys[i]);
				}
			}
			else if (keys[i].equals("value"))
			{
				buf.append(" ").append(keys[i]).append("=\"").append(attr.getString(keys[i])).append("\"");
			}
			else
			{
				buf.append(" ").append(keys[i]).append("=\"").append(attr.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();
	}

}
