package com.nuba;


import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceDateTimeField;
import com.smartgwt.client.data.fields.DataSourceSequenceField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.FetchMode;
import com.smartgwt.client.types.TimeUnit;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.calendar.*;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;

import java.util.Date;

public class TimelineResolutionSample implements EntryPoint {

    public Timeline timeline;

    public void onModuleLoad() {
        Canvas layout = createLayout();
        layout.draw();
    }

    public VLayout createLayout() {
        VLayout layout = new VLayout();
        layout.setWidth100();
        layout.setHeight100();
        layout.addMember(getToolStrip());
        layout.addMember(getTimelineDS());
        return layout;
    }

    public Timeline getTimelineDS () {
        HeaderLevel[] headerLevels = new HeaderLevel[]{
            new HeaderLevel(TimeUnit.WEEK),
            new HeaderLevel(TimeUnit.DAY)
        };
        timeline = new Timeline();
        timeline.setHeight(451);
        timeline.setStartDate(new Date(116, 5, 2));
        timeline.setEndDate(new Date(116, 5, 22));
        //timeline.setData(TimelineData.getRecords());
        //timeline.setLanes(TimelineLaneData.getRecords());
        timeline.setDataSource(createTimelineDS());
        timeline.setCanEditLane(true);
        timeline.setShowEventDescriptions(false);

        timeline.setHeaderLevels(headerLevels);
        timeline.setLaneFields(new ListGridField[]{ new ListGridField("title", "Developer", 120)});
        
        loadLanes(timeline, createLaneDS());
        return timeline;
    }

    private DataSource createTimelineDS(){
        DataSource eventDS = new DataSource();
        DataSourceSequenceField eventIdField = new DataSourceSequenceField("eventId");
        eventIdField.setPrimaryKey(true);

        DataSourceTextField nameField = new DataSourceTextField("name");
        DataSourceTextField descField = new DataSourceTextField("description");
        DataSourceDateTimeField startDateField = new DataSourceDateTimeField("startDate");
        DataSourceDateTimeField endDateField = new DataSourceDateTimeField("endDate");
        DataSourceTextField laneField = new DataSourceTextField("lane");

        eventDS.setFields(eventIdField, nameField, descField, startDateField, endDateField, laneField);
        eventDS.setClientOnly(true);
        eventDS.setTestData(TimelineData.getRecords());

        return eventDS;
    }

    private DataSource createLaneDS(){
        DataSource eventDS = new DataSource();
        DataSourceTextField nameField = new DataSourceTextField("name");
        nameField.setPrimaryKey(true);
        DataSourceTextField titleField = new DataSourceTextField("title");

        eventDS.setFields(nameField, titleField);
        eventDS.setClientOnly(true);
        eventDS.setTestData(TimelineLaneData.getRecords());

        return eventDS;
    }

    public void loadLanes(Timeline timeline, DataSource laneDS) {
        String laneNameField = "title";
        timeline.setLaneFields(new ListGridField("title", "User", 100));
        Criteria crit = new Criteria();
        laneDS.fetchData(crit, (dsResponse, o, dsRequest) -> {
            Record[] data = dsResponse.getData();
            GWT.log("got " + data.length + " lanes");
            Lane[] lanes = new Lane[dsResponse.getData().length];
            for (int i = 0; i < data.length; i++) {
                lanes[i] = new Lane(data[i].getAttribute("name"), data[i].getAttribute(laneNameField));
                lanes[i].setAttribute(laneNameField, data[i].getAttribute(laneNameField));
            }
            timeline.setLanes(lanes);
            timeline.fetchData();
        });
    }

    public Timeline getTimeline () {
        HeaderLevel[] headerLevels = new HeaderLevel[]{
            new HeaderLevel(TimeUnit.WEEK),
            new HeaderLevel(TimeUnit.DAY)
        };

        timeline = new Timeline();
        timeline.setDataFetchMode(FetchMode.PAGED);
        timeline.setHeight(451);
        timeline.setStartDate(new Date(116, 5, 2));
        timeline.setEndDate(new Date(116, 5, 22));
        timeline.setCanEditLane(true);
        timeline.setShowEventDescriptions(false);
        timeline.setEventSnapGap(60); // snap to 1 hour intervals
        timeline.setLaneEventPadding(2); // add a little space around events
        // set up the grid
        timeline.setHeaderLevels(headerLevels);
        timeline.setLanes(TimelineLaneData.getLanes());
        timeline.setLaneFields(new ListGridField("title", "Developer", 120));
        timeline.setData(TimelineData.getRecords());
        return timeline;
    }

    public ToolStrip getToolStrip() {
        ToolStrip toolStrip = new ToolStrip();
        toolStrip.addButton(
            getButton("minuteDay", "Minutes (12 hours, every 15 minute)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.HOUR), new HeaderLevel(TimeUnit.MINUTE) }, TimeUnit.HOUR, 12, 15
            )
        );
        toolStrip.addButton(
            getButton("hourDay", "Hours (1 day)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.DAY), new HeaderLevel(TimeUnit.HOUR) }, TimeUnit.HOUR, 24, null
            )
        );
        toolStrip.addButton(
            getButton("dayWeek", "Days (3 weeks)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.WEEK), new HeaderLevel(TimeUnit.DAY) }, TimeUnit.DAY, 21, null
            )
        );
        toolStrip.addButton(
            getButton("week6Month", "Weeks (6 months)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.MONTH), new HeaderLevel(TimeUnit.WEEK) }, TimeUnit.MONTH, 6, null
            )
        );
        toolStrip.addButton(
            getButton("monthYear", "Months (1 year)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.YEAR), new HeaderLevel(TimeUnit.MONTH) }, TimeUnit.MONTH, 12, null
            )
        );
        toolStrip.addButton(
            getButton("monthQuarterYear", "Months (2 years, with quarters)",
                new HeaderLevel[] { new HeaderLevel(TimeUnit.YEAR), new HeaderLevel(TimeUnit.QUARTER), new HeaderLevel(TimeUnit.MONTH) }, TimeUnit.MONTH, 24, null
            )
        );

        return toolStrip;
    }
    public ToolStripButton getButton(String ID, String title, final HeaderLevel[] headerLevels, final TimeUnit unit, final Integer columnCount, final Integer minutesPerColumn) {
        ToolStripButton button = new ToolStripButton(title);
        button.setID(ID);
        button.setAutoFit(true);
        button.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                timeline.setResolution(headerLevels, unit, columnCount, minutesPerColumn);
            }
        });
        return button;
    }

    public static class TimelineData {

        private static CalendarEvent[] records;
        private static Date today = new Date(116, 5, 2);
        private static int year = today.getYear();
        private static int month = today.getMonth();
        private static int start = today.getDate();

        public TimelineData() {
        }
        public static CalendarEvent[] getRecords() {
            if (records == null) {
                records = getNewRecords();
            }
            return records;
        }

        public static CalendarEvent[] getNewRecords() {
            return new CalendarEvent[]{
                new CalendarEvent(1, "Add new Timeline view", "Add a new calendar Timeline component", new Date(year, month, start + 2), new Date(year, month, start + 8, 23, 59, 59), "darcyFeeney"),
                new CalendarEvent(2, "ListGrid field autoSize", "Complex field-autosizing in ListGrid", new Date(year, month, start), new Date(year, month, start, 23, 59, 59), "kaiKong"),
                new CalendarEvent(3, "PDF Import/Export", "Implement native PDF import/export", new Date(year, month, start + 1), new Date(year, month, start + 5, 23, 59, 59), "garretMonroe"),
                new CalendarEvent(4, "Calculated Fields", "Formula and Summary fields for ListGrid", new Date(year, month, start), new Date(year, month, start + 4, 23, 59, 59), "charlesMadigen"),
                new CalendarEvent(5, "ListGrid cell-level selection", "Implement spreadsheet-like selection in ListGrid", new Date(year, month, start + 7), new Date(year, month, start + 14, 23, 59, 59), "charlesMadigen"),
                new CalendarEvent(6, "Text import", "Server text-import", new Date(year, month, start + 16), new Date(year, month, start + 20, 23, 59, 59), "charlesMadigen"),
                new CalendarEvent(7, "TabIndex enhancements", "Enhance formItem tabindex handling", new Date(year, month, start + 9), new Date(year, month, start + 11, 23, 59, 59), "kaiKong"),
                new CalendarEvent(8, "Reify skin", "Skinning changes", new Date(year, month, start), new Date(year, month, start + 3, 23, 59, 59), "shelleyFewel"),

                new CalendarEvent(9, "DataSource Transaction-handling", "New transaction features", new Date(year, month, start), new Date(year, month, start + 2, 23, 59, 59), "tamaraKane"),
                new CalendarEvent(10, "New Samples", "Add 20 samples for the following new features: ...", new Date(year, month, start + 4), new Date(year, month, start + 20, 23, 59, 59), "tamaraKane"),
                new CalendarEvent(11, "Localization", "Extend i18n support", new Date(year, month, start + 9), new Date(year, month, start + 14, 23, 59, 59), "darcyFeeney"),
                new CalendarEvent(12, "New Language Packs", "Add these 4 new language packs: ...", new Date(year, month, start + 16), new Date(year, month, start + 18, 23, 59, 59), "darcyFeeney"),

                new CalendarEvent(13, "ComponentXML", "Add the following features and update documentation: ...", new Date(year, month, start + 5), new Date(year, month, start + 11, 23, 59, 59), "shelleyFewel"),
                new CalendarEvent(14, "TileGrid", "Change styling on builtin tiles as follows: ...", new Date(year, month, start + 14), new Date(year, month, start + 19, 23, 59, 59), "shelleyFewel"),
                new CalendarEvent(15, "Dev Meeting", "Weekly dev meeting", new Date(year, month, start + 1), new Date(year, month, start + 1, 23, 59, 59), false, "testStyle", "charlesMadigen"),
                new CalendarEvent(16, "Dev Meeting", "Weekly dev meeting", new Date(year, month, start + 8), new Date(year, month, start + 8, 23, 59, 59), false, "testStyle", "charlesMadigen"),
                new CalendarEvent(17, "Dev Meeting", "Weekly dev meeting", new Date(year, month, start + 15), new Date(year, month, start + 15, 23, 59, 59), false, "testStyle", "charlesMadigen"),

                new CalendarEvent(18, "Oracle enhancements", "Add the following 11g-specific enhancements: ...", new Date(year, month, start + 5), new Date(year, month, start + 7, 23, 59, 59), "garretMonroe"),
                new CalendarEvent(19, "Client export", "Excel export alterations", new Date(year, month, start + 11), new Date(year, month, start + 14, 23, 59, 59), "garretMonroe"),
                new CalendarEvent(20, "Record Components", "New ListGrid recordComponent modes: ...", new Date(year, month, start + 16), new Date(year, month, start + 20, 23, 59, 59), "garretMonroe"),
                new CalendarEvent(21, "SQLDataSource", "Enhancements to customSQL support", new Date(year, month, start + 2), new Date(year, month, start + 4, 23, 59, 59), "kaiKong"),
                new CalendarEvent(22, "includeFrom", "Update support via includeFrom", new Date(year, month, start + 6), new Date(year, month, start + 8, 23, 59, 59), "kaiKong"),
                new CalendarEvent(23, "FileItem", "Add milti-file upload support", new Date(year, month, start + 14), new Date(year, month, start + 16, 23, 59, 59), "kaiKong"),
                new CalendarEvent(24, "Doc viewer", "Enhance documentation viewer with these additional syntax-hilites: ...", new Date(year, month, start + 18), new Date(year, month, start + 19, 23, 59, 59), "kaiKong")
            };
        }
    }

    public static class TimelineLaneData {

        private static Lane[] lanes;

        public static Lane[] getLanes() {
            if (lanes == null) {
                lanes = getNewRecords();
            }
            return lanes;
        }

        public TimelineLaneData() {
        }

        public static Lane[] getNewRecords() {
            Lane[] lanes = new Lane[]{
                getLane("charlesMadigen", "Banana banana", "Managers"),
                getLane("tamaraKane", "Tamara Kane", "Developers"),
                getLane("darcyFeeney", "Darcy Feeney", "Managers"),
                getLane("kaiKong", "Kai Kong", "Developers"),
                getLane("shelleyFewel", "Shelley Fewel", "Managers"),
                getLane("garretMonroe", "Garret Monroe", "Developers")
            };
            return lanes;
        }

        private static Lane getLane(String name, String title, String devGroup) {
            Lane lane = new Lane(name, title);
            lane.setAttribute("devGroup", devGroup);
            return lane;
        }

        public static Record[] getRecords(){
            Record[] records = new Record[]{
                getRecord("charlesMadigen", "Darth Vader", "Managers"),
                getRecord("tamaraKane", "Tamara Kane", "Developers"),
                getRecord("darcyFeeney", "Darcy Feeney", "Managers"),
                getRecord("kaiKong", "Kai Kong", "Developers"),
                getRecord("shelleyFewel", "Shelley Fewel", "Managers"),
                getRecord("garretMonroe", "Garret Monroe", "Developers")
            };
            return records;
        }

        private static Record getRecord(String name, String title, String devGroup) {
            Record record = new Record();
            record.setAttribute("name", name);
            record.setAttribute("title", title);
            record.setAttribute("devGroup", devGroup);
            return record;
        }
    }

}