import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.smartgwt.client.types.TimeUnit;
import com.smartgwt.client.widgets.calendar.CalendarEvent;
import com.smartgwt.client.widgets.calendar.CalendarView;
import com.smartgwt.client.widgets.calendar.HeaderLevel;
import com.smartgwt.client.widgets.calendar.Lane;
import com.smartgwt.client.widgets.calendar.ShowDateCustomizer;
import com.smartgwt.client.widgets.calendar.Timeline;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.layout.VLayout;

public class Test implements EntryPoint {
    private int eventId = 0;
    
    @Override
    public void onModuleLoad() {
        // demo shows date August 29th 2019
        Date periodStart = new Date(119, 7, 29);
        Date periodEnd = new Date(119, 7, 29, 23, 59, 59);
        
        VLayout body = new VLayout(10);
        body.setWidth100();
        body.setMembers(build30MinuteBasedTimeline(periodStart, periodEnd), build3HourBasedTimeline(periodStart, periodEnd));
        body.draw();
    }
    
    private Timeline build30MinuteBasedTimeline(Date periodStart, Date periodEnd) {
        Timeline timeline = createTimeline(periodStart, periodEnd);
        timeline.setEventSnapGap(1); // Note: This triggers a warning: Cannot change configuration property 'eventSnapGap' to 1 now that component isc_Timeline_0 has been created.
        
        // display the whole day as blocks of 30 minutes
        timeline.setResolution(new HeaderLevel[] {
                new HeaderLevel(TimeUnit.DAY),
                new HeaderLevel(TimeUnit.MINUTE)
        }, TimeUnit.MINUTE, 24 * 60 - 1, 30);
        
        timeline.setLanes(new Lane("lane1", "Lane 1"), new Lane("lane2", "Lane 2"));
        timeline.setData(buildData());
        return timeline;
    }
    
    private Timeline build3HourBasedTimeline(Date periodStart, Date periodEnd) {
        Timeline timeline = createTimeline(periodStart, periodEnd);
        timeline.setEventSnapGap(3); // Note: This triggers a warning: Cannot change configuration property 'eventSnapGap' to 3 now that component isc_Timeline_1 has been created.
        
        // display the whole day as blocks of 30 minutes
        timeline.setResolution(new HeaderLevel[] {
                new HeaderLevel(TimeUnit.DAY),
                new HeaderLevel(TimeUnit.MINUTE)
        }, TimeUnit.MINUTE, 24 * 60 - 1, 180);
        
        timeline.setLanes(new Lane("lane1", "Lane 1"), new Lane("lane2", "Lane 2"));
        timeline.setData(buildData());
        return timeline;
    }

    
    private CalendarEvent[] buildData() {
        // lane 1 has more realistic events, lane 2 has only events that start and end in minute 0 or 30, to illustrate the difference in behavior of the timeline 
        return new CalendarEvent[] {
                createEvent("event 1", "lane1", 10, 20, 12, 20),
                createEvent("event 2", "lane1", 12, 20, 15, 33),
                createEvent("event 3", "lane1", 15, 33, 17, 8),
                createEvent("event 4", "lane2", 10, 30, 12, 30),
                createEvent("event 5", "lane2", 12, 30, 15, 0),
                createEvent("event 6", "lane2", 15, 0, 17, 30)
        };
    }
    
    private Timeline createTimeline(Date startDate, Date endDate) {
        Timeline timeline = new Timeline();
        timeline.setHeight(250);
        timeline.setShowEventDescriptions(false);
        timeline.setSizeEventsToGrid(false);
        timeline.setShowLaneRollOver(true);
        timeline.setShowTimelineView(true);
        timeline.setAlternateLaneStyles(true);
        timeline.setShowControlsBar(false);
        timeline.setShowAddEventButton(false);
        timeline.setShowDatePickerButton(false);
        timeline.setShowDateChooser(false); // would be nice to enable this with only the selected period (for data) available
        timeline.setShowDateCustomizer(new ShowDateCustomizer() {
            
            @Override
            public boolean shouldShowDate(Date date, CalendarView calendarView) {
                return date.equals(startDate) || date.equals(endDate) || date.after(startDate) && date.before(endDate);
            }
        });
        timeline.setSnapVDirection("nearest");
        timeline.setLaneFields(new ListGridField[] { new ListGridField("title", "My Lanes", 100) });
        timeline.setShowZones(true);
        timeline.setShowIndicators(true);
        timeline.setTimelineRange(startDate, endDate);
        
        return timeline;
    }
    
    private CalendarEvent createEvent(String name, String lane, int startHours, int startMinutes, int endHours, int endMinutes) {
        // this secondsParameter is not representing real data, but only used for illustration of how changing the seconds affects the timeline behavior.
        // when this parameter is set to 0, lane2 displays correctly in the 30-minute based grid; the overlap disappears
        int secondsParameter = 13;
        
        CalendarEvent event = new CalendarEvent(++eventId, name, name, new Date(119, 7, 29, startHours, startMinutes, secondsParameter), new Date(119, 7, 29, endHours, endMinutes, secondsParameter), lane);
        event.setCanEdit(false);
        return event;
    }
}