package com.giftoftheembalmer.gotefarm.client; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Hyperlink; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.RadioButton; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.datepicker.client.DateBox; import java.util.Date; import java.util.List; public class ScheduleEditor extends Composite { Admin admin; static int last_group_num = 0; class Schedule extends Composite implements ClickHandler, ValueChangeHandler<Date> { JSEventSchedule sched; // append a distinct number to radio button group names, per schedule, // so multiple schedules' radio buttons don't end up in the same group final int radio_group_num = last_group_num++; final String REPEAT_GROUP = "repeatGroup_" + radio_group_num; final String DAYOF_GROUP = "dayofGroup_" + radio_group_num; VerticalPanel vpanel = new VerticalPanel(); final DateBox db; final TimePicker tp; final DurationPicker display_start = new DurationPicker(); final DurationPicker display_end = new DurationPicker(); final DurationPicker signups_start = new DurationPicker(); final DurationPicker signups_end = new DurationPicker(); final Label display_start_time = new Label(); final Label display_end_time = new Label(); final Label signups_start_time = new Label(); final Label signups_end_time = new Label(); final DateTimeFormat time_formatter = DateTimeFormat.getShortDateTimeFormat(); final RadioButton rptnever = new RadioButton(REPEAT_GROUP, "Never"); final RadioButton rptdaily = new RadioButton(REPEAT_GROUP, "Daily"); final RadioButton rptweekly = new RadioButton(REPEAT_GROUP, "Weekly"); final RadioButton rptmonthly = new RadioButton(REPEAT_GROUP, "Monthly"); final VerticalPanel dailyrptpanel = new VerticalPanel(); final VerticalPanel weeklyrptpanel = new VerticalPanel(); final VerticalPanel monthlyrptpanel = new VerticalPanel(); final ListBox dailyrptdays = new ListBox(); final Label dailyrptdaylabel = new Label("day"); final ListBox weeklyrptweeks = new ListBox(); final Label weeklyrptweeklabel = new Label("week"); final CheckBox[] weeklydays = { new CheckBox("Sun"), new CheckBox("Mon"), new CheckBox("Tue"), new CheckBox("Wed"), new CheckBox("Thu"), new CheckBox("Fri"), new CheckBox("Sat") }; final ListBox monthlyrptmonth = new ListBox(); final Label monthlyrptmonthlabel = new Label("month"); final RadioButton rptdayofmonth = new RadioButton(DAYOF_GROUP, "day of the month"); final RadioButton rptdayofweek = new RadioButton(DAYOF_GROUP, "day of the week"); class DurationChangeHandler implements ValueChangeHandler<Integer> { public void onValueChange(ValueChangeEvent<Integer> event) { final Object sender = event.getSource(); if (sched == null) return; if (sender == display_start) { sched.display_start = display_start.getValue(); } else if (sender == display_end) { sched.display_end = display_end.getValue(); } else if (sender == signups_start) { sched.signups_start = signups_start.getValue(); } else if (sender == signups_end) { sched.signups_end = signups_end.getValue(); } updateTimes(); } } final DurationChangeHandler dch = new DurationChangeHandler(); @SuppressWarnings("deprecation") public Schedule(String eventKey, JSEventSchedule sched) { this.sched = sched; if (this.sched == null) { this.sched = sched = new JSEventSchedule(); sched.event_schedule_key = null; sched.event_template_key = eventKey; sched.start_time = new Date(); sched.start_time.setTime( sched.start_time.getTime() - (sched.start_time.getTime() % 3600000) ); sched.orig_start_time = sched.start_time; sched.duration = 120 * 60; sched.display_start = 7 * 86400; sched.display_end = 3600; sched.signups_start = 2 * 86400; sched.signups_end = 1800; sched.repeat_size = JSEventSchedule.REPEAT_NEVER; sched.repeat_freq = 1; sched.day_mask = 1 << sched.start_time.getDay(); sched.repeat_by = JSEventSchedule.REPEAT_BY_DAY_OF_MONTH; sched.active = true; } vpanel.setWidth("100%"); db = new DateBox(); db.setValue(sched.start_time); db.setFormat( new DateBox.DefaultFormat(DateTimeFormat.getShortDateFormat()) ); db.addValueChangeHandler(this); tp = new TimePicker(sched.start_time); tp.addValueChangeHandler(this); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); hpanel.add(new Label("Start Date:")); hpanel.add(db); hpanel.add(new HTML("  ")); hpanel.add(new Label("Start Time:")); hpanel.add(tp); vpanel.add(hpanel); } display_start.addValueChangeHandler(dch); display_start.setVisibleLength(6); display_start.setValue(sched.display_start); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); hpanel.setSpacing(5); hpanel.add(new Label("Display event ")); hpanel.add(display_start); hpanel.add(new Label(" before start time: ")); hpanel.add(display_start_time); vpanel.add(hpanel); } display_end.addValueChangeHandler(dch); display_end.setVisibleLength(6); display_end.setValue(sched.display_end); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); hpanel.setSpacing(5); hpanel.add(new Label("Remove event ")); hpanel.add(display_end); hpanel.add(new Label(" after start time: ")); hpanel.add(display_end_time); vpanel.add(hpanel); } signups_start.addValueChangeHandler(dch); signups_start.setVisibleLength(6); signups_start.setValue(sched.signups_start); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); hpanel.setSpacing(5); hpanel.add(new Label("Signups open ")); hpanel.add(signups_start); hpanel.add(new Label(" before start time: ")); hpanel.add(signups_start_time); vpanel.add(hpanel); } signups_end.addValueChangeHandler(dch); signups_end.setVisibleLength(6); signups_end.setValue(sched.signups_end); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); hpanel.setSpacing(5); hpanel.add(new Label("Signups end ")); hpanel.add(signups_end); hpanel.add(new Label(" before start time: ")); hpanel.add(signups_end_time); vpanel.add(hpanel); } { HorizontalPanel rptpanel = new HorizontalPanel(); rptpanel.add(new Label("Repeat event")); rptpanel.add(rptnever); rptpanel.add(rptdaily); rptpanel.add(rptweekly); rptpanel.add(rptmonthly); rptnever.addClickHandler(this); rptdaily.addClickHandler(this); rptweekly.addClickHandler(this); rptmonthly.addClickHandler(this); vpanel.add(rptpanel); } dailyrptpanel.setVisible(false); weeklyrptpanel.setVisible(false); monthlyrptpanel.setVisible(false); { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add(new Label("Repeat every")); for (int i = 1; i < 31; ++i) { dailyrptdays.addItem("" + i); } dailyrptdays.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { final int index = dailyrptdays.getSelectedIndex(); Schedule.this.sched.repeat_freq = index + 1; if (index > 0) { dailyrptdaylabel.setText("days"); } else { dailyrptdaylabel.setText("day"); } } }); dailyrptdays.setSelectedIndex(sched.repeat_freq - 1); hpanel.add(dailyrptdays); hpanel.add(dailyrptdaylabel); dailyrptpanel.add(hpanel); vpanel.add(dailyrptpanel); } { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add(new Label("Repeat every")); for (int i = 1; i < 31; ++i) { weeklyrptweeks.addItem("" + i); } weeklyrptweeks.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { final int index = weeklyrptweeks.getSelectedIndex(); Schedule.this.sched.repeat_freq = index + 1; if (index > 0) { weeklyrptweeklabel.setText("weeks"); } else { weeklyrptweeklabel.setText("week"); } } }); weeklyrptweeks.setSelectedIndex(sched.repeat_freq - 1); hpanel.add(weeklyrptweeks); hpanel.add(weeklyrptweeklabel); weeklyrptpanel.add(hpanel); } { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add(new Label("Repeat on")); final ValueChangeHandler<Boolean> daychanged = new ValueChangeHandler<Boolean>() { public void onValueChange(ValueChangeEvent<Boolean> event) { final Object sender = event.getSource(); final boolean checked = event.getValue(); for (int i = 0; i < 7; ++i ) { if (sender == weeklydays[i]) { if (checked) { Schedule.this.sched.day_mask |= (1 << i); } else { Schedule.this.sched.day_mask &= ~(1 << i); } break; } } } }; for (int i = 0; i < 7; ++i ) { weeklydays[i].addStyleName("padleft"); if ((sched.day_mask & (1 << i)) > 0) { weeklydays[i].setValue(true); } weeklydays[i].addValueChangeHandler(daychanged); hpanel.add(weeklydays[i]); } weeklyrptpanel.add(hpanel); vpanel.add(weeklyrptpanel); } { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add(new Label("Repeat every")); for (int i = 1; i < 31; ++i) { monthlyrptmonth.addItem("" + i); } monthlyrptmonth.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { final int index = monthlyrptmonth.getSelectedIndex(); Schedule.this.sched.repeat_freq = index + 1; if (index > 0) { monthlyrptmonthlabel.setText("months"); } else { monthlyrptmonthlabel.setText("month"); } } }); monthlyrptmonth.setSelectedIndex(sched.repeat_freq - 1); hpanel.add(monthlyrptmonth); hpanel.add(monthlyrptmonthlabel); monthlyrptpanel.add(hpanel); } { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.add(new Label("Repeat by")); final ValueChangeHandler<Boolean> rptdayofchanged = new ValueChangeHandler<Boolean>() { public void onValueChange(ValueChangeEvent<Boolean> event) { final Object sender = event.getSource(); if (sender == rptdayofmonth && event.getValue()) { Schedule.this.sched.repeat_by = JSEventSchedule.REPEAT_BY_DAY_OF_MONTH; } else if (sender == rptdayofweek && event.getValue()) { Schedule.this.sched.repeat_by = JSEventSchedule.REPEAT_BY_DAY_OF_WEEK; } } }; if (sched.repeat_by == JSEventSchedule.REPEAT_BY_DAY_OF_MONTH) { rptdayofmonth.setValue(true); } else { rptdayofweek.setValue(true); } rptdayofmonth.addValueChangeHandler(rptdayofchanged); rptdayofweek.addValueChangeHandler(rptdayofchanged); hpanel.add(rptdayofmonth); hpanel.add(rptdayofweek); monthlyrptpanel.add(hpanel); vpanel.add(monthlyrptpanel); } updateTimes(); switch (sched.repeat_size) { case JSEventSchedule.REPEAT_NEVER: rptnever.setValue(true); break; case JSEventSchedule.REPEAT_DAILY: rptdaily.setValue(true); onClick(rptdaily); break; case JSEventSchedule.REPEAT_WEEKLY: rptweekly.setValue(true); onClick(rptweekly); break; case JSEventSchedule.REPEAT_MONTHLY: rptmonthly.setValue(true); onClick(rptmonthly); break; } HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setWidth("100%"); final Label errmsg = new Label(); errmsg.addStyleName(errmsg.getStylePrimaryName() + "-bottom"); Button save = new Button("Save", new ClickHandler() { public void onClick(ClickEvent event) { // clear error message errmsg.setText(""); // clone start_time into orig_start_time Schedule.this.sched.orig_start_time = Schedule.this.sched.start_time; GoteFarm.goteService.saveEventSchedule( admin.current_guild.key, Schedule.this.sched, new AsyncCallback<Void>() { public void onSuccess(Void v) { errmsg.removeStyleName(errmsg.getStylePrimaryName() + "-error"); errmsg.setText("Schedule saved successfully."); admin.fireAdminChange(AdminChange.getEventsChanged()); } public void onFailure(Throwable caught) { errmsg.addStyleName(errmsg.getStylePrimaryName() + "-error"); errmsg.setText(caught.getMessage()); } }); } }); save.addStyleName(save.getStylePrimaryName() + "-bottom"); save.addStyleName(save.getStylePrimaryName() + "-left"); hpanel.add(save); hpanel.add(errmsg); vpanel.add(hpanel); initWidget(vpanel); setStyleName("Admin-Schedule"); } public Schedule(String eventKey) { this(eventKey, null); } private void updateTimes() { Date d = new Date(); d.setTime(sched.start_time.getTime() - display_start.getValue() * 1000); display_start_time.setText(time_formatter.format(d)); d.setTime(sched.start_time.getTime() + display_end.getValue() * 1000); display_end_time.setText(time_formatter.format(d)); d.setTime(sched.start_time.getTime() - signups_start.getValue() * 1000); signups_start_time.setText(time_formatter.format(d)); d.setTime(sched.start_time.getTime() - signups_end.getValue() * 1000); signups_end_time.setText(time_formatter.format(d)); } private void onClick(Object sender) { Widget toshow = null; int repeat_size = JSEventSchedule.REPEAT_NEVER; if (sender == rptdaily) { toshow = dailyrptpanel; repeat_size = JSEventSchedule.REPEAT_DAILY; } else if (sender == rptweekly) { toshow = weeklyrptpanel; repeat_size = JSEventSchedule.REPEAT_WEEKLY; } else if (sender == rptmonthly) { toshow = monthlyrptpanel; repeat_size = JSEventSchedule.REPEAT_MONTHLY; } dailyrptpanel.setVisible(toshow == dailyrptpanel); weeklyrptpanel.setVisible(toshow == weeklyrptpanel); monthlyrptpanel.setVisible(toshow == monthlyrptpanel); sched.repeat_size = repeat_size; } public void onClick(ClickEvent event) { final Object sender = event.getSource(); onClick(sender); } @SuppressWarnings("deprecation") public void onValueChange(ValueChangeEvent<Date> event) { final Object sender = event.getSource(); final Date d = event.getValue(); if (sender == db) { sched.start_time.setYear(d.getYear()); sched.start_time.setMonth(d.getMonth()); sched.start_time.setDate(d.getDate()); } else if (sender == tp) { sched.start_time.setHours(d.getHours()); sched.start_time.setMinutes(d.getMinutes()); sched.start_time.setSeconds(d.getSeconds()); } updateTimes(); } } VerticalPanel vpanel = new VerticalPanel(); public ScheduleEditor(final Admin admin, String eventKey, List<JSEventSchedule> schedules) { this.admin = admin; vpanel.setWidth("100%"); vpanel.setHeight("100%"); vpanel.setSpacing(40); if (admin.current_guild.time_zone == null) { HorizontalPanel hpanel = new HorizontalPanel(); hpanel.setSpacing(10); hpanel.add(new Label( "The guild time zone must be set before" + " creating schedules.")); hpanel.add(new Hyperlink("Manage guild", "guilds")); vpanel.add(hpanel); } else { for (JSEventSchedule s : schedules) { vpanel.add(new Schedule(eventKey, s)); } vpanel.add(new Schedule(eventKey)); } initWidget(vpanel); setStyleName("Admin-ScheduleEditor"); } }