/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package com.aimluck.commons.utils;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

/**
 * 入力フィールドで取り扱う日付に対するユーティリティクラスです。 <br />
 * 
 */
public class ALDateUtil {

  /** 日付の表示フォーマット */
  protected static final String DEFAULT_DATE_FORMAT = "yyyy'/'M'/'d";

  /**
   * 日付の文字列をもとに、Calendar型に変換します。
   * 
   * @param strDate
   * @return
   */
  public static Calendar dateToCalendar(String strDate) {
    return dateToCalendar(strDate.substring(0, 4), strDate.substring(4, 6),
        strDate.substring(6, 8), false);
  }

  /**
   * 年月日の文字列をもとに、Calendar型に変換します。
   * 
   * @param strYear
   * @param strMonth
   * @param strDay
   * @param b
   * @return
   */
  public static Calendar dateToCalendar(String strYear, String strMonth,
      String strDay, boolean b) {
    int year, month, day;
    try {
      year = Integer.parseInt(strYear);
      month = Integer.parseInt(strMonth) - 1;
      day = Integer.parseInt(strDay);
    } catch (StringIndexOutOfBoundsException e) {
      return null;
    } catch (NumberFormatException e) {
      return null;
    }
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("JST"));
    cal.setLenient(b);
    cal.set(year, month, day, 0, 0, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal;
  }

  /**
   * 年月日の文字列表現を取得します。
   * 
   * @param year
   * @param month
   * @param day
   * @return
   */
  public static String formatDate(int year, int month, int day) {
    return formatDate(String.valueOf(year), String.valueOf(month), String
        .valueOf(day));
  }

  /**
   * 年月日の文字列表現を取得します。
   * 
   * @param strYear
   * @param strMonth
   * @param strDay
   * @return
   */
  public static String formatDate(String strYear, String strMonth, String strDay) {
    Calendar cal = dateToCalendar(strYear, strMonth, strDay, false);
    if (cal == null) {
      return null;
    }
    try {
      cal.getTime();
    } catch (IllegalArgumentException e) {
      return null;
    }
    return formatCalendarDate(cal);
  }

  /**
   * Calendar型を文字列の日付に変換します。
   * 
   * @param cal
   * @return
   */
  public static String formatCalendarDate(Calendar cal) {
    return getStringYear(cal) + getStringMonth(cal) + getStringDay(cal);
  }

  /**
   * 年の文字列表現を取得します。
   * 
   * @param cal
   * @return
   */
  public static String getStringYear(Calendar cal) {
    Object[] args = new Object[1];
    args[0] = Integer.valueOf(cal.get(Calendar.YEAR));
    return MessageFormat.format("{0,number,0000}", args);
  }

  /**
   * 月の文字列表現を取得します。
   * 
   * @param cal
   * @return
   */
  public static String getStringMonth(Calendar cal) {
    return getStringMonth(cal.get(Calendar.MONTH));
  }

  /**
   * 月の文字列表現を取得します。
   * 
   * @param month
   * @return
   */
  public static String getStringMonth(int month) {
    switch (month) {
    case Calendar.JANUARY:
      return "01";
    case Calendar.FEBRUARY:
      return "02";
    case Calendar.MARCH:
      return "03";
    case Calendar.APRIL:
      return "04";
    case Calendar.MAY:
      return "05";
    case Calendar.JUNE:
      return "06";
    case Calendar.JULY:
      return "07";
    case Calendar.AUGUST:
      return "08";
    case Calendar.SEPTEMBER:
      return "09";
    case Calendar.OCTOBER:
      return "10";
    case Calendar.NOVEMBER:
      return "11";
    case Calendar.DECEMBER:
      return "12";
    default:
      return null;
    }
  }

  /**
   * 日の文字列表現を取得します。
   * 
   * @param cal
   * @return
   */
  public static String getStringDay(Calendar cal) {
    Object[] args = new Object[1];
    args[0] = Integer.valueOf(cal.get(Calendar.DATE));
    return MessageFormat.format("{0,number,00}", args);
  }

  /**
   * 曜日の文字列表現を取得します。
   * 
   * @param cal
   * @return
   */
  public static String getDayOfWeek(Calendar cal) {
    String res = "";
    switch (cal.get(Calendar.DAY_OF_WEEK)) {
    case Calendar.SUNDAY:
      res = "（日）";
      break;
    case Calendar.MONDAY:
      res = "（月）";
      break;
    case Calendar.TUESDAY:
      res = "（火）";
      break;
    case Calendar.WEDNESDAY:
      res = "（水）";
      break;
    case Calendar.THURSDAY:
      res = "（木）";
      break;
    case Calendar.FRIDAY:
      res = "（金）";
      break;
    case Calendar.SATURDAY:
      res = "（土）";
      break;
    }
    return res;
  }

  /**
   * 日付の文字列表現を取得します。
   * 
   * @param date
   * @return
   */
  public static String format(Date date) {
    return format(date, null);
  }

  /**
   * 日付の文字列表現を取得します。
   * 
   * @param date
   * @param strFormat
   * @return
   */
  public static String format(Date date, String strFormat) {
    String formatStr = null;
    int year;
    int month;
    int day;

    if (date == null) {
      return "";
    }
    if (strFormat == null) {
      strFormat = DEFAULT_DATE_FORMAT;
    }

    try {
      Calendar calendar = new GregorianCalendar();
      calendar.setTime(date);
      year = calendar.get(Calendar.YEAR);
      month = calendar.get(Calendar.MONTH) + 1;
      day = calendar.get(Calendar.DATE);
    } catch (Throwable ex) {
      year = 0;
      month = 0;
      day = 0;
    }
    SimpleDateFormat formatter = new SimpleDateFormat(strFormat);
    GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);

    try {
      calendar.setLenient(false);
      formatStr = formatter.format(calendar.getTime());
    } catch (Exception ex) {
      formatStr = "";
    }
    return formatStr;
  }

}
