/*
 * MosP - Mind Open Source Project    http://www.mosp.jp/
 * Copyright (C) MIND Co., Ltd.       http://www.e-mind.co.jp/
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package jp.mosp.common.utils;

import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.BaseDao;
import jp.mosp.common.common.BaseDto;
import jp.mosp.common.common.MospConst;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.part.BasePart;

/**
 * 各種メソッドに関するPartクラス
 * @author yoshida
 *	@version	0.0.3
 */
public class VariousUtil {
	
	/**
	 * 
	 */
	private VariousUtil() {
		// 他クラスによるインスタンス化を防止
	}
	
	/**
	 * 削除フラグリスト取得
	 * @return 削除フラグリスト
	 */
	public static String[][] getDeleteArray() {
		String[][] array = new String[2][2];
		array[0][0] = String.valueOf(MospConst.DELETE_FLAG_OFF);
		array[0][1] = MospConst.DELETE_FLAG_OFF_NAME;
		array[1][0] = String.valueOf(MospConst.DELETE_FLAG_ON);
		array[1][1] = MospConst.DELETE_FLAG_ON_NAME;
		return array;
	}
	
	/**
	 * 適用フラグリスト取得
	 * @return 削除フラグリスト
	 */
	public static String[][] getApplicableFlagArray() {
		String[][] array = new String[2][2];
		array[0][0] = String.valueOf(CommonConst.APPLICABLE_FLAG_OFF);
		array[0][1] = CommonConst.NAM_APPLICABLE_FLAG_OFF;
		array[1][0] = String.valueOf(CommonConst.APPLICABLE_FLAG_ON);
		array[1][1] = CommonConst.NAM_APPLICABLE_FLAG_ON;
		return array;
	}
	
	/**
	 * データ存在確認
	 * @param dto 確認対象DTO
	 * @return boolean	対象DTO存在有無
	 */
	public static boolean chkExistDto(BaseDto dto) {
		if (dto == null) {
			return false;
		}
		return true;
	}
	
	/**
	 * DTO存在確認
	 * @since	0.0.3
	 * @param dto 確認対象DTO
	 * @return	対象DTO存在有無
	 */
	public static boolean isNull(BaseDto dto) {
		if (dto == null) {
			return true;
		}
		return false;
	}
	
	/**
	 * DTO存在確認
	 * @since	0.0.3
	 * @param dto 確認対象DTO
	 * @return	対象DTO存在有無
	 */
	public static boolean isNotNull(BaseDto dto) {
		return !isNull(dto);
	}
	
	/**
	 * データ存在確認
	 * @param obj 確認対象Object
	 * @return boolean	対象Object存在有無
	 */
	public static boolean chkExistObject(Object obj) {
		if (obj == null) {
			return false;
		}
		return true;
	}
	
	/**
	 * データ存在確認
	 * @since	0.0.3
	 * @param obj 確認対象Object
	 * @return boolean	対象Object存在有無
	 */
	public static boolean isNull(Object obj) {
		if (obj == null) {
			return true;
		}
		return false;
	}
	
	/**
	 * データ存在確認
	 * @since	0.0.3
	 * @param obj 確認対象Object
	 * @return boolean	対象Object存在有無
	 */
	public static boolean isNotNull(Object obj) {
		return !isNull(obj);
	}
	
	/**
	 * Part存在確認
	 * @since	0.0.3
	 * @param part 確認対象Part
	 * @return boolean	対象Part存在有無
	 */
	public static boolean isNull(BasePart part) {
		return isNull((Object)part);
	}
	
	/**
	 * Part存在確認
	 * @since	0.0.3
	 * @param part 確認対象Part
	 * @return boolean	対象Part存在有無
	 */
	public static boolean isNotNull(BasePart part) {
		return !isNull(part);
	}
	
	/**
	 * DAO存在確認
	 * @since	0.0.3
	 * @param dao 確認対象DAO
	 * @return boolean	対象DAO存在有無
	 */
	public static boolean isNull(BaseDao dao) {
		return isNull((Object)dao);
	}
	
	/**
	 * DAO存在確認
	 * @since	0.0.3
	 * @param dao 確認対象DAO
	 * @return boolean	対象DAO存在有無
	 */
	public static boolean isNotNull(BaseDao dao) {
		return !isNull(dao);
	}
	
	/**
	 * 閲覧権限コード配列取得
	 * @return	閲覧権限コード配列
	 * <p>
	 * [0]…所属部署
	 * [1]…選択部署
	 * [2]…全部署
	 * </p>
	 */
	public static int[] getManageCode() {
		int[] aryCode = new int[3];
		aryCode[0] = Integer.parseInt(CommonConst.NUM_BELONGING_SECTION);
		aryCode[1] = Integer.parseInt(CommonConst.NUM_SELECT_SECTION);
		aryCode[2] = Integer.parseInt(CommonConst.NUM_ALL_SECTION);
		return aryCode;
	}
	
	/**
	 * キー値取得(複合キー)
	 * @param key		対象キー
	 * @param keyIndex キーインデックス
	 * @return キー値
	 */
	public static String getKeyValue(String key, int keyIndex) {
		String[] aryKey = key.split(CommonConst.KEY_SEPARATOR);
		return aryKey[keyIndex];
	}
	
	/**
	 * 曜日設定
	 * @param dayOfWeek 曜日
	 * @return 曜日名
	 */
	public static String getDayOfWeek(int dayOfWeek) {
		switch (dayOfWeek) {
			case Calendar.SUNDAY:
				return CommonConst.NAM_SUNDAY;
			case Calendar.MONDAY:
				return CommonConst.NAM_MONDAY;
			case Calendar.TUESDAY:
				return CommonConst.NAM_TUESDAY;
			case Calendar.WEDNESDAY:
				return CommonConst.NAM_WEDNESDAY;
			case Calendar.THURSDAY:
				return CommonConst.NAM_THURSDAY;
			case Calendar.FRIDAY:
				return CommonConst.NAM_FRIDAY;
			case Calendar.SATURDAY:
				return CommonConst.NAM_SATURDAY;
			default:
				return "";
		}
	}
	
	/**
	 * 出力範囲プルダウンリスト
	 * @return	String[][]	出力範囲配列
	 */
	public static String[][] getOutputScopeArray() {
		// 範囲プルダウンリスト作成
		String[][] aryScope = new String[3][2];
		aryScope[0][0] = CommonConst.CODE_SCOPE_PERSONAL;
		aryScope[0][1] = CommonConst.NAM_SCOPE_PERSONAL;
		aryScope[1][0] = CommonConst.CODE_SCOPE_SECTION;
		aryScope[1][1] = CommonConst.NAM_SCOPE_SECTION;
		aryScope[2][0] = CommonConst.CODE_SCOPE_ALL;
		aryScope[2][1] = CommonConst.NAM_SCOPE_ALL;
		return aryScope;
	}
	
	/**
	 * 承認ステータスコードリスト取得
	 * @return 承認ステータスコードリスト配列
	 * <p>
	 * [0]…未承認（申請中）
	 * [1]…一次承認
	 * [2]…一次差戻
	 * [3]…二次承認
	 * [4]…二次差戻
	 * [5]…下書き
	 * </p>
	 */
	public static String[] getApprovalStatusCodeArray() {
		// 配列の作成
		String[] aryStatus = new String[6];
		aryStatus[0] = CommonConst.NUM_ATTENDANCE_REQUEST;
		aryStatus[1] = CommonConst.NUM_ATTENDANCE_1ST_APPROVED;
		aryStatus[2] = CommonConst.NUM_ATTENDANCE_1ST_RETURNED;
		aryStatus[3] = CommonConst.NUM_ATTENDANCE_2ND_APPROVED;
		aryStatus[4] = CommonConst.NUM_ATTENDANCE_2ND_RETURNED;
		aryStatus[5] = CommonConst.CODE_DRAFT;
		return aryStatus;
	}
	
	/**
	 * 閲覧権限プルダウンリスト
	 * @return	String[][]	出力範囲配列
	 */
	public static String[][] getManageArray() {
		// 範囲プルダウンリスト作成
		String[][] aryScope = new String[3][2];
		aryScope[0][0] = String.valueOf(getManageCode()[0]);
		aryScope[0][1] = CommonConst.NAM_BELONGING_SECTION;
		aryScope[1][0] = String.valueOf(getManageCode()[1]);
		aryScope[1][1] = CommonConst.NAM_SELECT_SECTION;
		aryScope[2][0] = String.valueOf(getManageCode()[2]);
		aryScope[2][1] = CommonConst.NAM_ALL_SECTION;
		return aryScope;
	}
	
	/**
	 * DTO同一性チェック
	 * @param formerDto		元対象DTO
	 * @param currentDto	現対象DTO
	 * @return
	 * <p>
	 * 更新日時が同一の場合true、そうでない場合false
	 * </p>
	 */
	public static boolean chkIdentityDto(BaseDto formerDto, BaseDto currentDto) {
		if (chkExistDto(currentDto)) {
			if (formerDto.getUpdateDate().compareTo(currentDto.getUpdateDate()) == 0) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 役職手当区分プルダウンリスト（有無＋給与情報単価）
	 * @return 役職手当区分配列
	 */
	public static String[][] getPositionAllowanceType1() {
		String[][] array = { { CommonConst.CODE_ALLOWANCE_NONE, CommonConst.NAME_ALLOWANCE_NONE },
			{ CommonConst.CODE_ALLOWANCE_STATE_1, CommonConst.NAME_ALLOWANCE_SALARY } };
		return array.clone();
	}
	
	/**
	 * 役職手当区分プルダウンリスト（有無＋固定単価）
	 * @return 役職手当区分配列
	 */
	public static String[][] getPositionAllowanceType2() {
		String[][] array = { { CommonConst.CODE_ALLOWANCE_NONE, CommonConst.NAME_ALLOWANCE_NONE },
			{ CommonConst.CODE_ALLOWANCE_STATE_1, CommonConst.NAME_ALLOWANCE_FIXED } };
		return array.clone();
	}
	
	/**
	 * 役職手当区分プルダウンリスト（有無＋給与情報単価＋固定単価）
	 * @return 役職手当区分配列
	 */
	public static String[][] getPositionAllowanceType3() {
		String[][] array = { { CommonConst.CODE_ALLOWANCE_NONE, CommonConst.NAME_ALLOWANCE_NONE },
			{ CommonConst.CODE_ALLOWANCE_STATE_1, CommonConst.NAME_ALLOWANCE_SALARY },
			{ CommonConst.CODE_ALLOWANCE_STATE_2, CommonConst.NAME_ALLOWANCE_FIXED } };
		return array.clone();
	}
	
	/**
	 * 該当フラグ配列
	 * @return 該当フラグ配列
	 */
	public static String[][] getCorrespondFlagArray() {
		return StringUtil.getFlagArray(CommonConst.NAM_DEFAULT_FLAG_OFF, CommonConst.NAM_DEFAULT_FLAG_ON);
	}
	
	/**
	 * フィールド名称内のデータ分解取得
	 * <p>
	 * インデックス番号
	 * </p>
	 * <ol start="0">
	 * 		<li>ファイルID</li>
	 * 		<li>管理番号</li>
	 * 		<li>フィールドID</li>
	 * 		<li>フィールド名称</li>
	 * </ol>
	 * @param csvString 対象文字列
	 * @param i インデックス
	 * @return 対象インデックス文字列
	 */
	public static String getCsvSplitInfo(String csvString, int i) {
		//　管理番号取得
		if (StringUtil.isNotNull(csvString)) {
			String[] arl = csvString.split(CommonConst.STR_CSV_SEPARATOR);
			return arl[i];
		}
		return "";
	}
	
	/**
	 * 時間フォーマット
	 * @param hour 時間
	 * @return 時間(文字列)
	 */
	public static String getHourString(double hour) {
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setMinimumFractionDigits(2);
		return nf.format(hour);
	}
	
	/**
	 * 時間差取得(分)
	 * @param date1 終了日付
	 * @param date2 開始日付
	 * @return 時間差(date1 - date2)
	 */
	public static long getTimeRemainder(Date date1, Date date2) {
		final int thousand = 1000;
		long timeRemainder = date1.getTime() - date2.getTime();
		final int min = 60;
		long result = timeRemainder / (thousand * min);
		return result;
	}
	
	/**
	 * 対象年から対象年度を取得
	 * @param year		対象年
	 * @param month		対象月
	 * @param startmonth	年度開始月
	 * @return	対象年度
	 */
	public static int getTargetFiscalYear(int year, int month, int startmonth) {
		// 年度開始月より前月の場合対象年の前年を使用する。
		// 年度開始月より後の月の場合は対象年を使用する
		int fiscalyear = year;
		if (month < startmonth) {
			fiscalyear--;
		}
		return fiscalyear;
	}
	
	/**
	 * 対象年度から対象年を取得
	 * @param fiscalyear		対象年度
	 * @param month				対象月
	 * @param startmonth		年度開始月
	 * @return	対象年
	 */
	public static int getTargetYear(int fiscalyear, int month, int startmonth) {
		// 年度開始月の前月は対象年度の翌年を利用する
		// 年度開始月の後の月は対象年度を使用する
		int year = fiscalyear;
		if (month < startmonth) {
			year++;
		}
		return year;
	}
	
	/**
	 * 名称存在チェック
	 * @since	0.0.2
	 * @param value			対象コード
	 * @param aryTarget		対象名称を含む配列
	 * @return
	 * <p>
	 * 名称が存在する場合true、そうでない場合false
	 * </p>
	 */
	public static boolean checkNameExist(String value, String[][] aryTarget) {
		String target = StringUtil.getCodeName(value, aryTarget);
		if (target.equals(value)) {
			return false;
		}
		return true;
	}
	
	/**
	 * リストのソート
	 * @since	0.0.2
	 * @param list		対象リスト
	 * @param comp		対象Comparator
	 */
	public static void sortList(List<?> list, Comparator<Object> comp) {
		Collections.sort(list, comp);
	}
	
	/**
	 * リストのソート
	 * @since	0.0.2
	 * @param list			対象リスト
	 * @param comp			対象Comparator
	 * @param isAscending	true...昇順、false...降順
	 */
	public static void sortList(List<?> list, Comparator<Object> comp, boolean isAscending) {
		if (isAscending) {
			sortList(list, comp);
		} else {
			sortList(list, Collections.reverseOrder(comp));
		}
	}
	
	/**
	 * デフォルトパスワードチェック
	 * @param userid			対象ユーザID
	 * @param inputPassWord		対象入力パスワード
	 * @return
	 * <p>
	 * デフォルトパスワードの場合true、そうでない場合false
	 * </p>
	 * @throws Exception	例外処理が発生した場合
	 */
	public static boolean isDefaultPassWord(String userid, String inputPassWord) throws Exception {
		if (MospUtility.getDigest(MospUtility.getDigest(userid)).equals(MospUtility.getDigest(inputPassWord))) {
			return true;
		}
		return false;
	}
	
	/**
	 * コードの存在チェック。
	 * @param code 対象コード
	 * @param aryTarget 対象配列
	 * @return
	 * <p>
	 * 対象コードが対象配列に含まれる場合true、そうでない場合false。
	 * </p>
	 */
	public static boolean checkCodeExist(String code, String[][] aryTarget) {
		for (String[] target : aryTarget) {
			if (code.equals(target[0])) {
				return true;
			}
		}
		return false;
	}
	
}
