/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * http://aipo.com/
 *
 * Copyright(C) 2012 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.aimluck.eip.schedule;

import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.aimluck.commons.field.ALDateTimeField;
import com.aimluck.eip.schedule.util.ScheduleUtils;

/**
 * 1日スケジュール用のユーザー別日単位予定のコンテナです。
 * 
 */
public class AjaxScheduleUserOneDayContainer {

  /** ユーザー別日単位予定マップ */
  private Map<Integer, AjaxScheduleDayContainer> userDayConMap = null;

  /** 基準日 */
  Calendar targetDateCalendar = null;

  /**
   * コンストラクタ
   * 
   * @param targetDate
   *            基準日（yyyy/mm/dd形式）
   */
  public AjaxScheduleUserOneDayContainer(ALDateTimeField targetDate, List<Integer> userIdList) {
    // 基準日の初期化
    targetDateCalendar = Calendar.getInstance();
    if (targetDate != null) {
      targetDateCalendar.set(Calendar.YEAR, Integer.parseInt(targetDate.getYear()));
      targetDateCalendar.set(Calendar.MONTH, Integer.parseInt(targetDate.getMonth()) - 1);
      targetDateCalendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(targetDate.getDay()));
    }
    targetDateCalendar.set(Calendar.HOUR_OF_DAY, 0);
    targetDateCalendar.set(Calendar.MINUTE, 0);
    targetDateCalendar.set(Calendar.SECOND, 0);
    targetDateCalendar.set(Calendar.MILLISECOND, 0);

    // ユーザー別日単位予定マップの初期化
    userDayConMap = new LinkedHashMap<Integer, AjaxScheduleDayContainer>();
    for (Integer userId : userIdList) {
      AjaxScheduleDayContainer sdCon = new AjaxScheduleDayContainer();
      sdCon.initField();
      sdCon.setDate(targetDateCalendar.getTime());
      userDayConMap.put(userId, sdCon);
    }

  }

  /**
   * 予定をコンテナに格納します。
   * 
   * @param rd
   */
  public boolean addResultData(Integer userId, AjaxScheduleResultData rd) {
    AjaxScheduleDayContainer con = userDayConMap.get(userId);
    ALDateTimeField field = con.getDate();
    if (!rd.getPattern().equals("N")) {
      if (rd.getPattern().equals(ScheduleConst.SCHEDULE_PATTERN_DAYS)) {
        // <繰り返しパターン>=[日またぎ] の場合
        // 開始、終了日時の再設定用変数
        // コンテナ日付の00：00
        Calendar new_start_day = Calendar.getInstance();
        new_start_day.setTime(field.getValue());
        new_start_day.set(Calendar.HOUR_OF_DAY, 0);
        new_start_day.set(Calendar.MINUTE, 0);
        new_start_day.set(Calendar.SECOND, 0);
        new_start_day.set(Calendar.MILLISECOND, 0);
        // コンテナ日付の23：59
        Calendar new_end_day = Calendar.getInstance();
        new_end_day.setTime(field.getValue());
        new_end_day.set(Calendar.HOUR_OF_DAY, 23);
        new_end_day.set(Calendar.MINUTE, 59);
        new_end_day.set(Calendar.SECOND, 0);
        new_end_day.set(Calendar.MILLISECOND, 0);

        // rdの日付をカレンダー型に変換
        Calendar rd_start_day = Calendar.getInstance();
        rd_start_day.setTime(rd.getStartDate().getValue());
        rd_start_day.set(Calendar.HOUR_OF_DAY, 0);
        rd_start_day.set(Calendar.MINUTE, 0);
        rd_start_day.set(Calendar.SECOND, 0);
        rd_start_day.set(Calendar.MILLISECOND, 0);
        Calendar rd_end_day = Calendar.getInstance();
        rd_end_day.setTime(rd.getEndDate().getValue());
        rd_end_day.set(Calendar.HOUR_OF_DAY, 0);
        rd_end_day.set(Calendar.MINUTE, 0);
        rd_end_day.set(Calendar.SECOND, 0);
        rd_end_day.set(Calendar.MILLISECOND, 0);

        AjaxScheduleResultData rd3 = new AjaxScheduleResultData();

        rd3.initField();
        // スケジュールID
        rd3.setScheduleId((int) rd.getScheduleId().getValue());
        // 親ID
        rd3.setParentId((int) rd.getParentId().getValue());
        // スケジュール名
        rd3.setName(rd.getName().getValue());
        // 場所
        rd3.setPlace(rd.getPlace().getValue());
        // 仮スケジュールか
        rd3.setTmpreserve(rd.isTmpreserve());
        // 公開か
        rd3.setPublic(rd.isPublic());
        // 表示/非表示か
        rd3.setHidden(rd.isHidden());
        // ダミーか
        rd3.setDummy(rd.isDummy());
        // ログインユーザーか
        rd3.setLoginuser(rd.isLoginuser());
        // オーナーか
        rd3.setOwner(rd.isOwner());
        // 共有メンバーの更新が可能か
        rd3.setEditFlag(rd.isEditable());
        // メンバーか
        rd3.setMember(rd.isMember());
        // ユーザー/施設
        rd3.setType(rd.getType());
        // 所有者
        rd3.setUserId(rd.getUserId());
        // 参加メンバー一覧
        rd3.setMemberList(rd.getMemberList());

        // 状態
        rd3.setStatus(rd.getStatus());
        // 必須フラグ
        rd3.setRequired(rd.getRequired());
        // 重要フラグ
        rd3.setPriority(rd.getPriority());
        // 作成ユーザーID
        rd3.setCreateUserId(rd.getCreateUserId());
        // add start 要件No.9 スケジュール表示 （仮の予定、確定した予定）
        rd3.setTemporaryFlag(rd.getTemporaryFlag());
        // add end
        // add start 要件No.18 会議案内ファイル添付
        rd3.setFiles(rd.hasFiles());
        // add end
        // 個別色
        rd3.setIndividualColor(rd.getIndividualColor());
        // add start 結合試験障害16-01対応
        rd3.setOrganizer(rd.isOrganizer());
        // add end

        if (rd_start_day.equals(new_start_day)) {
          // 開始日時の年月日付=コンテナ年月日付 の場合
          rd3.setStartDate(rd.getStartDate().getValue());
          // 終了日時を再設定用日付に設定し直す
          rd3.setEndDate(new_end_day.getTime());
          rd3.setStraddleLocation(AjaxScheduleResultData.STRADDLE_LOC_START);
          con.addResultData(rd3, true);
        } else if (rd_start_day.before(new_start_day) && new_start_day.before(rd_end_day)) {
          // "開始日時の年月日付＜コンテナ年月日付" かつ "終了日時の年月日付＞コンテナ年月日付の場合"
          // 開始日時を再設定用日付に設定し直す
          rd3.setStartDate(new_start_day.getTime());
          // 終了日時を再設定用日付に設定し直す
          rd3.setEndDate(new_end_day.getTime());
          rd3.setStraddleLocation(AjaxScheduleResultData.STRADDLE_LOC_MIDDLE);
          con.addResultData(rd3, true);
        } else if (rd_end_day.equals(new_start_day)) {
          // 終了日時の年月日付=コンテナ年月日付 の場合
          // 開始日時を再設定用日付に設定し直す
          rd3.setStartDate(new_start_day.getTime());
          rd3.setEndDate(rd.getEndDate().getValue());
          rd3.setStraddleLocation(AjaxScheduleResultData.STRADDLE_LOC_END);
          con.addResultData(rd3, true);
        }
      } else {
        // 繰り返しスケジュール
        if (ScheduleUtils.isView(con.getDate(), rd.getPattern(), rd.getStartDate().getValue(), rd.getEndDate().getValue())) {
          Calendar temp = Calendar.getInstance();
          temp.setTime(field.getValue());
          temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(rd.getStartDate().getHour()));
          temp.set(Calendar.MINUTE, Integer.parseInt(rd.getStartDate().getMinute()));
          temp.set(Calendar.SECOND, 0);
          temp.set(Calendar.MILLISECOND, 0);
          Calendar temp2 = Calendar.getInstance();
          temp2.setTime(field.getValue());
          temp2.set(Calendar.HOUR_OF_DAY, Integer.parseInt(rd.getEndDate().getHour()));
          temp2.set(Calendar.MINUTE, Integer.parseInt(rd.getEndDate().getMinute()));
          temp2.set(Calendar.SECOND, 0);
          temp2.set(Calendar.MILLISECOND, 0);
          AjaxScheduleResultData rd3 = new AjaxScheduleResultData();
          rd3.initField();
          rd3.setScheduleId((int) rd.getScheduleId().getValue());
          rd3.setParentId((int) rd.getParentId().getValue());
          rd3.setName(rd.getName().getValue());
          rd3.setPlace(rd.getPlace().getValue());
          // 開始日を設定し直す
          rd3.setStartDate(temp.getTime());
          // 終了日を設定し直す
          rd3.setEndDate(temp2.getTime());
          rd3.setTmpreserve(rd.isTmpreserve());
          rd3.setPublic(rd.isPublic());
          rd3.setHidden(rd.isHidden());
          rd3.setDummy(rd.isDummy());
          rd3.setLoginuser(rd.isLoginuser());
          rd3.setOwner(rd.isOwner());
          rd3.setEditFlag(rd.isEditable());
          rd3.setMember(rd.isMember());
          rd3.setType(rd.getType());
          // 繰り返しはON
          rd3.setRepeat(true);
          rd3.setUserId(rd.getUserId());
          rd3.setMemberList(rd.getMemberList());

          // 状態
          rd3.setStatus(rd.getStatus());
          // 必須フラグ
          rd3.setRequired(rd.getRequired());
          // 重要フラグ
          rd3.setPriority(rd.getPriority());
          // 作成ユーザーID
          rd3.setCreateUserId(rd.getCreateUserId());
          // add start 要件No.9 スケジュール表示 （仮の予定、確定した予定）
          rd3.setTemporaryFlag(rd.getTemporaryFlag());
          // add end
          // add start 要件No.18 会議案内ファイル添付
          rd3.setFiles(rd.hasFiles());
          // add end
          // 個別色
          rd3.setIndividualColor(rd.getIndividualColor());
          // add start 結合試験障害16-01対応
          rd3.setOrganizer(rd.isOrganizer());
          // add end

          con.addResultData(rd3, true);
        }
      }
    } else if (field.getYear().equals(rd.getStartDate().getYear())
      && field.getMonth().equals(rd.getStartDate().getMonth())
      && field.getDay().equals(rd.getStartDate().getDay())) {
      con.addResultData(rd, true);
      return true;
    }
    return false;
  }

  /**
   * 予定マップを取得します。
   * 
   * @return
   */
  public Map<Integer, AjaxScheduleDayContainer> getUserDayConMap() {
    return userDayConMap;
  }

}
