/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JPCCheckUtil
*	ソースファイル名：JPCCheckUtil.java
*	作成者			：富士通
*	日付			：2011年06月16日
*＜機能概要＞
*	チェックに関する共通機能を提供する。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/06/16	富士通		新規作成
*
**********************************************************************/
package eo.common.util;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * チェックを行うクラスです。<p>
 * <br>
 * @author 富士通
 */
public class JPCCheckUtil extends JPCCommonUtil 
{
	/**
	 * 指定した文字列が上限値と下限値の有効範囲内か判断します。（文字列比較）
	 * <br>
	 * @param arg0 上限値
	 * @param arg1 下限値
	 * @param arg2  指定文字列
	 * @param arg3 指定文字列が数値として扱われるデータか判断する
	 * （1:数値、2:文字列（可変）、3:文字列（年月日）、4:文字列（時分秒））
	 * @return boolean true :有効範囲内
	 * 					false:有効範囲外
	 */
	public static boolean rangeCheck(String arg0, String arg1, String arg2, String arg3) 
	{
		String sMax = arg0;
		String sMin = arg1;
		String sTarget = arg2;
		if(isNull(sMax)) 
		{
			throw new IllegalArgumentException("引数が不正です。");
		}

		if(isNull(sMin)) 
		{
			throw new IllegalArgumentException("引数が不正です。");
		}

		if(isNull(sTarget)) 
		{
			throw new IllegalArgumentException("引数が不正です。");
		}

		if(isNull(arg3)) 
		{
			return false;
		}

		sTarget = sTarget.trim();

		if ("".equals(sTarget)) 
		{
			return false;
		}

		// フラグから桁埋めの形式を判定する
		// 数値の場合
		if ("1".equals(arg3)) 
		{
			// 全体の桁数を合わせる（空白左詰め）
			if (sMax.length() >= sMin.length()) 
			{
				while (sMax.length() != sMin.length()) 
				{
					sMin = " ".concat(sMin);
				}
			}
			else 
			{
				throw new IllegalArgumentException("上限値と下限値が不正です。");
			}
			if (sMax.length() >= sTarget.length()) 
			{
				while (sMax.length() != sTarget.length()) 
				{
					sTarget = " ".concat(sTarget);
				}
			}
			else 
			{
				return false;
			}
		}
		// 文字列（可変）の場合
		else if ("2".equals(arg3)) 
		{
			// 全体の桁数を合わせる（空白右詰め）
			if (sMax.length() >= sMin.length()) 
			{
				while (sMax.length() != sMin.length()) 
				{
					sMin = sMin.concat(" ");
				}
			}
			else 
			{
				while (sMax.length() != sMin.length()) 
				{
					sMax = sMax.concat(" ");
				}
			}
			if (sMax.length() >= sTarget.length()) 
			{
				while (sMax.length() != sTarget.length()) 
				{
					sTarget = sTarget.concat(" ");
				}
			}
			else 
			{
				// arg0とarg1の桁合わせを同じwhileで行っても構わないが、一応分別。
				while (sMax.length() != sTarget.length()) 
				{
					sMax = sMax.concat(" ");
				}

				while (sMin.length() != sTarget.length()) 
				{
					sMin = sMin.concat(" ");
				}
			}
		}
		// それ以外の場合
		else 
		{
			// 指定文字列の桁数を合わせる（空白左詰め）
			if (sMax.length() != sTarget.length() 
			|| sMin.length() != sTarget.length()) 
			{
				throw new IllegalArgumentException("年月日または時分秒のデータが不正です。");
			}
		}

		// 上限値下限値不正チェック
		if (0 > sMax.compareTo(sMin)) 
		{
			throw new IllegalArgumentException("上限値と下限値が不正です。");
		}

		// 有効範囲チェック
		if (0 > sTarget.compareTo(sMin)) 
		{
			return false;
		}
		if (0 < sTarget.compareTo(sMax)) 
		{
			return false;
		}

		return true;
	}

	/**
	 * 指定された日付の妥当性チェックを行います。
	 * <br>
     * @param arg0 yyyyMMddもしくはyyyyMM形式の日付
     * @param length チェック対象の日付の桁数
     * @return boolean チェック結果
     */
	public static boolean checkDate(String arg0, int arg1) 
	{
		// 引数チェック
		if (isNull(arg0)) 
		{
			return false;
		}

		try 
		{
			int yyyy = Integer.parseInt(arg0.substring(0, 4));

			int mm = Integer.parseInt(arg0.substring(4, 6));

			int dd = 1;

			if (arg1 == 8) 
			{
				dd = Integer.parseInt(arg0.substring(6, 8));
			}

			// 月は 0 から始まる。（0:１月 となる。）
			Calendar cl = new GregorianCalendar(yyyy, mm - 1, dd);

			// カレンダークラスにより、日付が調整されてしまっている場合は、エラーである。
			if ((cl.get(Calendar.YEAR) != yyyy) 
					|| ((cl.get(Calendar.MONTH) + 1) != mm) 
					|| (cl.get(Calendar.DATE) != dd)) 
			{
				return false;
			}
			else 
			{
				return true;
			}
		}
		catch (NumberFormatException e) 
		{
			return false;
		}
		catch (IndexOutOfBoundsException e) 
		{
			return false;
		}
	}

	/**
	 * 指定された時間の妥当性チェックを行います。
	 * <br>
	 * @param time HHmmssSもしくはHHmmssSSS形式の時間
	 * @param length チェック対象の日付の桁数
	 * @return　boolean チェック結果
	 */
	public static boolean checkTime(String time, int length) 
	{
		// 引数チェック
		if(!isValidParameter(time, length)) 
		{
			return false;
		}

		if(!isValidParameter(time, 7) && !isValidParameter(time, 9)) 
		{
			return false;
		}

		try 
		{
			int HH = Integer.parseInt(time.substring(0, 2));

			int mm = Integer.parseInt(time.substring(2, 4));

			int ss = Integer.parseInt(time.substring(4, 6));
			int msec = 0;

			if (length == 7) 
			{
				msec = Integer.parseInt(time.substring(6, 7)) * 100;
			}
			else 
			{
				msec = Integer.parseInt(time.substring(6, 9));
			}
			Calendar cl = new GregorianCalendar();

			cl.set(Calendar.HOUR_OF_DAY, HH);

			cl.set(Calendar.MINUTE, mm);

			cl.set(Calendar.SECOND, ss);

			cl.set(Calendar.MILLISECOND, msec);

			// カレンダークラスにより、時間が調整されてしまっている場合は、エラーである。
			if ((cl.get(Calendar.HOUR_OF_DAY) != HH) 
					|| (cl.get(Calendar.MINUTE) != mm) 
					|| (cl.get(Calendar.SECOND) != ss) 
					|| (cl.get(Calendar.MILLISECOND) != msec)) 
			{
				return false;
			}
			else 
			{
				return true;
			}
		}
		catch (NumberFormatException e) 
		{
			return false;
		}
	}
}
