/*
 * 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.part;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import jp.mosp.common.CommonConst;
import jp.mosp.common.common.MospUtility;
import jp.mosp.common.utils.JapanHolidayUtil;
import jp.mosp.common.utils.StringUtil;
import jp.mosp.common.utils.VariousUtil;

/**
 * 祝祭日に関するPartクラス
 * @author yoshida
 *	@version	0.0.3
 */
public class JPHolidayPart extends BasePart {
	
	/**
	 * コンストラクタ
	 */
	public JPHolidayPart() {
		super();
	}
	
	/**
	 * コンストラクタ
	 * @param partInfo	Partを利用する際に必要な情報
	 */
	public JPHolidayPart(PartInfo partInfo) {
		super(partInfo);
	}
	

	/**
	 * 年をキーとした祝日マップ
	 */
	private Map<Integer, Map<Date, String>>	holidayMap;
	

	/**
	 * 祝日名称取得
	 * <p>	2009/02/25	m.yoshida	祝日メソッド修正 </p>
	 * @param targetDate		対象年月日
	 * @return	対象年月日祝日名称
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getPublicHolidayName(Date targetDate) throws Exception {
		// 対象日祝日名称取得
		String targetName = searchMap(targetDate, true, true).get(targetDate);
		if (StringUtil.isNotNull(targetName)) {
			return targetName;
		}
		return "";
	}
	
	/**
	 * 所定休日名称取得
	 * @param targetDate		対象年月日
	 * @param addJPholiday  	国民の祝日フラグ(労使協定)
	 * @param addHolidayMaster 休暇マスタフラグ(労使協定)
	 * @return	対象年月日所定休日名称
	 * @throws Exception	例外処理が発生した場合
	 */
	public String getStandardHolidayName(Date targetDate, boolean addJPholiday, boolean addHolidayMaster)
			throws Exception {
		// 対象日祝日名称取得
		String targetName = searchMap(targetDate, addJPholiday, addHolidayMaster).get(targetDate);
		if (StringUtil.isNotNull(targetName)) {
			return targetName;
		}
		return "";
	}
	
	/**
	 * 祝祭日判定
	 * @since	0.0.3
	 * @param targetDate		対象年月日
	 * @return
	 * <p>
	 * 対象年月日が祝祭日ならtrue、そうでない場合false
	 * </p>
	 * @throws Exception	例外処理が発生した場合
	 */
	public boolean isPublicHoliday(Date targetDate) throws Exception {
		if (searchMap(targetDate, true, true).containsKey(targetDate)) {
			return true;
		}
		return isStandardHoliday(targetDate, true, true);
	}
	
	/**
	 * 所定休日判定
	 * @param targetDate 	対象年月日
	 * @param addJPholiday 国民の祝日フラグ(労使協定)
	 * @param addHolidayMaster 休暇マスタフラグ(労使協定)
	 * @return
	 * <p>
	 * 対象年月日が所定休日ならtrue、そうでない場合false
	 * </p>
	 * @throws Exception 	例外処理が発生した場合
	 */
	public boolean isStandardHoliday(Date targetDate, boolean addJPholiday, boolean addHolidayMaster) throws Exception {
		// 国民の祝日フラグ(労使協定)対応
		// 休暇マスタフラグ(労使協定)対応
		if (searchMap(targetDate, addJPholiday, addHolidayMaster).containsKey(targetDate)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 祝日マップ検索
	 * @since	0.0.3
	 * @param targetDate 	対象年月日
	 * @param addJPholiday 国民の祝日フラグ(労使協定)
	 * @param addHolidayMaster 休暇マスタフラグ(労使協定)
	 * @return	対象年祝日マップ
	 * @throws Exception 	例外処理が発生した場合
	 */
	private Map<Date, String> searchMap(Date targetDate, boolean addJPholiday, boolean addHolidayMaster)
			throws Exception {
		int year = MospUtility.getYear(targetDate);
		if (VariousUtil.isNull(holidayMap)) {
			holidayMap = new TreeMap<Integer, Map<Date, String>>();
		}
		if (!holidayMap.containsKey(year)) {
			holidayMap.put(year, createHolidayMap(year, addHolidayMaster, addJPholiday));
		}
		return holidayMap.get(year);
	}
	
	/**
	 * 祝日名称マップ生成
	 * @param year			対象年
	 * @param addHolidayMaster 祝祭日マスタの利用可否
	 * @param addJPholiday 祝日法の適用可否
	 * @return 	祝祭日マップ
	 * @throws Exception 	例外処理が発生した場合
	 */
	private Map<Date, String> createHolidayMap(int year, boolean addHolidayMaster, boolean addJPholiday)
			throws Exception {
		Map<Date, String> map = new TreeMap<Date, String>();
		// 祝祭日マスタ
		if (addHolidayMaster) {
			String[][] aryCodeHoliday = part().mospcode().getMosPCodeArray(CommonConst.TID_HOLIDAY);
			Date holiday = null;
			for (String[] element : aryCodeHoliday) {
				// MM/DDから始まる休日への対応
				if (element[0].startsWith("0") || element[0].startsWith("1")) {
					StringBuffer date = new StringBuffer();
					date.append(String.valueOf(year));
					date.append(CommonConst.SEPARATOR_DATE);
					date.append(element[0]);
					holiday = MospUtility.getDate(date.toString());
				} else {
					holiday = MospUtility.getDate(element[0]);
				}
				map.put(holiday, element[1]);
			}
		}
		// 国民の祝日
		if (addJPholiday) {
			/*						
			 *  	2009/10/29	m.yoshida	祝日法対応
			 */
			Map<Date, String> jpHolidayMap = getJapanHolidayMap(year);
			map.putAll(jpHolidayMap);
		}
		return map;
	}
	
	/**
	 * 単年祝祭日マップ取得
	 * @param year	対象年
	 * @return	祝祭日マップ
	 */
	private Map<Date, String> getJapanHolidayMap(int year) {
		return new JapanHolidayUtil(year).getHolidayMap();
	}
	
}
