/*
 * 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 jp.morpho.util.ConversionMap;
import jp.morpho.webapp.servlet.http.HttpActionRequest;
import jp.morpho.webapp.servlet.http.impl.HttpActionRequestImpl;
import jp.morpho.webapp.servlet.jsp.tagext.TagManager;
import jp.morpho.webapp.servlet.jsp.tagext.TagTemplate;

/**
 * <P>
 * 複数行のテキスト入力コントロールを作成します。
 * </P>
 * <P>
 * TEXTAREA の HTML 4 定義は次のとおりです。
 * <PRE>
 * &lt;!ELEMENT TEXTAREA - - (#PCDATA)       -- multi-line text field --&gt;
 * &lt;!ATTLIST TEXTAREA
 *   %attrs;                              -- %coreattrs, %i18n, %events --
 *   name        CDATA          #IMPLIED
 *   rows        NUMBER         #REQUIRED
 *   cols        NUMBER         #REQUIRED
 *   disabled    (disabled)     #IMPLIED  -- unavailable in this context --
 *   readonly    (readonly)     #IMPLIED
 *   tabindex    NUMBER         #IMPLIED  -- position in tabbing order --
 *   accesskey   %Character;    #IMPLIED  -- accessibility key character --
 *   onfocus     %Script;       #IMPLIED  -- the element got the focus --
 *   onblur      %Script;       #IMPLIED  -- the element lost the focus --
 *   onselect    %Script;       #IMPLIED  -- some text was selected --
 *   onchange    %Script;       #IMPLIED  -- the element value was changed --
 *   &gt;
 * </PRE>
 * </P>
 * @author Kumiko Hiroi
 */
public class TextareaTag
	extends ControlTagSupport
	implements TagTemplate
{
	/**
	 * <P>
	 * TextareaTag を作成します。
	 * </P>
	 */
	public TextareaTag()
	{
		super();
	}

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

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

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

	/**
	 * <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>
	 * onselect 属性を返します。
	 * </P>
	 * @return onselect 属性
	 */
	public String getOnselect()
	{
		return getAttributeMap().getString("onselect");
	}

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

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

	/**
	 * <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>
	 * accesskey 属性を設定します。
	 * </P>
	 * @param accesskey accesskey 属性
	 */
	public void setAccesskey(String accesskey)
	{
		getAttributeMap().putString("accesskey", accesskey);
	}

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

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

	/**
	 * <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>
	 * onselect 属性を設定します。
	 * </P>
	 * @param onselect onselect 属性
	 */
	public void setOnselect(String onselect)
	{
		getAttributeMap().putString("onselect", onselect);
	}

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

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

	/**
	 * <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.TextareaTag";
	}

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

		//タグ本体がない場合
		if (!isBodyExists())
		{
			HttpActionRequest req = new HttpActionRequestImpl((HttpServletRequest)pageContext.getRequest());
			ConversionMap param = ConversionMap.valueOf(req.getParameterMap());
			if (param.containsKey(this.getName()))
			{
				HtmlEncoder encoder = this.getTagManager().getHtmlEncoder();
				buf.append(encoder.encode(param.getString(this.getName())));
			}
		}
		buf.append("</textarea>");

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

		//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"))
			{
				if (attr.getBoolean(keys[i]))
				{
					buf.append(" ").append(keys[i]);
				}
			}
			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();
	}

}
