package pbl2011.model;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import pbl2011.common.CommonConst;

public class PackageManager implements CommonConst{

	/**
	 * パッケージを保持するマップ
	 */
	private static Map<Integer, String> packageMap;
	
	/**
	 * パッケージマネージャーのStaticイニシャライザ
	 */
	static {
		packageMap = new HashMap<Integer, String>();
		init();
	}
	
	// 現在使用しているパッケージIDの最大値
	private static int maxPackageId = 0;

	/**
	 * <p>
	 * パッケージID採番
	 */
	private static int getNextPackageId() {
		if (maxPackageId < 1) {
			calcMaxPackageId();
		}
		return ++maxPackageId;
	}


	private static void calcMaxPackageId() {
		for (Integer n : packageMap.keySet()) {
			// システムで利用するパッケージは除く
			if (isUserDefinitionPackage(n) && maxPackageId < n.intValue()) {
				maxPackageId = n.intValue();
			}
		}
	}

	/**
	 * パッケージマップを初期化する
	 * システムで利用するパッケージをロードする
	 */
	private static void init() {
		packageMap.clear();
		packageMap.put(PACKAGE_DEFAULT_ID, PACKAGE_DEFAULT);
		packageMap.put(PACKAGE_JAVA_LANG_ID, PACKAGE_JAVA_LANG);
	}
	
	/**
	 * パッケージマネージャが保持するパッケージ情報をクリアする
	 * システムで利用するパッケージは消去しない
	 */
	public static void clear() {
		init();
	}
	/**
	 * パッケージをパッケージマネージャーに追加する
	 * @param packageName パッケージ名
	 * @return 追加したパッケージID
	 */
	public static Integer add(String packageName) {
		if (packageMap.containsValue(packageName)) {
			return getPackageId(packageName);
		} else {
			Integer nextPackageId = getNextPackageId();
			packageMap.put(nextPackageId, packageName);
			return nextPackageId;
		}
	}

	/**
	 * パッケージをパッケージマネージャーに追加する
	 * 現状読み込みから利用することしか想定していないため、存在チェック等のチェックはしない
	 * @param newPackageMap　パッケージ情報Map
	 */
	public static void add(Map<Integer, String> newPackageMap) {
		packageMap.putAll(newPackageMap);
	}

	/**
	 * パッケージ名からパッケージIDを取得する
	 * @param packageName パッケージ名
	 * @return パッケージID(存在しない場合はnull)
	 */
	public static Integer getPackageId(String packageName) {
		for(Entry<Integer, String> packageInfo: packageMap.entrySet()) {
			if (packageInfo.getValue().equals(packageName)) {
				return packageInfo.getKey();
			}
		}
		return null;
	}
	
	/**
	 * 	パッケージIDからパッケージ名を取得する
	 * @param packageId
	 * @return
	 */
	public static String getPackageName(Integer packageId) {
		return packageMap.get(packageId);
	}

	/**
	 * 登録されたパッケージの内容をファイル出力形式に変換する
	 * @return
	 */
	public static String write() {
		StringBuffer buffer = new StringBuffer();
		for (Integer packageId : packageMap.keySet()) {
			if (isUserDefinitionPackage(packageId)) {
				buffer.append(PackageType.PACKAGE.alias());
				buffer.append(DELIMITER);
				buffer.append(packageId);
				buffer.append(DELIMITER);
				buffer.append(packageMap.get(packageId));
				buffer.append(System.getProperty("line.separator"));
			}
		}
		return buffer.toString();
	}
	
	/**
	 * ユーザが定義したパッケージかどうかを判断する
	 * @param packageId 
	 * @return ユーザが定義したパッケージ:true、システムが定義したパッケージ：false
	 */
	public static boolean isUserDefinitionPackage(int packageId) {
		if ( packageId < PACKAGE_DEFAULT_ID ) {
			return true;
		} 
		return false;
	}
	
	/**
	 * インポートが必要なパッケージなのかを判定する
	 * @param packageId パッケージID
	 * @return インポートが必要：true,不要：false
	 */
	public static boolean isNeedImport(int packageId) {
		if (PACKAGE_DEFAULT_ID == packageId || PACKAGE_JAVA_LANG_ID == packageId) {
			return false;
		} 
		return true;
	}
	
}
