/* * Aipo is a groupware program developed by TOWN, Inc. * Copyright (C) 2004-2015 TOWN, Inc. * http://www.aipo.com * * 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.ArrayList; import java.util.Calendar; import java.util.List; import com.aimluck.commons.field.ALDateTimeField; import com.aimluck.eip.common.ALData; /** * 1日スケジュールのコンテナです。 * */ public class ScheduleOnedayContainer implements ALData { /** <code>list</code> スケジュールリスト */ private List<ScheduleOnedayResultData> list; /** <code>dList</code> 重複スケジュールリスト */ private List<ScheduleOnedayResultData> dList; /** <code>dList</code> 重複スケジュールリスト */ private List<ScheduleOnedayResultData> dupList; /** <code>rowIndex</code> rowIndex */ private int dRowCount; /** <code>rd</code> 期間スケジュール */ private ScheduleOnedayResultData rd; /** <code>rows</code> rows */ private int rows[]; /** <code>count</code> count */ private int count; /** <code>count</code> count */ private int dcount; /** <code>rowIndex</code> rowIndex */ private int rowIndex; /* * */ @Override public void initField() { // スケジュールリスト list = new ArrayList<ScheduleOnedayResultData>(); // 重複スケジュールリスト dList = new ArrayList<ScheduleOnedayResultData>(); // 重複スケジュールリスト dupList = new ArrayList<ScheduleOnedayResultData>(); } /** * 開始時間、終了時間を設定します。 * * @param startHour * @param endHour */ public void initHour(int startHour, int endHour) { rows = new int[(endHour - startHour) * 12 + 1]; int size = rows.length; for (int i = 0; i < size; i++) { rows[i] = 1; } } /** * スケジュールを追加します。 * * @param rd * @param startHour * @param endHour * @param viewDate */ public void addResultData(ScheduleOnedayResultData rd, int startHour, int endHour, ALDateTimeField viewDate) { ScheduleOnedayResultData rd2 = new ScheduleOnedayResultData(); rd2.setFormat("yyyy-MM-dd-HH-mm"); rd2.initField(); // Oneday boolean dup = false; int sta = startHour * 12; int eta = endHour * 12; int st = Integer.parseInt(rd.getStartDate().getHour()) * 12 + Integer.parseInt(rd.getStartDate().getMinute()) / 5; int ed = Integer.parseInt(rd.getEndDate().getHour()) * 12 + Integer.parseInt(rd.getEndDate().getMinute()) / 5; if ((ed - sta > 0 && eta - st > 0) || (ed - sta == 0 && st == ed)) { if (sta > st) { st = sta; } if (eta < ed) { ed = eta; } int tmpRowIndex = rowIndex; rd.setStartRow(st - sta); rd.setEndRow(ed - sta); if ((ed - st == 0) && (st - sta + tmpRowIndex - count >= 0)) { rd.setIndex(rows[st - sta]); if (rows[st - sta] > 1) { rd.setDuplicate(true); list.get(list.size() - 1).setDuplicate(true); } rows[st - sta]++; rowIndex++; ed++; } sta -= tmpRowIndex; if (st - sta - count > 0) { // Rowspan は Velocity で設定される。 // rd2.setRowspan(st - sta - count); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (count - tmpRowIndex) / 12; int min = ((count - tmpRowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setStartDate(cal.getTime()); hour = (st - sta - count) / 12; min = ((st - sta - count) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setEndDate(cal.getTime()); rd2.setStartRow(list.size() == 0 ? 0 : list .get(list.size() - 1) .getEndRow()); rd2.setEndRow(rd.getStartRow()); list.add(rd2); } else if (st - sta - count != 0) { rd.setDuplicate(true); dup = true; list.get(list.size() - 1).setDuplicate(true); dupList.add(rd); // 重複スケジュールの並べ替え dRowCount = dupList.size(); for (int i = 0; i < dupList.size() - 1; i++) { for (int j = i + 1; j < dupList.size(); j++) { if ((dupList.get(i).getEndDateTime() <= dupList .get(j) .getStartDateTime())) { dupList.add(i + 1, dupList.get(j)); dupList.remove(j + 1); dRowCount = dRowCount - 1; break; } else if ((dupList.get(i).getEndRow() <= dupList .get(j) .getStartRow())) { dRowCount = dRowCount - 1; } } } interrupDList(rd, dupList, startHour, endHour, viewDate); } if (!dup) { list.add(rd); count = ed - sta; } else { rd.setdRowCount(dRowCount); } } } /** * @param rd3 * @param dupList2 * @param i * @param viewDate * @param endHour * @param startHour */ private void interrupDList(ScheduleOnedayResultData rd3, List<ScheduleOnedayResultData> dupList2, int startHour, int endHour, ALDateTimeField viewDate) { dList.clear(); dcount = 0; int i = 0; int tmpRowIndex = 0; int dRowIndex = 0; // 重複スケジュールでのrows加算 int sta = startHour * 12; int eta = endHour * 12; int st = Integer.parseInt(rd3.getStartDate().getHour()) * 12 + Integer.parseInt(rd3.getStartDate().getMinute()) / 5; int ed = Integer.parseInt(rd3.getEndDate().getHour()) * 12 + Integer.parseInt(rd3.getEndDate().getMinute()) / 5; if (!(rd3.getStartDate().getDay().equals(rd3.getEndDate().getDay())) && rd3.getEndDate().getHour().equals("0")) { ed = 12 * 24; } if ((ed - sta > 0 && eta - st > 0) || (ed - sta == 0 && st == ed)) { if (sta > st) { st = sta; } if (eta < ed) { ed = eta; } tmpRowIndex = rowIndex; if ((ed - st == 0) && (st - sta + tmpRowIndex - dcount >= 0)) { rd3.setIndex(rows[st - sta]); if (rows[st - sta] > 1) { rd3.setDuplicate(true); } rows[st - sta]++; } } do { ScheduleOnedayResultData rd2 = new ScheduleOnedayResultData(); rd2.setFormat("yyyy-MM-dd-HH-mm"); rd2.initField(); // Oneday sta = startHour * 12; eta = endHour * 12; st = Integer.parseInt(dupList2.get(i).getStartDate().getHour()) * 12 + Integer.parseInt(dupList2.get(i).getStartDate().getMinute()) / 5; ed = Integer.parseInt(dupList2.get(i).getEndDate().getHour()) * 12 + Integer.parseInt(dupList2.get(i).getEndDate().getMinute()) / 5; if (!(dupList2.get(i).getStartDate().getDay().equals(dupList2 .get(i) .getEndDate() .getDay())) && dupList2.get(i).getEndDate().getHour().equals("0")) { ed = 12 * 24; } if ((ed - sta > 0 && eta - st > 0) || (ed - sta == 0 && st == ed)) { if (sta > st) { st = sta; } if (eta < ed) { ed = eta; } tmpRowIndex = dRowIndex; // tmpRowIndex = rows[st - sta]; dupList2.get(i).setStartRow(st - sta); dupList2.get(i).setEndRow(ed - sta); if ((ed - st == 0) && (st - sta + tmpRowIndex - dcount >= 0)) { dRowIndex++; ed++; } sta -= tmpRowIndex; if (i > 0) { if (st - sta - dcount > 0) { // Rowspan は Velocity で設定される。 // rd2.setRowspan(st - sta - count); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (dcount - tmpRowIndex) / 12; int min = ((dcount - tmpRowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setStartDate(cal.getTime()); hour = (st - sta - dcount) / 12; min = ((st - sta - dcount) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setEndDate(cal.getTime()); rd2.setStartRow(dList.size() == 0 ? 0 : dList .get(dList.size() - 1) .getEndRow()); rd2.setEndRow(dupList2.get(i).getStartRow()); dList.add(rd2); } else if (st - sta - dcount == 0) { } else { int index = (endHour - startHour) * 12 + dRowIndex; if (index > dcount) { ScheduleOnedayResultData rd = new ScheduleOnedayResultData(); rd.setFormat("yyyy-MM-dd-HH-mm"); rd.initField(); rd.setRowspan(index - dcount); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (dcount - dRowIndex) / 12; int min = ((dcount - dRowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setStartDate(cal.getTime()); hour = (index - dcount) / 12; min = ((index - dcount) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setEndDate(cal.getTime()); rd.setStartRow(dList.size() == 0 ? 0 : dList .get(dList.size() - 1) .getEndRow()); rd.setEndRow(rows.length - 1); dList.add(rd); } dcount = 0; dRowIndex = 0; tmpRowIndex = dRowIndex; sta = startHour * 12; if (st - sta - dcount > 0) { Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (dcount - tmpRowIndex) / 12; int min = ((dcount - tmpRowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setStartDate(cal.getTime()); hour = (st - sta - dcount) / 12; min = ((st - sta - dcount) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setEndDate(cal.getTime()); rd2.setStartRow(0); rd2.setEndRow(dupList2.get(i).getStartRow()); dList.add(rd2); } } } else { if (st - sta - dcount > 0) { // Rowspan は Velocity で設定される。 // rd2.setRowspan(st - sta - count); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (dcount - tmpRowIndex) / 12; int min = ((dcount - tmpRowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setStartDate(cal.getTime()); hour = (st - sta - dcount) / 12; min = ((st - sta - dcount) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd2.setEndDate(cal.getTime()); rd2.setStartRow(dList.size() == 0 ? 0 : dList .get(dList.size() - 1) .getEndRow()); rd2.setEndRow(dupList2.get(i).getStartRow()); dList.add(rd2); } else if (st - sta - dcount != 0) { } } dcount = ed - sta; dList.add(dupList2.get(i)); } i++; } while (i < dupList2.size()); } /** * 後処理を行います。 * * @param startHour * @param endHour * @param viewDate */ public void last(int startHour, int endHour, ALDateTimeField viewDate) { int index = (endHour - startHour) * 12 + rowIndex; if (index > count) { ScheduleOnedayResultData rd = new ScheduleOnedayResultData(); rd.setFormat("yyyy-MM-dd-HH-mm"); rd.initField(); rd.setRowspan(index - count); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (count - rowIndex) / 12; int min = ((count - rowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setStartDate(cal.getTime()); hour = (index - count) / 12; min = ((index - count) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setEndDate(cal.getTime()); rd.setStartRow(list.size() == 0 ? 0 : list .get(list.size() - 1) .getEndRow()); rd.setEndRow(rows.length - 1); list.add(rd); } if (index > dcount + rowIndex) { ScheduleOnedayResultData rd = new ScheduleOnedayResultData(); rd.setFormat("yyyy-MM-dd-HH-mm"); rd.initField(); rd.setRowspan(index - dcount); Calendar cal = Calendar.getInstance(); cal.setTime(viewDate.getValue()); cal.add(Calendar.HOUR, startHour); int hour = (dcount - rowIndex) / 12; int min = ((dcount - rowIndex) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setStartDate(cal.getTime()); hour = (index - dcount) / 12; min = ((index - dcount) % 12) * 5; cal.add(Calendar.HOUR, hour); cal.add(Calendar.MINUTE, min); rd.setEndDate(cal.getTime()); rd.setStartRow(dList.size() == 0 ? 0 : dList .get(dList.size() - 1) .getEndRow()); rd.setEndRow(rows.length - 1); dList.add(rd); } } /** * 期間スケジュールを設定します。 * * @param rd */ public void setSpanResultData(ScheduleOnedayResultData rd) { this.rd = rd; } /** * rowsを取得します。 * * @return */ public int[] getRows() { return rows; } /** * 期間スケジュールを取得します。 * * @return */ public ScheduleOnedayResultData getSpanResultData() { return rd; } /** * スケジュールリストを取得します。 * * @return */ public List<ScheduleOnedayResultData> getSchedule() { return list; } /** * 重複スケジュールリストを取得します。 * * @return */ public List<ScheduleOnedayResultData> getDuplicateSchedule() { return dList; } /** * 重複スケジュールがあるかどうか * * @return */ public boolean isDuplicate() { return dList.size() != 0; } /** * @return */ public int getDuplicateScheduleRowCount() { return dRowCount; } }