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

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import sun.util.calendar.CalendarUtils;

import com.aimluck.commons.field.ALDateTimeField;
import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.commons.utils.ALDateUtil;
import com.aimluck.eip.cayenne.om.portlet.EipTExtTimecard;
import com.aimluck.eip.common.ALData;

/**
 * タイムカードのResultDataです。 <BR>
 * 
 */
public class ExtTimecardResultData implements ALData {

  /** 現在時刻 */
  private ALStringField now_time;

  /** 出勤フラグ */
  private ALStringField work_flag;

  /** 勤務時刻 */
  private ALDateTimeField work_date;
  
  /** 算出退勤時刻 */
  private Calendar computed_clock_out_time;

  /** 修正フラグ */
  private ALStringField refix_flag;

  /** 一覧の日付 */
  private ALStringField list_date;

  /** 理由 */
  private ALStringField reason;

  public boolean reason_flg;

  /** 備考 */
  private ALStringField remarks;

  public boolean remarks_flg;

  /** タイムカードのID */
  private ALStringField timecard_id;

  /** ある一日の合計勤務時間 */
  private ALNumberField sum_work_date;

  /** */
  private ALDateTimeField punch_date;

  /** 出勤時間 */
  private ALDateTimeField clock_in_time;

  /** 退勤時間 */
  private ALDateTimeField clock_out_time;

  /** 外出時間 */
  private ArrayList<ALDateTimeField> outgoing_time;

  /** 復帰時間 */
  private ArrayList<ALDateTimeField> comeback_time;

  /** 種類 */
  private ALStringField type;

  private boolean isTypeP;

  private boolean isTypeA;

  private boolean isTypeH;

  private boolean isTypeC;

  private boolean isTypeE;

  private String paid_holiday_type;

  private String car_commuting_class;
  
  /**
   * 代休時間（分） 
   * 
   **/
  private int off_time = 0;
  
  /**
   * 代休時間（時）を文字で取得します。
   */
  public String getOffTime(){
    if(off_time == 0) return "";
    return String.format("%2.2f", (double)off_time / 60f);
  } 
  
  /**
   * 代休時間（分）を数値で取得します。
   */
  public int getOffTimeMinutes(){
    return off_time;
  }
  
  /**
   * 代休時間（分）を設定します。
   * @param value
   */
  public void setOffTime(Object value){
    if(value != null)
      off_time = Integer.parseInt(value.toString());
  }
  
  /**
   * 
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initField() {
    work_flag = new ALStringField();
    now_time = new ALStringField();
    work_date = new ALDateTimeField();
    refix_flag = new ALStringField();
    list_date = new ALStringField();
    timecard_id = new ALStringField();
    reason = new ALStringField();
    sum_work_date = new ALNumberField();
    remarks = new ALStringField();
    punch_date = new ALDateTimeField();
    clock_in_time = new ALDateTimeField();
    clock_out_time = new ALDateTimeField();
    reason_flg = false;
    remarks_flg = false;
    isTypeP = false;
    isTypeA = false;
    isTypeH = false;
    isTypeC = false;
    isTypeE = false;
    outgoing_time = new ArrayList<ALDateTimeField>();
    comeback_time = new ArrayList<ALDateTimeField>();

    type = new ALStringField();
    /*
     * outgoing_time = new
     * ALDateTimeField[EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY]; comeback_time
     * = new ALDateTimeField[EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY]; for
     * (int i = 0 ; i < EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY ; i++) {
     * outgoing_time[i] = new ALDateTimeField(); comeback_time[i] = new
     * ALDateTimeField(); }
     */
  }

  /**
   * 出勤時間がNULLかどうか調べます。
   * 
   * @return boolean
   */
  public boolean getIsNullClockInTime() {
    if (clock_in_time.isNullHour()) {
      return true;
    }
    return false;
  }

  /**
   * 退勤時間がNULLかどうか調べます。
   * ここでは算出退勤時刻のみを監視します。
   * 
   * @return boolean
   */
  public boolean getIsNullClockOutTime() {
    if (computed_clock_out_time == null) {
      return true;
    }
    return false;
  }

  /**
   * 現在外出中かどうか調べます。
   * 
   * @return boolean
   */
  public boolean getIsOutgoing() {
    int length = outgoing_time.size();
    for (int i = 0; i < length; i++) {
      if (!outgoing_time.get(i).isNullHour()
          && comeback_time.get(i).isNullHour()) {
        return true;
      }
    }
    return false;
  }

  /**
   * 算出退勤時刻を設定します。
   * @param date
   */
  public void setComputedClockOutTime(Date date) {
    if(date != null){
      if(computed_clock_out_time == null) computed_clock_out_time = Calendar.getInstance();
      computed_clock_out_time.setTime(date);
    } 
  }
  
  public void setClockInTime(Date date) {
    clock_in_time.setValue(date);
  }

  public void setClockOutTime(Date date) {
    clock_out_time.setValue(date);
  }

  public void setOutgoingTime(Date date, int n) {
    ALDateTimeField datetime = new ALDateTimeField();
    datetime.setValue(date);
    outgoing_time.add(datetime);
    // outgoing_time.get(n-1).setValue(date);
  }

  public void setComebackTime(Date date, int n) {
    ALDateTimeField datetime = new ALDateTimeField();
    datetime.setValue(date);
    comeback_time.add(datetime);
    // comeback_time.get(n-1).setValue(date);
  }

  public void setPunchDate(Date date) {
    punch_date.setValue(date);
  }

  /**
   * @param i
   */
  public void setNowTime(String time) {
    now_time.setValue(time);
  }

  public void setType(String str) {
    type.setValue(str);
  }

  /**
   * @param i
   */
  public void setRefixFlag(Date create_date, Date update_date) {
    if (equalsToDate(create_date, update_date, true)) {
      refix_flag.setValue("0");
    } else {
      refix_flag.setValue("1");
    }
  }

  /**
   * @return
   */
  public void setTimecardId(long i) {
    timecard_id.setValue(Long.valueOf(i).toString());
  }

  /**
   * @param i
   */
  public void setReason(String str_reason) {
    reason.setValue(str_reason);
  }

  /**
   * @param i
   */
  public void setRemarks(String str_remarks) {
    remarks.setValue(str_remarks);
  }

  /**
   * 
   * @return
   */
  public void addSumWorkDate() {
    long count = sum_work_date.getValue();
    sum_work_date.setValue(count + 1);
  }

  /**
   * @return
   */
  public ALNumberField getSumWorkDate() {
    return sum_work_date;
  }

  public ALDateTimeField getClockInTime() {
    return clock_in_time;
  }

  public String getClockInTime(String format) {
    try {
      SimpleDateFormat sdf = new SimpleDateFormat(format);
      return sdf.format(clock_in_time.getValue());
    } catch (Exception e) {
      return "";
    }
  }

  public ALDateTimeField getPunchDate() {
    return punch_date;
  }

  /**
   * 算出退勤時刻を取得します。
   * @return
   */
  public Calendar getComputedClockOutTime() {
    return computed_clock_out_time;
  }

  /**
   * 有給（全休・半休）を取得します
   * 
   * @return　0：通常/1:全休/2：午前休/3：午後休
   */
  public String getPaidHolidayType() {
    return paid_holiday_type;
  }
  /**
   * 有給（全休・半休）を設定します
   * @param data　0：通常/1:全休/2：午前休/3：午後休
   */
  public void setPaidHolidayType(String data) {
    paid_holiday_type = data;
  }

  /**
   * 自家用車通勤区分を取得します。
   * 
   * @return　0:×/1:△/2:○
   */
  public String getCarCommutingClass() {
    return car_commuting_class;
  }
  /**
   * 自家用車通勤区分を設定します。
   * @param data　0:×/1:△/2:○
   */
  public void setCarCommutingClass(String data) {
    car_commuting_class = data;
  } 

  public ALDateTimeField getClockOutTime() {
    return clock_out_time;
  }
  public String getClockOutTime(String format) {
    try {
      SimpleDateFormat sdf = new SimpleDateFormat(format);
      return sdf.format(clock_out_time.getValue());
    } catch (Exception e) {
      return "";
    }
  }

  public ALStringField getType() {
    return type;
  }

  /**
   * 当日中最新の外出時間を得ます。
   * 
   * @return
   */
  public ALDateTimeField getOutgoingTime() {
    for (int i = 0; i < EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) {
      if (outgoing_time.get(i).isNullHour()) {
        if (i == 0)
          return null;
        return outgoing_time.get(i - 1);
      }
    }
    return outgoing_time.get(EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY - 1);
  }

  /**
   * 当日中最近の復帰時間を得ます。
   * 
   * @return
   */
  public ALDateTimeField getComebackTime() {
    for (int i = 0; i < EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY; i++) {
      if (!comeback_time.get(i).isNullHour()) {
        if (i == 0)
          return null;
        return comeback_time.get(i - 1);
      }
    }
    return comeback_time.get(EipTExtTimecard.OUTGOING_COMEBACK_PER_DAY - 1);
  }

  /**
   * 当日全ての外出時間を得ます。
   * 
   * @return
   */
  public ArrayList<ALDateTimeField> getAllOutgoingTime() {
    return outgoing_time;
  }

  /**
   * 当日全ての復帰時間を得ます。
   * 
   * @return
   */
  public ArrayList<ALDateTimeField> getAllComebackTime() {
    return comeback_time;
  }

  /**
   *
   */
  public ALStringField getNowTime() {
    return now_time;
  }

  /**
   *
   */
  public ALStringField getRefixFlag() {
    return refix_flag;
  }

  /**
   *
   */
  public ALStringField getListDate() {
    return list_date;
  }

  /**
   *
   */
  public ALStringField getTimecardId() {
    return timecard_id;
  }

  /**
   *
   */
  public ALStringField getReason() {
    return reason;
  }

  /**
  *
  */
  public ALStringField getRemarks() {
    return remarks;
  }

  /**
   * 指定した2つの日付を比較する．
   * 
   * @param date1
   * @param date2
   * @param checkTime
   *          時間まで比較する場合，true．
   * @return 等しい場合，true．
   */
  private boolean equalsToDate(Date date1, Date date2, boolean checkTime) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date1);
    int date1Year = cal.get(Calendar.YEAR);
    int date1Month = cal.get(Calendar.MONTH) + 1;
    int date1Day = cal.get(Calendar.DATE);
    int date1Hour = cal.get(Calendar.HOUR);
    int date1Minute = cal.get(Calendar.MINUTE);
    int date1Second = cal.get(Calendar.SECOND);
    cal.setTime(date2);
    int date2Year = cal.get(Calendar.YEAR);
    int date2Month = cal.get(Calendar.MONTH) + 1;
    int date2Day = cal.get(Calendar.DATE);
    int date2Hour = cal.get(Calendar.HOUR);
    int date2Minute = cal.get(Calendar.MINUTE);
    int date2Second = cal.get(Calendar.SECOND);
    if (checkTime) {
      if (date1Year == date2Year && date1Month == date2Month
          && date1Day == date2Day && date1Hour == date2Hour
          && date1Minute == date2Minute && date1Second == date2Second) {
        return true;
      }
    } else {
      if (date1Year == date2Year && date1Month == date2Month
          && date1Day == date2Day) {
        return true;
      }
    }
    return false;
  }

  /**
   *
   */
  public ALDateTimeField getWorkDate() {
    return work_date;
  }

  public String getWorkDateStr() {
    SimpleDateFormat sdf = new SimpleDateFormat("HH時mm分");
    return sdf.format(work_date.getValue());
  }

  /**
   * @return
   */
  public ALStringField getWorkFlag() {
    return work_flag;
  }

  /**
   * @return
   */
  public void setWorkFlag(String flag) {
    work_flag.setValue(flag);
  }

  /**
   * @param i
   */
  public void setWorkDate(Date date) {
    work_date.setValue(date);
    list_date.setValue(ALDateUtil.format(date, "MM月dd日"));
  }

  public boolean getRemarksFlg() {
    return remarks_flg;
  }

  public boolean getReasonFlg() {
    return reason_flg;
  }

  public boolean getIsTypeP() {
    return isTypeP;
  }

  public boolean getIsTypeA() {
    return isTypeA;
  }

  public boolean getIsTypeH() {
    return isTypeH;
  }

  public boolean getIsTypeC() {
    return isTypeC;
  }

  public boolean getIsTypeE() {
    return isTypeE;
  }

  public void setRemarksFlg(boolean b) {
    remarks_flg = b;
  }

  public void setReasonFlg(boolean b) {
    reason_flg = b;
  }

  public void setIsTypeP(boolean b) {
    isTypeP = b;
  }

  public void setIsTypeA(boolean b) {
    isTypeA = b;
  }

  public void setIsTypeH(boolean b) {
    isTypeH = b;
  }

  public void setIsTypeC(boolean b) {
    isTypeC = b;
  }

  public void setIsTypeE(boolean b) {
    isTypeE = b;
  }

}
