/*
 * Created on 2003/05/10
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package org.j69.eewiki.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.j69.eewiki.wiki.WikiConstants;

/**
 * @author sally
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class CacheConfig {

	private static File file_;
	private static CacheConfig cacheconfig_ = null;
	private long lastModified_;
	private final static Properties cache_ = new Properties(); 
	private static final String NULL_STRING = "";
		
	/**
	 * コンストラクタ 
	 */
	public CacheConfig(File file) {
		file_ = file;
	}

	public synchronized static CacheConfig getInstance() {
		return createInstance(file_);
	}

	public synchronized static CacheConfig createInstance(File file) {
		file_ = file;
		if (cacheconfig_ != null) {
			// 更新があったかどうかチェック
			// 更新されていたら再ロード
//			if(cacheconfig_.isUpdate()) {
//				cacheconfig_.load();
//			}
			return cacheconfig_;
		}
		// 新規ロード
		cacheconfig_ = new CacheConfig(file);
		cacheconfig_.load();
		return cacheconfig_;
	}

	/**
	 * プロパティファイルからデータを読み込み
	 * 新規にCacheCinfigを生成
	 */
	private void load() {
		cache_.clear() ;
		try {
			cache_.load(new FileInputStream(file_));
			lastModified_ = file_.lastModified();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * ファイルが更新されているかどうかの判定
	 * @return boolean ファイルが更新されていればtrue, それ以外はfalse
	 */
	private synchronized boolean isUpdate() {
		return ( lastModified_ != file_.lastModified() ? true : false );
	}

	/**
	 * 文字を指定されたコードからデコード
	 */
	private static String decode(String str){
		try{
			return new String(str.getBytes("8859_1"), WikiConstants.DEFAULT_FILE_ENCODING);
		} catch(Throwable ex){
			return str;
		}
	}
	
	/**
	 * プロパティ値のセット
	 * @param key キー
	 * @param Value 値
	 */
	public synchronized void setConfig(String key, String Value) {
		cache_.setProperty(key, Value);
	}

	/**
	 * プロパティ値の取得
	 * @param key キー
	 * @return String 値
	 */
	public String getConfig(String key) {
		return this.getConfig (key, "");
	}

	/**
	 * プロパティ値の取得
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return String 値
	 */
	public String getConfig(String key, String defaultval) {
//		if(isUpdate()) {
//			load();
//		}
		return decode(cache_.getProperty(key, defaultval));
	}
	
	/**
	 * プロパティ値を配列で取得
	 * @param key キー
	 * @return String[] 配列の値
	 */
	public synchronized String[] getConfigArray(String key) {

		ArrayList list = new ArrayList();
		StringTokenizer st = new StringTokenizer(decode(cache_.getProperty(key)), ",");
		while (st.hasMoreTokens()) {
			list.add(st.nextToken());
		}
		return (String[])list.toArray(new String[0]);
	}

	/**
	 * プロパティ値をBooleanで取得
	 * @param key キー
	 * @return String[] 配列の値
	 */
	public boolean getConfigAsBoolean(String key) {
		return getConfigAsBoolean(key, false);
	}

	/**
	 * プロパティ値をBooleanで取得
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return String[] 配列の値
	 */
	public boolean getConfigAsBoolean(String key, boolean defaultValue) {
		String value = cache_.getProperty(key);
		boolean result = Boolean.valueOf(value).booleanValue();
		return result ? result : defaultValue;
	}
	
	/**
	 * プロパティ値を数値で取得
	 * @param key キー
	 * @return String[] 配列の値
	 */
	public int getConfigAsInt(String key) {
		return getConfigAsInt(key,0);
	}
	
	/**
	 * プロパティ値を数値で取得
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return String[] 配列の値
	 */
	public int getConfigAsInt(String key, int defaultValue) throws NumberFormatException{
		String value = cache_.getProperty(key);
		return value.equals(NULL_STRING)? defaultValue : Integer.parseInt(value);
	}

	/**
	 * キー一覧の取得
	 * @return String[] 配列の値
	 */
	public Set getKeySet() {
		return cache_.keySet();
	}

}
