/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	LO設定情報管理クラス
//
//		変更履歴
//			2005.02.03  新規作成  Katsuhiko.Sakurai(UNITEC)
//
//	機能
//
//	このクラスはLO設定情報管理クラスです。
//
////////////////////////////////////////////////////////////////
package jp.co.ntt.lms.lo.progress.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jp.co.ntt.lms.xmo.util.DebugLog;

/**
 * LO設定情報管理クラスです。
 * 
 * @author Katsuhiko Sakurai (UNITEC)
 * @version 1.0
 */
public class LOConfiguration {
	
	private String loID = null;
	private String completeRate = null;
	private String notCompleteRate = null;
	private String notStartRate = null;
	private Map unitWeight = null;
	private List statusList = null;
	private String startDate = null;
	private String timeSpan = null;
	
	/**
	 * コンストラクタです。
	 * 
	 */
	public LOConfiguration() {
		this.statusList = new ArrayList();
		this.unitWeight = new HashMap();
	}
	
	/**
	 * 完了ステータスの進捗率を設定します。
	 * 
	 * @param completeRate 完了ステータスの進捗率
	 */
	public void setCompleteRate(String completeRate) {
		this.completeRate = completeRate;
	}

	/**
	 * LoIDを設定します。
	 * 
	 * @param loID LoID
	 */
	public void setLoID(String loID) {
		this.loID = loID;
	}

	/**
	 * 未完了ステータスの進捗率を設定します。
	 * 
	 * @param notCompleteRate 未完了ステータスの進捗率 
	 */
	public void setNotCompleteRate(String notCompleteRate) {
		this.notCompleteRate = notCompleteRate;
	}
	
	/**
	 * 未着手ステータスの進捗率を設定します。
	 * 
	 * @param notStartRate 未着手ステータスの進捗率 
	 */
	public void setNotStartRate(String notStartRate) {
		this.notStartRate = notStartRate;
	}
	
	/**
	 * ユニットの重みを設定します。
	 * 
	 * @param unitWeight ユニットの重み 
	 */
	public void setUnitWeight(HashMap unitWeight) {
		this.unitWeight = unitWeight;
	}
	
	/**
	 * LoIDを取得します。
	 * 
	 * @return String LOID 
	 */
	public String getLoID() {
		return loID;
	}

	/**
	 * 完了ステータスの進捗率を取得します。
	 * 
	 * @return String 完了ステータスの進捗率
	 */
	public String getCompleteRate() {
		return ( this.completeRate == null ? "" : this.completeRate );
	}
	
	/**
	 * 未完了ステータスの進捗率を取得します。
	 * 
	 * @return String 未完了ステータスの進捗率
	 */
	public String getNotCompleteRate() {
		return ( this.notCompleteRate == null ? "" : this.notCompleteRate );
	}
	
	/**
	 * 未着手ステータスの進捗率を取得します。
	 * 
	 * @return String 未着手ステータスの進捗率
	 */
	public String getNotStartRate() {
		return ( this.notStartRate == null ? "" : this.notStartRate );
	}
	
	/**
	 * 学習開始日を取得します。
	 * 
	 * @return Date 学習開始日
	 */
	public Date getStartDate() {
		
		if (this.startDate == null 
				|| this.startDate.length() == 0) return null;
		
		return this.convertToDate(this.startDate);
	}
	
	/**
	 * 学習開始日を設定します。
	 * 
	 * @param startDate 学習開始日
	 */
	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}
	
	/**
	 * 学習時間を取得します。
	 * 
	 * @return TimeSpan 学習時間
	 */
	public TimeSpan getTimeSpan() {
		
		if (this.timeSpan == null 
				|| this.timeSpan.length() ==0) return null;
		
		try {
			return TimeSpan.parseTimeSpan(this.timeSpan);
		} catch (Exception ex) {
			DebugLog.write(this.getClass(),"外部設定ファイル学習期間変換失敗:" + ex.getMessage(), DebugLog.MID);
			return null;
		}
	}
	
	/**
	 * 学習時間を設定します。
	 * 
	 * @param timeSpan 学習時間
	 */
	public void setTimeSpan(String timeSpan) {
		this.timeSpan = timeSpan;
	}
	
	/**
	 * 指定された進捗率が該当する進捗状況名を取得します。 
	 * 
	 * @return String 進捗状況名
	 */
	public String getProgressStatusName(long progressRate) {
		
		Iterator ite = this.statusList.iterator();
		while(ite.hasNext()) {
			ProgressStatus status = (ProgressStatus)ite.next();
			if (status.contains(progressRate) ) return status.name;
		}
		return "";
	}

	/**
	 * 指定されたユニットIDのユニットの重みを取得します。 
	 * 
	 * @return String ユニットの重み
	 */
	public String getUnitWeight(String unitID) {
		
		if (this.unitWeight.containsKey(unitID)==false) return ""; 
		
		return this.unitWeight.get(unitID).toString();
	}
	
	/**
	 * ユニットの重みを設定します。
	 * 
	 * @param unitID ユニットID
	 * @param weight 重み
	 */
	public void setUnitWeight(String unitID, String weight) {
		
		String rightWeight = weight;
		
		try {
			if( Double.parseDouble(weight) > 1 ) rightWeight = "";
		} catch(NumberFormatException ex) {
			rightWeight = "";
		}

		this.unitWeight.put(unitID, rightWeight);
	}
	
	/**
	 * 進捗状況を設定します。
	 * 
	 * @param name 進捗状況名
	 * @param minValue 該当する進捗率の最小値
	 * @param maxValue 該当する進捗率の最大値
	 */
	public void setProgressStatus( String name, String minValue, String maxValue ) {
		
		this.statusList.add(new ProgressStatus(name, minValue, maxValue) );
	}
	
	/**
	 * 指定された文字列に指定された文字列でパディングを行います。
	 * 
	 * @param target 対象となる文字列
	 * @param digit パディング後の文字列の長さ
	 * @param padString パディングする文字列
	 * @return String　パディングされた文字列
	 */
	private String leftPad(String target, int digit, String padString){
		
		if (target.length() >= digit) return target;
		
		String paddingString = target;
		
		for (int i=0; i<(digit-target.length()); i++ ) {
			paddingString = padString + paddingString;
		}
		
		return paddingString;
	}

	/**
	 * 指定された日付文字列を日付に変換します。
	 * 
	 * @param dateTimeString ISO8601形式の日付文字列
	 * @return Date 変換された日付
	 */
	private Date convertToDate(String dateTimeString) {

		final int BASIC_DATE_ONLY_LENGTH = 8;
		final int EXTEND_DATE_ONLY_LENGTH = 10;
		final int BASIC_DATE_TIME_LENGTH = 15;
		final int EXTEND_DATE_TIME_LENGTH = 19;
		
		final String BASIC_DATE_ONLY_FORMAT = "yyyyMMdd";
		final String EXTEND_DATE_ONLY_FORMAT = "yyyy-MM-dd";
		final String BASIC_DATE_TIME_FORMAT = "yyyyMMdd'T'hhmmss";
		final String EXTEND_DATE_TIME_FORMAT = "yyyy-MM-dd'T'hh:mm:ss";
		
		SimpleDateFormat sdf = null;
		
		try {
			// 日付形式ごとにフォーマット変換
			switch ( dateTimeString.length() ) {
			
			// "yyyyMMdd" 形式
			case BASIC_DATE_ONLY_LENGTH :
				sdf = new SimpleDateFormat(BASIC_DATE_ONLY_FORMAT);
				return sdf.parse(dateTimeString);
				
			// "yyyy-MM-dd" 形式
			case EXTEND_DATE_ONLY_LENGTH :
				sdf = new SimpleDateFormat(EXTEND_DATE_ONLY_FORMAT);
				return sdf.parse(dateTimeString);
				
			// "yyyyMMddThhmmss" 形式
			case BASIC_DATE_TIME_LENGTH :
				sdf = new SimpleDateFormat(BASIC_DATE_TIME_FORMAT);
				return sdf.parse(dateTimeString);
				
			// "yyyy-MM-ddThh:mm:ss" 形式
			case EXTEND_DATE_TIME_LENGTH :
				sdf = new SimpleDateFormat(EXTEND_DATE_TIME_FORMAT);
				return sdf.parse(dateTimeString);
				
			default :
				return null;
			}
		} catch (ParseException pex) {
			DebugLog.write(this.getClass(),"外部設定ファイル学習開始日変換失敗", DebugLog.ROW);
			return null;
		}
	}
	
	/**
	 * 進捗状況クラスです。
	 * 
	 * @author Katsuhiko Sakurai (UNITEC)
	 * @version 1.0
	 */
	public class ProgressStatus {
		
		private String name = null;
		private String min = null;
		private String max = null;
		
		/**
		 * コンストラクタです。
		 * 
		 * @param name 進捗状況名
		 * @param min 対象となる進捗率の最小値
		 * @param max 対象となる進捗率の最大値
		 */
		public ProgressStatus( String name, String min, String max ) {
			this.name = ( name==null ? "" : name );
			this.max = ( max==null ? "" : max );
			this.min = ( min==null ? "" : min );
		}
	
		/**
		 * 対象となる進捗率の最大値を取得します。
		 * 
		 * @return String 対象となる進捗率の最大値
		 */
		public String getMax() {
			return this.max;
		}

		/**
		 * 対象となる進捗率の最小値を取得します。
		 * 
		 * @return String 対象となる進捗率の最小値
		 */
		public String getMin() {
			return this.min;
		}

		/**
		 * 進捗状況名称を取得します。
		 * 
		 * @return String 進捗状況名称
		 */
		public String getName() {
			return this.name;
		}
		
		/**
		 * 指定された進捗率が進捗状況の対象となっているかどうかを判別します。
		 * 
		 * @param progressRate 進捗率
		 * @return boolean 対象の進捗率かどうか True:対象範囲に含まれる
		 */
		public boolean contains( long progressRate ) {
			
			try {
				if ( this.min.length()==0 && this.max.length() == 0 ) {
					return false;
	
				} else if (this.min.length() == 0 ){
					return ( progressRate <=Integer.parseInt(this.max) );
	
				} else if (this.max.length() == 0 ){
					return ( Integer.parseInt(this.min) <= progressRate );
				
				} else {
					return ( Integer.parseInt(this.min) <= progressRate && progressRate <=Integer.parseInt(this.max) );
				}
			}catch (NumberFormatException nfe) {
				DebugLog.write(this.getClass(), "進捗状況範囲数値変換エラー", DebugLog.MID);
				return false;
			}
		}
	}
}
