/*
 * Copyright (c) 2008-2009 OrangeSignal.com All rights reserved.
 */

package jp.sourceforge.orangesignal.ta.dataset;

import java.util.Calendar;

/**
 * 足単位変換で使用する日時切捨て用クラスを提供します。
 * 
 * @author 杉澤 浩二
 */
public class DateTruncater {

	protected Calendar calendar;

	/**
	 * 年の初期値を保持します。
	 */
	protected int year = 1970;

	/**
	 * 月の初期値を保持します。
	 */
	protected int month = Calendar.JANUARY;

	/**
	 * 日の初期値を保持します。
	 */
	protected int date = 1;

	/**
	 * 時の初期値を保持します。
	 */
	protected int hour = 0;

	/**
	 * 分の初期値を保持します。
	 */
	protected int minute = 0;

	/**
	 * 秒の初期値を保持します。
	 */
	protected int second = 0;

	/**
	 * ミリ秒の初期値を保持します。
	 */
	protected int millisecond = 0;

	/**
	 * デフォルトコンストラクタです。
	 */
	public DateTruncater() {
		this.calendar = Calendar.getInstance();
	}

	/**
	 * コンストラクタです。
	 * 
	 * @param calendar カレンダー
	 */
	public DateTruncater(final Calendar calendar) {
		if (calendar == null)
			throw new NullPointerException("Calendar is null.");
		this.calendar = calendar;
	}

	/**
	 * 指定されたカレンダーを指定された精度で切捨てて返します。
	 * 
	 * @param calendar カレンダー
	 * @param field 切捨て精度
	 * @return 指定された精度で切捨てられたカレンダー
	 */
	public Calendar truncate(final Calendar calendar, final int field) {
		final Calendar c = (Calendar) calendar.clone();

		if (field == Calendar.DAY_OF_WEEK) {
			final int first = c.getFirstDayOfWeek();
			final int current = c.get(Calendar.DAY_OF_WEEK);
			c.add(Calendar.DATE, first - current);
			return truncate(c, Calendar.HOUR_OF_DAY);
		}

		switch (field) {
			case Calendar.ERA:
			case Calendar.YEAR:
				c.set(Calendar.YEAR, year);
			case Calendar.MONTH:
				c.set(Calendar.MONTH, month);
			case Calendar.DATE:	// with Calendar.DAY_OF_MONTH ...
				c.set(Calendar.DATE, date);
			case Calendar.AM_PM:
			case Calendar.HOUR:
			case Calendar.HOUR_OF_DAY:
				c.set(Calendar.HOUR_OF_DAY, hour);
			case Calendar.MINUTE:
				c.set(Calendar.MINUTE, minute);
			case Calendar.SECOND:
				c.set(Calendar.SECOND, second);
			case Calendar.MILLISECOND:
				c.set(Calendar.MILLISECOND, millisecond);
				break;
			default:
		}
		return c;
	}

}
