package online.view.tag;

import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import org.apache.logging.log4j.LogManager;

import online.view.ViewUtil;
import online.view.model.ViewMap;
import core.config.Factory;

/**
 * タグライブラリ用ユーティリティ
 *
 * @author Tadashi Nakayama
 * @version 1.0.0
 */
public abstract class BaseTag extends TagSupport {
	/** serivalVersionUID */
	private static final long serialVersionUID = -7792897218713999276L;

	/**
	 * 値分割処理
	 *
	 * @param value 入力値
	 * @return 分割後配列
	 */
	protected final String[] splitValue(final String value) {
		return value != null ? value.split(",", -1) : new String[0];
	}

	/**
	 * リクエスト取得
	 * @return リクエスト
	 */
	protected final HttpServletRequest getRequest() {
		return HttpServletRequest.class.cast(this.pageContext.getRequest());
	}

	/**
	 * レスポンス取得
	 * @return レスポンス
	 */
	protected final HttpServletResponse getResponse() {
		return HttpServletResponse.class.cast(this.pageContext.getResponse());
	}

	/**
	 * 出力処理
	 *
	 * @param var 変数
	 * @param obj 出力オブジェクト
	 * @return 出力結果
	 */
	protected final boolean output(final String var, final Object obj) {
		return output(var, obj, false);
	}

	/**
	 * 出力処理
	 *
	 * @param var 変数
	 * @param obj 出力オブジェクト
	 * @param bool 改行フラグ
	 * @return 出力結果
	 */
	protected final boolean output(final String var, final Object obj, final boolean bool) {
		try {
			if (obj != null) {
				if (var == null) {
					if (bool) {
						// 出力
						this.pageContext.getOut().println(obj);
					} else {
						// 出力
						this.pageContext.getOut().print(obj);
					}
				} else {
					// 変数設定
					this.pageContext.setAttribute(var, obj);
				}
			}
			return true;
		} catch (final IOException ex) {
			LogManager.getLogger().info(ex.getMessage());
			return false;
		}
	}

	/**
	 * 汎用マップ取得
	 *
	 * @return 汎用マップ
	 */
	protected final ViewMap getViewMap() {
		ViewMap ret = ViewMap.class.cast(this.pageContext.getAttribute(
						ViewUtil.ATTR_MAP, PageContext.REQUEST_SCOPE));
		if (ret == null) {
			ret = Factory.create(ViewMap.class);
			ret.setMap(new HashMap<String, Serializable>());
			ret.setResponse(getResponse());
		}
		return ret;
	}

	/**
	 * オブジェクト取得
	 *
	 * @param vm ViewMap
	 * @param key キー
	 * @return オブジェクト
	 */
	protected final Object getObject(final Map<String, Serializable> vm, final String key) {
		Map<String, Serializable> map = vm;
		String[] keys = key.split("\\.");
		for (int i = 0; i < keys.length - 1; i++) {
			Object obj = map.get(keys[i]);
			if (!Map.class.isInstance(obj)) {
				return null;
			}
			map = Map.class.cast(obj);
		}

		return map.get(keys[keys.length - 1]);
	}

	/**
	 * 配列取得名化
	 * @param name 項目名
	 * @return 配列取得名
	 */
	protected final String toArrayName(final String name) {
		StringBuilder ret = new StringBuilder();
		int loc = name.lastIndexOf('.');
		if (0 <= loc) {
			ret.append(name.substring(0, loc + ".".length()));
		}
		ret.append(ViewMap.ATTR_ARRAY).append(".");
		ret.append(name.substring(loc + ".".length()));
		return ret.toString();
	}
}
