/**
 * 独自に作成したVelocityToolを置くパッケージ.
 */
package jp.agentec.sinaburocast.common.util.velocity;

import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.log4j.Logger;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.tools.generic.ValueParser;

import jp.agentec.sinaburocast.common.util.PropertyUtil;

/**
 * SinaburoCast.properties用VelocityTools.
 *
 * applicationスコープに置き、起動時に一度だけ設定ファイルを読んでapplicationコンテキストへ反映させるツール
 *
 * @author arima
 *
 */
public class SinaburocastPropertiesTool {
	private static final Logger __LOG = Logger.getLogger(SinaburocastPropertiesTool.class);

	public interface PropertyKey {
		String POPULATION_PREFIX = "view.";
		String CSSPATH = "cssPath";
		String JSPATH = "jsPath";
		String IMAGESPATH = "imagesPath";
		String LOGOPATH = "logoPath";
		String SWFPATH = "swfPath";
	}

	protected ServletContext _application;

	protected String _propertiesFileName;
	protected String _propertiesDfFileName;
	protected Properties _props;
	protected Properties _propsDf;

	protected String _defaultCssSubDirName;
	protected String _defaultJsSubDirName;
	protected String _defaultImagesSubDirName;
	protected String _defaultLogoSubDirName;
	protected String _defaultSwfSubDirName;

	/**
	 * Initializes this tool.
	 *
	 * @param obj the current ViewContext
	 * @throws IllegalArgumentException if the param is not a ViewContext
	 */
	public void init(Object obj) {
		if (! (obj instanceof ServletContext)) {
			throw new IllegalArgumentException("Tool can only be initialized with a ServletContext");
		}

		_application = (ServletContext) obj;

		populateProperties();
		populateDefaultValues();
	}

    /**
     * Looks for configuration values in the given params.
     * @since VelocityTools 1.4
     */
    public void configure(Map<?, ?> params)
    {
    	ValueParser values = new ValueParser(params);
    	_propertiesFileName = values.getString("filename", "sinaburocast");
    	_propertiesDfFileName = values.getString("filename", "sinaburocast_df");
    	_defaultCssSubDirName = values.getString("defaultCssSubDir", "css");
    	_defaultJsSubDirName = values.getString("defaultJsSubDir", "js");
    	_defaultImagesSubDirName = values.getString("defaultImagesSubDir", "images");
    	_defaultLogoSubDirName = values.getString("defaultLogoSubDir", "logo");
    	_defaultSwfSubDirName = values.getString("defaultSwfSubDir", "swf");
    }

	/**
	 * 設定ファイルを展開・設定する
	 * @param context
	 */
	private void populateProperties() {
		_props = PropertyUtil.getProperties(_propertiesFileName, false);
		_propsDf = PropertyUtil.getProperties(_propertiesDfFileName, false);
		if (_props == null || _propsDf == null) {
			throw new ResourceNotFoundException("Can't find configuration (" + _propertiesFileName + ")" );
		}

		final int prefixLength = PropertyKey.POPULATION_PREFIX.length();
		for (String key : _props.stringPropertyNames()) {
			if (key.startsWith(PropertyKey.POPULATION_PREFIX)) {
				_application.setAttribute(key.substring(prefixLength), _props.getProperty(key));
			}
		}
		for (String key : _propsDf.stringPropertyNames()) {
			if (key.startsWith(PropertyKey.POPULATION_PREFIX)) {
				_application.setAttribute(key.substring(prefixLength), _propsDf.getProperty(key));
			}
		}

	}

	/**
	 * いくつかの要素について、設定ファイルになかった場合のデフォルト値を設定する
	 */
	private void populateDefaultValues() {
		String contextPath = _application.getContextPath(); 
		if (contextPath == null)	contextPath = "";

		if (_application.getAttribute(PropertyKey.CSSPATH) == null) {
			_application.setAttribute(PropertyKey.CSSPATH, contextPath + '/' + _defaultCssSubDirName);
		}
		if (_application.getAttribute(PropertyKey.JSPATH) == null) {
			_application.setAttribute(PropertyKey.JSPATH, contextPath + '/' + _defaultJsSubDirName);
		}
		if (_application.getAttribute(PropertyKey.IMAGESPATH) == null) {
			_application.setAttribute(PropertyKey.IMAGESPATH, contextPath + '/' + _defaultImagesSubDirName);
		}
		if (_application.getAttribute(PropertyKey.LOGOPATH) == null) {
			_application.setAttribute(PropertyKey.LOGOPATH, contextPath + '/' + _defaultLogoSubDirName);
		}
		if (_application.getAttribute(PropertyKey.SWFPATH) == null) {
			_application.setAttribute(PropertyKey.SWFPATH, contextPath + '/' + _defaultSwfSubDirName);
		}
	}

	/**
	 * プロパティを返す.
	 *
	 * 名前が POPULATION_PREFIX で始まらないプロパティはこちらから取得できる
	 *
	 * @param key
	 * @return
	 */
	public String get(String key) {
		return PropertyUtil.getProperty(key);
	}
}