protected Span _nextSpan(PointerType pointer) {
int halfDay = RepeaterDay.DAY_SECONDS / 2;
int fullDay = RepeaterDay.DAY_SECONDS;
Calendar now = getNow();
Tick tick = getType();
boolean first = false;
if (_currentTime == null) {
first = true;
Calendar midnight = Time.ymd(now);
Calendar yesterdayMidnight = Time.cloneAndAdd(midnight, Calendar.SECOND, -fullDay);
Calendar tomorrowMidnight = Time.cloneAndAdd(midnight, Calendar.SECOND, fullDay);
int offsetFix = (midnight.get(Calendar.ZONE_OFFSET) - tomorrowMidnight.get(Calendar.ZONE_OFFSET)) / 1000;
tomorrowMidnight.add(Calendar.SECOND, offsetFix);
boolean done = false;
if (pointer == Pointer.PointerType.FUTURE) {
if (tick.isAmbiguous()) {
List<Calendar> futureDates = new LinkedList<Calendar>();
futureDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, tick.intValue() + offsetFix));
futureDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, halfDay + tick.intValue() + offsetFix));
futureDates.add(Time.cloneAndAdd(tomorrowMidnight, Calendar.SECOND, tick.intValue()));
for (Calendar futureDate : futureDates) {
if (futureDate.after(now) || futureDate.equals(now)) {
_currentTime = futureDate;
done = true;
break;
}
}
}
else {
List<Calendar> futureDates = new LinkedList<Calendar>();
futureDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, tick.intValue() + offsetFix));
futureDates.add(Time.cloneAndAdd(tomorrowMidnight, Calendar.SECOND, tick.intValue()));
for (Calendar futureDate : futureDates) {
if (futureDate.after(now) || futureDate.equals(now)) {
_currentTime = futureDate;
done = true;
break;
}
}
}
}
else {
if (tick.isAmbiguous()) {
List<Calendar> pastDates = new LinkedList<Calendar>();
pastDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, halfDay + tick.intValue() + offsetFix));
pastDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, tick.intValue() + offsetFix));
pastDates.add(Time.cloneAndAdd(yesterdayMidnight, Calendar.SECOND, tick.intValue() + halfDay));
for (Calendar pastDate : pastDates) {
if (pastDate.before(now) || pastDate.equals(now)) {
_currentTime = pastDate;
done = true;
break;
}
}
}
else {
List<Calendar> pastDates = new LinkedList<Calendar>();
pastDates.add(Time.cloneAndAdd(midnight, Calendar.SECOND, tick.intValue() + offsetFix));
pastDates.add(Time.cloneAndAdd(yesterdayMidnight, Calendar.SECOND, tick.intValue()));
for (Calendar pastDate : pastDates) {
if (pastDate.before(now) || pastDate.equals(now)) {
_currentTime = pastDate;
done = true;
break;
}
}
}
}
if (!done && _currentTime == null) {
throw new IllegalStateException("Current time cannot be null at this point.");
}
}
if (!first) {
int increment = (tick.isAmbiguous()) ? halfDay : fullDay;
int direction = (pointer == Pointer.PointerType.FUTURE) ? 1 : -1;
_currentTime.add(Calendar.SECOND, direction * increment);
}
return new Span(_currentTime, Time.cloneAndAdd(_currentTime, Calendar.SECOND, getWidth()));