1 package de.jaret.examples.timebars.calendar.model;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import de.jaret.util.date.Interval;
7 import de.jaret.util.date.JaretDate;
8 import de.jaret.util.ui.timebars.model.DefaultTimeBarModel;
9 import de.jaret.util.ui.timebars.model.TimeBarRow;
10
11 public class CalendarModel extends DefaultTimeBarModel {
12 /*** date used as a base date for all intervals. */
13 public static final JaretDate BASEDATE = new JaretDate(1, 5, 2000, 0, 0, 0);
14 /***
15 * Update or create the model for the given month. If the month is not already created, day entries will be created.
16 *
17 * @param month month
18 * @param year year
19 */
20 public void createMonth(int month, int year) {
21 int beginIndex = getIndexForDate(new JaretDate(1, month, year, 0, 0, 0));
22 if (beginIndex == -1) {
23 createMonthInternal(month, year);
24 }
25 }
26 /***
27 * Get the index for the given date or -1.
28 *
29 * @param jaretDate date
30 * @return index or -1
31 */
32 public int getIndexForDate(JaretDate jaretDate) {
33 for (int i = 0; i < _rows.size(); i++) {
34 Day day = (Day) _rows.get(i);
35 if (day.getDayDate().compareDateTo(jaretDate) == 0) {
36 return i;
37 }
38 }
39 return -1;
40 }
41
42 /***
43 * Create empty days for the given month. The method assumes that the existing days are present without gaps.
44 *
45 * @param month month
46 * @param year year
47 */
48 private void createMonthInternal(int month, int year) {
49 if (_rows.size() == 0
50 || ((Day) _rows.get(_rows.size() - 1)).getDayDate().compareDateTo(
51 new JaretDate(1, month, year, 0, 0, 0)) < 0) {
52
53 JaretDate date = new JaretDate(1, month, year, 0, 0, 0);
54 while (date.getMonth() == month) {
55 Day day = new Day(date);
56 addRow(day);
57 date = date.copy().advanceDays(1);
58 }
59 } else {
60
61 JaretDate date = new JaretDate(1, month, year, 0, 0, 0);
62 int index = 0;
63 while (date.getMonth() == month) {
64 Day day = new Day(date);
65 addRow(index++, day);
66 date = date.copy().advanceDays(1);
67 }
68 }
69 }
70
71 /***
72 * Retrieve the day for a given date.
73 *
74 * @param date date of the day
75 * @return the day or <code>null</code> if none could be found
76 */
77 public Day getDay(JaretDate date) {
78 for (TimeBarRow row : _rows) {
79 Day day = (Day) row;
80 if (day.getDayDate().compareDateTo(date) == 0) {
81 return day;
82 }
83 }
84 return null;
85 }
86
87 /***
88 * Retrieve the day for an index (simple cast from getRow).
89 *
90 * @param idx index
91 * @return day
92 */
93 public Day getDay(int idx) {
94 return (Day) getRow(idx);
95 }
96
97
98 /***
99 * {@inheritDoc} Adds handling of the placeholder creation.
100 */
101 protected void fireElementAdded(TimeBarRow row, Interval interval) {
102 Appointment app = (Appointment) interval;
103 deletePlaceholders(app);
104 if (app.isSpansMultipleDays()) {
105 Day day = (Day) row;
106 int idx = getIndexForRow(day);
107 createOrUpdatePlaceholders(idx, app);
108 }
109
110 super.fireElementAdded(row, interval);
111 }
112
113 /***
114 * {@inheritDoc} Adds handling of the placeholder handling and checks whether an appointment is still registered
115 * with the right day (row) of the model.
116 */
117 protected void fireElementChanged(TimeBarRow row, Interval interval) {
118 Appointment app = (Appointment) interval;
119
120 Day day = (Day) checkDayOfAppointment((Appointment) interval, (Day) row);
121 deletePlaceholders(app);
122 if (app.isSpansMultipleDays()) {
123 int idx = getIndexForRow(day);
124 createOrUpdatePlaceholders(idx, app);
125 }
126
127 super.fireElementChanged(row, interval);
128 }
129
130 /***
131 * Check and possibly correct the day for an appointment.
132 *
133 * @param appointment appointment to check
134 * @param day the current day
135 * @return the new day
136 */
137 private Day checkDayOfAppointment(Appointment appointment, Day day) {
138 if (day.getDayDate().compareDateTo(appointment.getRealBegin()) == 0) {
139 return day;
140 }
141 day.remInterval(appointment);
142 Day newDay = getDay(appointment.getRealBegin());
143 newDay.addInterval(appointment);
144 return newDay;
145 }
146
147 /***
148 * {@inheritDoc} Adds handling of the placeholder deletion for the removed interval.
149 */
150 protected void fireElementRemoved(TimeBarRow row, Interval interval) {
151 Appointment app = (Appointment) interval;
152 deletePlaceholders(app);
153 super.fireElementRemoved(row, interval);
154 }
155
156 /***
157 * Remove all placeholders in the model for a given appointment.
158 *
159 * @param app appointment
160 */
161 private void deletePlaceholders(Appointment app) {
162 for (int i = 0; i < getRowCount(); i++) {
163 getDay(i).removePlaceholder(app);
164 }
165 }
166
167 /***
168 * Create or update placeholder objects for an appointment on several days.
169 *
170 * @param startDayIdx index of
171 * @param appointment
172 */
173 private void createOrUpdatePlaceholders(int startDayIdx, Appointment appointment) {
174 int idx = startDayIdx;
175 Day day = getDay(idx);
176 List<AppointmentPlaceholder> placeholders = new ArrayList<AppointmentPlaceholder>();
177 int maxPos = -1;
178 while (day.getDayDate().compareDateTo(appointment.getRealEnd()) <= 0) {
179
180
181 if (!(day.getDayDate().compareDateTo(appointment.getRealEnd()) == 0 && appointment.isWholeDayAppointment())) {
182 AppointmentPlaceholder ph = day.getPlaceholder(appointment);
183 if (ph == null) {
184 ph = new AppointmentPlaceholder(day, appointment);
185 }
186 placeholders.add(ph);
187 day.getPlaceholders().add(ph);
188
189 if (day.getMaxPlaceholderPos() > maxPos) {
190 maxPos = day.getMaxPlaceholderPos();
191 }
192 }
193 idx++;
194 day = getDay(idx);
195 }
196
197 for (AppointmentPlaceholder appointmentPlaceholder : placeholders) {
198 appointmentPlaceholder.setPosition(maxPos + 1);
199 }
200 }
201
202
203
204 }