package jfxtras.scene.control.agenda.icalendar.trial.controller;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
import java.util.Locale;
import java.util.ResourceBundle;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import jfxtras.icalendarfx.VCalendar;
import jfxtras.icalendarfx.components.VEvent;
import jfxtras.icalendarfx.properties.component.descriptive.Summary;
import jfxtras.icalendarfx.properties.component.recurrence.rrule.FrequencyType;
import jfxtras.icalendarfx.properties.component.recurrence.rrule.RecurrenceRuleValue;
import jfxtras.icalendarfx.properties.component.recurrence.rrule.byxxx.ByDay;
import jfxtras.icalendarfx.utilities.DateTimeUtilities;
import jfxtras.internal.scene.control.skin.agenda.AgendaDaySkin;
import jfxtras.internal.scene.control.skin.agenda.AgendaWeekSkin;
import jfxtras.scene.control.LocalDatePicker;
import jfxtras.scene.control.agenda.Agenda;
import jfxtras.scene.control.agenda.Agenda.LocalDateTimeRange;
import jfxtras.scene.control.agenda.icalendar.ICalendarAgenda;
import jfxtras.scene.control.agenda.icalendar.agenda.AgendaTestAbstract;
/**
* @author David Bal
*
* Instantiates and setups the Agenda.
* Contains listeners to write changes due to calendar interaction. Properties are in Agenda class.
*/
public class CalendarController
{
VCalendar vCalendar = new VCalendar();
public ICalendarAgenda agenda = new ICalendarAgenda(vCalendar);
@FXML private ResourceBundle resources; // ResourceBundle that was given to the FXMLLoader
@FXML private BorderPane agendaBorderPane;
final ToggleGroup skinGroup = new ToggleGroup();
@FXML private Label dateLabel;
@FXML private ToggleButton daySkinButton;
@FXML private ToggleButton weekSkinButton;
@FXML private ToggleButton monthSkinButton;
@FXML private ToggleButton agendaSkinButton;
final private LocalDatePicker localDatePicker = new LocalDatePicker(LocalDate.now());
public final ObjectProperty<LocalDate> selectedLocalDateProperty = new SimpleObjectProperty<LocalDate>();
public final ObjectProperty<LocalDateTime> selectedLocalDateTimeProperty = new SimpleObjectProperty<LocalDateTime>(LocalDateTime.now());
private Period shiftDuration = Period.ofWeeks(1);
public final TemporalField dayOfWeekField = WeekFields.of(Locale.getDefault()).dayOfWeek();
boolean editDone = false;
@FXML public void initialize()
{
daySkinButton.setToggleGroup(skinGroup);
weekSkinButton.setToggleGroup(skinGroup);
monthSkinButton.setToggleGroup(skinGroup);
agendaSkinButton.setToggleGroup(skinGroup);
weekSkinButton.selectedProperty().set(true);
// agenda.setOneAllThisAndFutureDialogCallback(EditChoiceDialog.EDIT_DIALOG_CALLBACK);
// accept new appointments
agenda.setNewAppointmentCallback((LocalDateTimeRange dateTimeRange) ->
{
Temporal s = dateTimeRange.getStartLocalDateTime().atZone(ZoneId.systemDefault());
Temporal e = dateTimeRange.getEndLocalDateTime().atZone(ZoneId.systemDefault());
return new Agenda.AppointmentImplTemporal()
.withStartTemporal(s)
.withEndTemporal(e)
.withSummary("New")
.withDescription("")
.withAppointmentGroup(agenda.appointmentGroups().get(0));
});
agendaBorderPane.setCenter(agenda);
dateLabel.textProperty().bind(makeLocalDateBindings(localDatePicker.localDateProperty()));
localDatePicker.setPadding(new Insets(20, 0, 5, 0)); //(top/right/bottom/left)
agendaBorderPane.setLeft(localDatePicker);
localDatePicker.localDateProperty().addListener((observable, oldSelection, newSelection)
-> {
if (newSelection != null) agenda.setDisplayedLocalDateTime(newSelection.atStartOfDay());
});
// Enable month and year changing to move calendar
localDatePicker.displayedLocalDateProperty().addListener((observable, oldSelection, newSelection)
-> {
int dayOfMonth = localDatePicker.getLocalDate().getDayOfMonth();
localDatePicker.setLocalDate(newSelection.withDayOfMonth(dayOfMonth));
});
agenda.setPadding(new Insets(0, 0, 0, 5)); //(top/right/bottom/left)
}
public void setupData(LocalDate startDate, LocalDate endDate)
{
VEvent vEventSplit = new VEvent()
.withDateTimeEnd(LocalDateTime.of(endDate, LocalTime.of(5, 45)))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 11, 10, 8, 0), ZoneOffset.UTC))
.withDateTimeStart(LocalDateTime.of(endDate.minusDays(1), LocalTime.of(15, 45)))
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(8).getDescription())
.withDescription("Split Description")
.withSummary(Summary.parse("Split"))
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withUniqueIdentifier("20150110T080000-00@jfxtras.org");
agenda.getVCalendar().addChild(vEventSplit);
VEvent vEventZonedUntil = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(10).getDescription())
.withDateTimeEnd(ZonedDateTime.of(LocalDateTime.of(startDate.plusDays(1), LocalTime.of(9, 45)), ZoneId.of("America/Los_Angeles")))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 11, 10, 8, 0), ZoneOffset.UTC))
.withDateTimeStart(ZonedDateTime.of(LocalDateTime.of(startDate.plusDays(1), LocalTime.of(8, 15)), ZoneId.of("America/Los_Angeles")))
.withDescription("WeeklyZoned Description")
.withRecurrenceRule(new RecurrenceRuleValue()
.withUntil(ZonedDateTime.of(LocalDateTime.of(startDate.plusDays(15), LocalTime.of(8, 15)), ZoneId.of("America/Los_Angeles")).withZoneSameInstant(ZoneId.of("Z")))
.withFrequency(FrequencyType.WEEKLY)
.withByRules(new ByDay(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.FRIDAY)))
.withSummary(Summary.parse("WeeklyZoned Ends"))
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withUniqueIdentifier("20150110T080000-01@jfxtras.org");
agenda.getVCalendar().addChild(vEventZonedUntil);
VEvent vEventZonedInfinite = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(3).getDescription())
.withDateTimeEnd(ZonedDateTime.of(LocalDateTime.of(startDate.plusDays(1), LocalTime.of(12, 00)), ZoneId.of("America/Los_Angeles")))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 11, 10, 8, 0), ZoneOffset.UTC))
.withDateTimeStart(ZonedDateTime.of(LocalDateTime.of(startDate.plusDays(1), LocalTime.of(7, 30)), ZoneId.of("America/Los_Angeles")))
.withDescription("WeeklyZoned Description")
.withRecurrenceRule(new RecurrenceRuleValue()
.withFrequency(FrequencyType.WEEKLY)
.withByRules(new ByDay(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.FRIDAY)))
.withSummary(Summary.parse("WeeklyZoned Infinite"))
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withUniqueIdentifier("20150110T080000-02@jfxtras.org");
agenda.getVCalendar().addChild(vEventZonedInfinite);
VEvent vEventLocalDate = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(15).getDescription())
.withDateTimeStart(startDate)
.withDateTimeEnd(startDate.plusDays(1))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 1, 10, 8, 0), ZoneOffset.UTC))
.withDescription("LocalDate Description")
.withSummary(Summary.parse("LocalDate"))
.withUniqueIdentifier("20150110T080000-3@jfxtras.org")
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withRecurrenceRule(new RecurrenceRuleValue()
.withFrequency(FrequencyType.WEEKLY)
.withInterval(3));
agenda.getVCalendar().addChild(vEventLocalDate);
VEvent vEventLocalDateTime = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(2).getDescription())
.withDateTimeStart(LocalDateTime.of(startDate, LocalTime.of(11, 00)))
.withDateTimeEnd(LocalDateTime.of(startDate, LocalTime.of(13, 0)))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 1, 10, 8, 0), ZoneOffset.UTC))
.withDescription("LocalDateTime Daily Description")
.withSummary(Summary.parse("LocalDateTime Daily"))
.withUniqueIdentifier("20150110T080000-4@jfxtras.org")
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withRecurrenceRule(new RecurrenceRuleValue()
.withFrequency(FrequencyType.DAILY));
agenda.getVCalendar().addChild(vEventLocalDateTime);
VEvent vEventLocalDateTimeMonthly = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(17).getDescription())
.withDateTimeStart(LocalDateTime.of(startDate, LocalTime.of(14, 00)))
.withDateTimeEnd(LocalDateTime.of(startDate, LocalTime.of(15, 0)))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 1, 10, 8, 0), ZoneOffset.UTC))
.withDescription("Monthly Description")
.withSummary(Summary.parse("Monthly"))
.withUniqueIdentifier("20150110T080000-5@jfxtras.org")
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withRecurrenceRule(new RecurrenceRuleValue()
.withFrequency(FrequencyType.MONTHLY));
agenda.getVCalendar().addChild(vEventLocalDateTimeMonthly);
DayOfWeek dayOfWeek = DayOfWeek.from(startDate.plusDays(2));
int ordinalWeekNumber = DateTimeUtilities.weekOrdinalInMonth(startDate.plusDays(2));
VEvent vEventLocalDateMonthlyOrdinal = new VEvent()
.withCategories(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS.get(5).getDescription())
.withDateTimeStart(startDate.plusDays(2))
.withDateTimeEnd(startDate.plusDays(3))
.withDateTimeStamp(ZonedDateTime.of(LocalDateTime.of(2015, 1, 10, 8, 0), ZoneOffset.UTC))
.withDescription("Monthly Ordinal Description " + dayOfWeek + "#" + ordinalWeekNumber + " in month")
.withSummary(Summary.parse("Monthly Ordinal"))
.withUniqueIdentifier("20150110T080000-6@jfxtras.org")
.withOrganizer("ORGANIZER;CN=Issac Newton:mailto:isaac@greatscientists.org")
.withRecurrenceRule(new RecurrenceRuleValue()
.withFrequency(FrequencyType.MONTHLY)
.withByRules(new ByDay(new ByDay.ByDayPair(dayOfWeek, ordinalWeekNumber))));
agenda.getVCalendar().addChild(vEventLocalDateMonthlyOrdinal);
// replace Agenda's appointmentGroups with the ones used in the test events.
agenda.appointmentGroups().clear();
agenda.appointmentGroups().addAll(AgendaTestAbstract.DEFAULT_APPOINTMENT_GROUPS);
agenda.updateAppointments();
}
@FXML private void handleToday()
{
LocalDate today = LocalDate.now();
localDatePicker.localDateProperty().set(today);
}
@FXML private void handleDateIncrement() {
LocalDate oldLocalDate = localDatePicker.getLocalDate();
localDatePicker.localDateProperty().set(oldLocalDate.plus(shiftDuration));
}
@FXML private void handleDateDecrement() {
LocalDate oldLocalDate = localDatePicker.getLocalDate();
localDatePicker.localDateProperty().set(oldLocalDate.minus(shiftDuration));
}
@FXML private void handleWeekSkin() {
shiftDuration = Period.ofWeeks(1);
agenda.setSkin(new AgendaWeekSkin(agenda));
}
@FXML private void handleDaySkin() {
shiftDuration = Period.ofDays(1);
agenda.setSkin(new AgendaDaySkin(agenda));
}
public static StringBinding makeLocalDateBindings(ObjectProperty<LocalDate> p)
{
final DateTimeFormatter DATE_FORMAT2 = DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy");
return Bindings.createStringBinding(() -> DATE_FORMAT2.format(p.get()), p);
}
}