package com.smartgwt.sample.client;

import java.util.ArrayList;
import java.util.Date;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceSequenceField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.TimeUnit;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.*;
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.*;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

public class ResolutionChange extends VLayout {

  private final Date _calStart = new Date(112, 6, 2);

  private final Date _calEnd = new Date(112, 6, 22);

  private final int year = _calStart.getYear();

  private final int month = _calStart.getMonth();

  private final int start = _calStart.getDate() - _calStart.getDay();

  private Lane[] developers = null;

  private ListGridField[] laneFields = null;

  private HLayout resolutionLayout = null;

  private Timeline currentTimeline = null;

  private DataSource eventDS = null;

  public ResolutionChange() {
    SC.showConsole();

    eventDS = new DataSource();
    eventDS.setID("siemensTestDS");
    DataSourceSequenceField eventIdField = new DataSourceSequenceField("eventId");
    eventIdField.setPrimaryKey(true);

    DataSourceTextField nameField = new DataSourceTextField("name");
    DataSourceTextField descField = new DataSourceTextField("description");
    DataSourceDateField startDateField = new DataSourceDateField("startDate");
    DataSourceDateField endDateField = new DataSourceDateField("endDate");

    eventDS.setFields(eventIdField, nameField, descField, startDateField, endDateField);
    eventDS.setClientOnly(true);
    eventDS.setTestData(getEvents());
    
    setWidth100();
    setHeight100();
    
    resolutionLayout = buildResolutionLayout();
    currentTimeline = getSublanesTimeline();
    this.addMembers(resolutionLayout, currentTimeline);
  }

  private HLayout buildResolutionLayout() {
    HLayout layout = new HLayout(5);
    layout.setHeight(1);
    layout.setWidth100();
    layout.addMembers(
            getResolutionButton("Hours (1 day)", new HeaderLevel[]{
              new HeaderLevel(TimeUnit.DAY),
              new HeaderLevel(TimeUnit.HOUR)
            }, TimeUnit.HOUR, 24));

    return layout;
  }

  private Button getResolutionButton(String title, final HeaderLevel[] headerLevels, final TimeUnit unit,
          final Integer unitCount) {
    Button button = new Button(title);
    button.setAutoFit(true);

    button.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        currentTimeline.setResolution(headerLevels, unit, unitCount);
      }
    });
    return button;
  }

  private Timeline getSublanesTimeline() {
    Timeline timeline = new Timeline();
    setupTimeline(timeline);
    timeline.setShowLaneRollOver(true);
    timeline.setDisableWeekends(false);

    return timeline;
  }

  private void setupTimeline(Timeline timeline) {
    timeline.setWidth100();
    timeline.setHeight(300);
    timeline.setStartDate(_calStart);
    timeline.setEndDate(_calEnd);
    timeline.setHideUnusedLanes(true);
    timeline.setDataSource(eventDS);
    timeline.setAutoFetchData(true);
    timeline.setAllowDurationEvents(true);
    timeline.setUseSublanes(true);
    timeline.setCanEditLane(true);
    timeline.setCanEditSublane(true);
    timeline.setLanes(getDevelopers());
    timeline.setCanReorderLanes(true);
    timeline.setLaneFields(getLaneFields());
    timeline.setHeaderLevels(new HeaderLevel[]{
      new HeaderLevel(TimeUnit.WEEK),
      new HeaderLevel(TimeUnit.DAY)
    });
    timeline.setDisableWeekends(false);
    timeline.setCanResizeEvents(true);
    timeline.setShowEventDescriptions(true);
    timeline.setColumnsPerPage(5);
    timeline.setLaneEventPadding(4);
    timeline.setShowZones(true);
    timeline.setZones(
            new CalendarEvent(99, "zone1", "", new Date(2012 - 1900, 6, 5), new Date(2012 - 1900, 6, 11)));
    timeline.setZoneStyleName("customZoneStyle");
    timeline.setShowIndicators(true);
    CalendarEvent indicator = new CalendarEvent(199, "indicator1", "", new Date(112, 6, 7, 12, 0), null);
    timeline.setIndicators(indicator);
  }

  private Lane[] getDevelopers() {
    developers = new Lane[]{
      getLane("shelleyFewel", "Shelley Fewel", 60, "Group 3", "a"),
      getLane("kaiKong", "Kai Kong", 40, "Group 2", "a"),
      getLane("charlesMadigen", "Charles Madigen", 60, "Group 1", "b"),
      getLane("tamaraKane", "Tamara Kane", 60, "Group 3", "a"),
      getLane("darcyFeeney", "Darcy Feeney", 60, "Group 1", "a"),
      getLane("garretMonroe", "Garret Monroe", 60, "Group 2", "b")
    };

    return developers;
  }

  private Lane getLane(String name, String title, Integer height, String groupField1, String groupField2) {
    ArrayList<Lane> sublanes = new ArrayList<Lane>();

    Lane sublane = new Lane("planned", "Planned");
    sublane.setEventStyleName("testStyle1");
    sublanes.add(sublane);
    sublane = new Lane("actual", "Actual");
    sublane.setEventStyleName("testStyle2");
    sublanes.add(sublane);

    if (name.equals("shelleyFewel")) {
      Lane extraLane = new Lane("additional", "Additional");
      extraLane.setEventStyleName("testStyle3");
      extraLane.setHeight(30);
      sublanes.add(extraLane);
    }

    Lane lane = new Lane(name, title);
    lane.setHeight(height);
    lane.setSublanes(sublanes.toArray(new Lane[sublanes.size()]));

    return lane;
  }

  private ListGridField[] getLaneFields() {
    laneFields = new ListGridField[]{
      getLaneField("title", "Title", 120),
    };

    return laneFields;
  }

  private ListGridField getLaneField(String name, String title, Integer width) {
    return new ListGridField(name, title, width);
  }

  private CalendarEvent[] getEvents() {

    return new CalendarEvent[]{
      getEvent(1, "Fixed Style", "Fixed Style", start, start + 2, null, null, "shelleyFewel", "planned",
      "testStyleRounded"),
      getEvent(2, "2HourDuration", "2 hour Duration", start, null, 12, TimeUnit.HOUR, "shelleyFewel", "actual", null),
      getEvent(11, "TestItem11", "Test Item 11", start, start + 2, null, null, "kaiKong", "planned", null),
      getEvent(12, "TestItem12", "Test Item 12", start, start + 2, null, null, "kaiKong", "actual", null),
      getEvent(21, "TestItem21", "Test Item 21", start, start + 2, null, null, "charlesMadigen", "planned", null),
      getEvent(22, "TestItem22", "Test Item 22", start, start + 2, null, null, "charlesMadigen", "actual", null),
      getEvent(31, "TestItem31", "Test Item 31", start, start + 2, null, null, "tamaraKane", "planned", null),
      getEvent(32, "TestItem32", "Test Item 32", start, start + 2, null, null, "tamaraKane", "actual", null),
      getEvent(41, "TestItem11", "Test Item 41", start, start + 2, null, null, "darcyFeeney", "planned", null),
      getEvent(42, "TestItem12", "Test Item 42", start, start + 2, null, null, "darcyFeeney", "actual", null),
      getEvent(51, "TestItem51", "Test Item 51", start, start + 2, null, null, "garretMonroe", "planned", null),
      getEvent(52, "TestItem52", "Test Item 52", start, start + 2, null, null, "garretMonroe", "actual", null),};
  }

  private CalendarEvent getEvent(Integer id, String name, String title, Integer start,
          Integer end,
          Integer duration,
          TimeUnit durationUnit,
          String lane, String sublane, String styleName) {
    CalendarEvent event = new CalendarEvent(id, name, title, new Date(year, month, start), null, lane);
    event.setSublane(sublane);
    if (duration != null) {
      if (duration == 0) {
        event.setCanResize(false);
      }
      event.setDuration(duration);
      event.setDurationUnit(durationUnit);
    } else {
      event.setEndDate(new Date(year, month, end));
    }
    event.setStyleName(styleName);
    return event;
  }
}
