/*
 * 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.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;

import jp.mosp.common.CommonConst;

/**
 * 時間、時刻に関するPartクラス
 * @author yoshida
 *	@version	0.0.4
 */
public class TimeUtil {
	
	/**
	 * 
	 */
	private TimeUtil() {
		// 他クラスによるインスタンス化を防止
	}
	
	/**
	 * int時刻の時間をString時に変換
	 * @param time	時刻（0時からの経過分数）
	 * @return	string	時間（時）
	 */
	public static String convIntegerTimeToStringHour(int time) {
		return String.valueOf(convIntegerTimeToIntegerHour(time));
	}
	
	/**
	 * int時刻の時間をString時に変換
	 * @since	0.0.3
	 * @param time	時刻（0時からの経過分数）
	 * @return	時間（時）
	 */
	public static int convIntegerTimeToIntegerHour(int time) {
		return time / CommonConst.NUM_1HOUR_MIN;
	}
	
	/**
	 * int時刻の分をString分に変換
	 * @param time	時刻（0時からの経過分数）
	 * @return	string	時間（分）
	 */
	public static String convIntegerTimeToStringMinutes(int time) {
		return String.valueOf(convIntegerTimeToIntegerMinutes(time));
	}
	
	/**
	 * int時刻の分をString分に変換
	 * @since	0.0.3
	 * @param time	時刻（0時からの経過分数）
	 * @return	時間（分）
	 */
	public static int convIntegerTimeToIntegerMinutes(int time) {
		return time % CommonConst.NUM_1HOUR_MIN;
	}
	
	/**
	 * String時刻の時間をString時に変換
	 * @param time HH:MM
	 * @return HH
	 */
	public static String convStringTimeToStringHour(String time) {
		if (time.equals("")) {
			return "0";
		} else {
			return convIntegerTimeToStringHour(convStringTimeToIntegerTime(time));
		}
	}
	
	/**
	 * String時刻の分をString分に変換
	 * @param time HH:MM
	 * @return MM
	 */
	public static String convStringTimeToStringMinutes(String time) {
		if (StringUtil.isNull(time)) {
			return "0";
		} else {
			return convIntegerTimeToStringMinutes(convStringTimeToIntegerTime(time));
		}
	}
	
	/**
	 * 時刻変換（int→String）
	 * @param time 時刻（0時からの経過分数）
	 * @return HH:MM
	 */
	public static String convIntegerTimeToStringTime(int time) {
		StringBuffer sb = new StringBuffer();
		sb.append(StringUtil.addZero(convIntegerTimeToIntegerHour(time)));
		sb.append(CommonConst.STR_TIME_SEPARATOR);
		sb.append(StringUtil.addZero(convIntegerTimeToIntegerMinutes(time)));
		return sb.toString();
	}
	
	/**
	 * 時刻変換（int→String）
	 * @param time  時刻（0時からの経過分数）
	 * @return HH時MM分
	 */
	public static String convIntegerTimeToJPTime(int time) {
		StringBuffer sb = new StringBuffer();
		sb.append(StringUtil.addZero(convIntegerTimeToIntegerHour(time)));
		sb.append(CommonConst.NAM_HOUR);
		sb.append(StringUtil.addZero(convIntegerTimeToIntegerMinutes(time)));
		sb.append(CommonConst.NAM_MINUTES);
		return sb.toString();
	}
	
	/**
	 * 時刻変換（String→int）
	 * @param time 時刻（HH:MM）
	 * @return int	時刻（0時からの経過分数）
	 */
	public static int convStringTimeToIntegerTime(String time) {
		String targetTime = time;
		if (StringUtil.isNull(time)) {
			targetTime = "0:0";
		}
		String[] ar = targetTime.split(CommonConst.STR_TIME_SEPARATOR);
		return convStringTimeToIntegerTime(ar[0], ar[1]);
	}
	
	/**
	 * 時刻変換（String→int）
	 * @param hour 時
	 * @param min 分
	 * @return int	時刻（0時からの経過分数）
	 */
	public static int convStringTimeToIntegerTime(String hour, String min) {
		return convIntegerTimeToIntegerTime(NumberUtil.getIntParam(hour), NumberUtil.getIntParam(min));
	}
	
	/**
	 * 時刻変換（String→String）
	 * @param hour 時
	 * @param min 分
	 * @return	HH:mm
	 */
	public static String convStringTimeFormatted(String hour, String min) {
		StringBuffer sb = new StringBuffer();
		sb.append(StringUtil.addZero(hour));
		sb.append(CommonConst.STR_TIME_SEPARATOR);
		sb.append(StringUtil.addZero(min));
		return sb.toString();
	}
	
	/**
	 * 時間変換（int→double）
	 * @param time 時刻（0時からの経過分数）
	 * @return hh.mm <br>分はそのまま
	 * 				[例] 65分→1.05
	 */
	public static double convIntegerTimeToDoubleTime(int time) {
		double dblhour = Math.floor(convMinutesToDoubleHour(time));
		double dblmin = (double)time % CommonConst.NUM_1HOUR_MIN / 100;
		double dtime = dblhour + dblmin;
		return dtime;
	}
	
	/**
	 * 時間変換（int→String）
	 * <p>[例] 90分→1.5</p>
	 * <p>15分単位の場合のみ利用してください。</p>
	 * @param time 時刻（0時からの経過分数）
	 * @return hh.mm 
	 */
	public static String convIntegerMinToStringHour(int time) {
		return String.valueOf(convIntegerTimeToDoubleTime(time));
	}
	
	/**
	 * 時間変換（int→String）
	 * @param time 時刻（0時からの経過分数）
	 * @return HH時間MM分
	 */
	public static String convIntegerTimeToJPHours(int time) {
		StringBuffer sb = new StringBuffer();
		sb.append(convIntegerTimeToStringHour(time));
		sb.append(CommonConst.NAM_COMMON_TIME);
		sb.append(StringUtil.addZero(convIntegerTimeToStringMinutes(time)));
		sb.append(CommonConst.NAM_MINUTES);
		return sb.toString();
	}
	
	/**
	 * 時間フォーマット
	 * @param hour 時間
	 * @return 時間(文字列)
	 */
	public static String getHourString(double hour) {
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setMinimumFractionDigits(2);
		return nf.format(hour);
	}
	
	/**
	 * 時刻変換（int→int）
	 * @since	0.0.2
	 * @param hour 時
	 * @param min 分
	 * @return int	時刻（0時からの経過分数）
	 */
	public static int convIntegerTimeToIntegerTime(int hour, int min) {
		return (hour * CommonConst.NUM_1HOUR_MIN) + min;
	}
	
	/**
	 * 時間重複判断。
	 * @since 0.0.4
	 * @param periodStart 期間開始時刻（0時からの経過分数）
	 * @param periodEnd 期間終了時刻（0時からの経過分数）
	 * @param startTime 対象開始時刻（0時からの経過分数）
	 * @param endTime 対象終了時刻（0時からの経過分数）
	 * @return
	 * <p>
	 * 期間に重複している場合true、そうでない場合false
	 * </p>
	 */
	public static boolean coverPeriod(int periodStart, int periodEnd, int startTime, int endTime) {
		if (periodEnd > periodStart && endTime > startTime) {
			// 開始時刻
			if (startTime >= periodStart && periodEnd > startTime) {
				return true;
			}
			// 終了時刻
			if (endTime > periodStart) {
				if (startTime >= periodEnd) {
					return false;
				}
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 時刻取得
	 * @param time 時刻（0時からの経過分数）
	 * @return HH:MM(24時以降「翌」が付く)
	 */
	public static String getJPStringTime(int time) {
		StringBuffer sb = new StringBuffer();
		int hour = convIntegerTimeToIntegerHour(time);
		if (hour >= CommonConst.NUM_DAILY_HOUR) {
			sb.append(CommonConst.NAM_NEXT);
			sb.append(StringUtil.addZero(hour - CommonConst.NUM_DAILY_HOUR));
		} else {
			sb.append(StringUtil.addZero(hour));
		}
		sb.append(CommonConst.STR_TIME_SEPARATOR);
		sb.append(StringUtil.addZero(convIntegerTimeToIntegerMinutes(time)));
		return sb.toString();
	}
	
	/**
	 * 時刻取得
	 * @param time 時刻（0時からの経過分数）
	 * @return H:M(24時以降「翌」が付く)
	 */
	public static String getJPStringTimeShort(int time) {
		StringBuffer sb = new StringBuffer();
		int hour = convIntegerTimeToIntegerHour(time);
		if (hour >= CommonConst.NUM_DAILY_HOUR) {
			sb.append(CommonConst.NAM_NEXT);
			sb.append(hour - CommonConst.NUM_DAILY_HOUR);
		} else {
			sb.append(hour);
		}
		sb.append(CommonConst.STR_TIME_SEPARATOR);
		sb.append(convIntegerTimeToIntegerMinutes(time));
		return sb.toString();
	}
	
	/**
	 * 時間取得
	 * @param minutes 対象時間（分）
	 * @return 変換後時間（時）※小数点第三位を切り上げ
	 */
	public static double convMinutesToDoubleHour(int minutes) {
		return new BigDecimal(Double.valueOf(minutes) / CommonConst.NUM_1HOUR_MIN).setScale(2, RoundingMode.CEILING)
			.doubleValue();
	}
	
	/**
	 * 時間取得
	 * @param hour 対象時間（時）
	 * @return 変換後時間（分）※小数点以下を切り上げ
	 */
	public static int convHourToMinutes(double hour) {
		return Double.valueOf(Math.ceil(hour * CommonConst.NUM_1HOUR_MIN)).intValue();
	}
	
}
