/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.gwt.user.datepicker.client;

import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.event.logical.shared.HasHighlightHandlers;
import com.google.gwt.event.logical.shared.HasShowRangeHandlers;
import com.google.gwt.event.logical.shared.HighlightEvent;
import com.google.gwt.event.logical.shared.HighlightHandler;
import com.google.gwt.event.logical.shared.ShowRangeEvent;
import com.google.gwt.event.logical.shared.ShowRangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.VerticalPanel;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Standard GWT date picker.
 *
 * <h3>CSS Style Rules</h3>
 *
 * <ul class="css">
 *
 * <li>.gwt-DatePicker { }</li>
 *
 * <li>.datePickerMonthSelector { the month selector widget }</li>
 *
 * <li>.datePickerMonth { the month in the month selector widget } <li>
 *
 * <li>.datePickerYear { the year in the month selector widget } <li>
 *
 * <li>.datePickerPreviousButton { the previous month button } <li>
 *
 * <li>.datePickerNextButton { the next month button } <li>
 *
 * <li>.datePickerPreviousYearButton { the previous year button } <li>
 *
 * <li>.datePickerNextYearButton { the next year button } <li>
 *
 * <li>.datePickerDays { the portion of the picker that shows the days }</li>
 *
 * <li>.datePickerWeekdayLabel { the label over weekdays }</li>
 *
 * <li>.datePickerWeekendLabel { the label over weekends }</li>
 *
 * <li>.datePickerDay { a single day }</li>
 *
 * <li>.datePickerDayIsToday { today's date }</li>
 *
 * <li>.datePickerDayIsWeekend { a weekend day }</li>
 *
 * <li>.datePickerDayIsFiller { a day in another month }</li>
 *
 * <li>.datePickerDayIsValue { the selected day }</li>
 *
 * <li>.datePickerDayIsDisabled { a disabled day }</li>
 *
 * <li>.datePickerDayIsHighlighted { the currently highlighted day }</li>
 *
 * <li>.datePickerDayIsValueAndHighlighted { the highlighted day if it is also
 * selected }</li>
 *
 * </ul>
 *
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.DatePickerExample}
 * </p>
 */
public class DatePicker extends Composite implements
    HasHighlightHandlers<Date>, HasShowRangeHandlers<Date>, HasValue<Date>,
    IsEditor<LeafValueEditor<Date>> {

  /**
   * Convenience class to group css style names.
   */
  static class StandardCss {

    static StandardCss DEFAULT = new StandardCss("gwt-DatePicker", "datePicker");

    private String baseName;
    private String widgetName;

    public StandardCss(String widgetName, String baseName) {
      this.widgetName = widgetName;
      this.baseName = baseName;
    }

    public String datePicker() {
      return getWidgetStyleName();
    }

    public String day() {
      return wrap("Day");
    }

    public String day(String dayModifier) {
      return day() + "Is" + dayModifier;
    }

    public String dayIsDisabled() {
      return day("Disabled");
    }

    public String dayIsFiller() {
      return day("Filler");
    }

    public String dayIsHighlighted() {
      return day("Highlighted");
    }

    public String dayIsToday() {
      return day("Today");
    }

    public String dayIsValue() {
      return day("Value");
    }

    public String dayIsValueAndHighlighted() {
      return dayIsValue() + "AndHighlighted";
    }

    public String dayIsWeekend() {
      return day("Weekend");
    }

    public String days() {
      return wrap("Days");
    }

    public String daysLabel() {
      return wrap("DaysLabel");
    }

    public String getBaseStyleName() {
      return baseName;
    }

    public String getWidgetStyleName() {
      return widgetName;
    }

    public String month() {
      return wrap("Month");
    }

    public String monthSelector() {
      return wrap("MonthSelector");
    }

    public String nextButton() {
      return wrap("NextButton");
    }

    public String nextYearButton() {
      return wrap("NextYearButton");
    }

    public String previousButton() {
      return wrap("PreviousButton");
    }

    public String previousYearButton() {
      return wrap("PreviousYearButton");
    }

    public String weekdayLabel() {
      return wrap("WeekdayLabel");
    }

    public String weekendLabel() {
      return wrap("WeekendLabel");
    }

    public String year() {
      return wrap("Year");
    }

    /**
     * Prepends the base name to the given style.
     *
     * @param style style name
     * @return style name
     */
    protected String wrap(String style) {
      return baseName + style;
    }
  }

  /**
   * A date highlighted event that copied on read.
   */
  private static class DateHighlightEvent extends HighlightEvent<Date> {
    protected DateHighlightEvent(Date highlighted) {
      super(highlighted);
    }

    @Override
    public Date getHighlighted() {
      return CalendarUtil.copyDate(super.getHighlighted());
    }
  }

  private static class DateStyler {
    private Map<String, String> info = new HashMap<String, String>();

    public String getStyleName(Date d) {
      return info.get(genKey(d));
    }

    public void setStyleName(Date d, String styleName, boolean add) {
      // Code is easier to maintain if surrounded by " ", and on all browsers
      // this is a no-op.
      styleName = " " + styleName + " ";
      String key = genKey(d);
      String current = info.get(key);

      if (add) {
        if (current == null) {
          info.put(key, styleName);
        } else if (current.indexOf(styleName) == -1) {
          info.put(key, current + styleName);
        }
      } else {
        if (current != null) {
          String newValue = current.replaceAll(styleName, "");
          if (newValue.trim().length() == 0) {
            info.remove(key);
          } else {
            info.put(key, newValue);
          }
        }
      }
    }

    @SuppressWarnings("deprecation")
    private String genKey(Date d) {
      return d.getYear() + "/" + d.getMonth() + "/" + d.getDate();
    }
  }

  private static final int DEFAULT_VISIBLE_YEAR_COUNT = 21;

  private final DateStyler styler = new DateStyler();

  private final MonthSelector monthAndYearSelector;
  private final CalendarView view;
  private final CalendarModel model;
  private Date value;
  private Date highlighted;
  private StandardCss css = StandardCss.DEFAULT;
  private LeafValueEditor<Date> editor;
  private int visibleYearCount = DEFAULT_VISIBLE_YEAR_COUNT;
  private boolean yearArrowsVisible;
  private boolean yearAndMonthDropdownVisible;

  /**
   * Create a new date picker.
   */
  public DatePicker() {
    this(new DefaultMonthSelector(), new DefaultCalendarView(),
        new CalendarModel());
  }

  /**
   * Creates a new date picker.
   *
   * @param monthAndYearSelector the month selector
   * @param view the view
   * @param model the model
   */

  protected DatePicker(MonthSelector monthAndYearSelector, CalendarView view,
      CalendarModel model) {

    this.model = model;
    this.monthAndYearSelector = monthAndYearSelector;
    monthAndYearSelector.setDatePicker(this);
    this.view = view;
    view.setDatePicker(this);

    view.setup();
    monthAndYearSelector.setup();
    this.setup();

    setCurrentMonth(new Date());
    addStyleToDates(css().dayIsToday(), new Date());
  }

  public HandlerRegistration addHighlightHandler(HighlightHandler<Date> handler) {
    return addHandler(handler, HighlightEvent.getType());
  }

  public HandlerRegistration addShowRangeHandler(ShowRangeHandler<Date> handler) {
    return addHandler(handler, ShowRangeEvent.getType());
  }

  /**
   * Adds a show range handler and immediately activate the handler on the
   * current view.
   *
   * @param handler the handler
   * @return the handler registration
   */
  public HandlerRegistration addShowRangeHandlerAndFire(
      ShowRangeHandler<Date> handler) {
    ShowRangeEvent<Date> event = new ShowRangeEvent<Date>(
        getView().getFirstDate(), getView().getLastDate()) {
    };
    handler.onShowRange(event);
    return addShowRangeHandler(handler);
  }

  /**
   * Add a style name to the given dates.
   */
  public void addStyleToDates(String styleName, Date date) {
    styler.setStyleName(date, styleName, true);
    if (isDateVisible(date)) {
      getView().addStyleToDate(styleName, date);
    }
  }

  /**
   * Add a style name to the given dates.
   */
  public void addStyleToDates(String styleName, Date date, Date... moreDates) {
    addStyleToDates(styleName, date);
    for (Date d : moreDates) {
      addStyleToDates(styleName, d);
    }
  }

  /**
   * Add a style name to the given dates.
   */
  public void addStyleToDates(String styleName, Iterable<Date> dates) {
    for (Date d : dates) {
      addStyleToDates(styleName, d);
    }
  }

  /**
   * Adds the given style name to the specified dates, which must be visible.
   * This is only set until the next time the DatePicker is refreshed.
   */
  public void addTransientStyleToDates(String styleName, Date date) {
    assert isDateVisible(date) : date + " must be visible";
    getView().addStyleToDate(styleName, date);
  }

  /**
   * Adds the given style name to the specified dates, which must be visible.
   * This is only set until the next time the DatePicker is refreshed.
   */
  public final void addTransientStyleToDates(String styleName, Date date,
      Date... moreDates) {
    addTransientStyleToDates(styleName, date);
    for (Date d : moreDates) {
      addTransientStyleToDates(styleName, d);
    }
  }

  /**
   * Adds the given style name to the specified dates, which must be visible.
   * This is only set until the next time the DatePicker is refreshed.
   */
  public final void addTransientStyleToDates(String styleName,
      Iterable<Date> dates) {
    for (Date d : dates) {
      addTransientStyleToDates(styleName, d);
    }
  }

  public HandlerRegistration addValueChangeHandler(
      ValueChangeHandler<Date> handler) {
    return addHandler(handler, ValueChangeEvent.getType());
  }

  /**
   * Returns a {@link TakesValueEditor} backed by the DatePicker.
   */
  public LeafValueEditor<Date> asEditor() {
    if (editor == null) {
      editor = TakesValueEditor.of(this);
    }
    return editor;
  }

  /**
   * Gets the current month the date picker is showing.
   *
   * <p>
   * A datepicker <b> may </b> show days not in the current month. It
   * <b>must</b> show all days in the current month.
   * </p>
   *
   * @return the current month
   *
   */
  public Date getCurrentMonth() {
    return getModel().getCurrentMonth();
  }

  /**
   * Returns the first shown date.
   *
   * @return the first date.
   */
  // Final because the view should always control the value of the first date.
  public final Date getFirstDate() {
    return view.getFirstDate();
  }

  /**
   * Gets the highlighted date (the one the mouse is hovering over), if any.
   *
   * @return the highlighted date
   */
  public final Date getHighlightedDate() {
    return CalendarUtil.copyDate(highlighted);
  }

  /**
   * Returns the last shown date.
   *
   * @return the last date.
   */
  // Final because the view should always control the value of the last date.
  public final Date getLastDate() {
    return view.getLastDate();
  }

  /**
   * Returns the number of year to display in the years selection dropdown.
   */
  public int getVisibleYearCount() {
    return visibleYearCount;
  }

  /**
   * Gets the style associated with a date (does not include styles set via
   * {@link #addTransientStyleToDates}).
   *
   * @param date the date
   * @return the styles associated with this date
   */
  public String getStyleOfDate(Date date) {
    return styler.getStyleName(date);
  }

  /**
   * Returns the selected date, or null if none is selected.
   *
   * @return the selected date, or null
   */
  public final Date getValue() {
    return CalendarUtil.copyDate(value);
  }

  /**
   * Is the visible date enabled?
   *
   * @param date the date, which must be visible
   *
   * @return is the date enabled?
   */
  public boolean isDateEnabled(Date date) {
    assert isDateVisible(date) : date + " is not visible";
    return getView().isDateEnabled(date);
  }

  /**
   * Is the date currently shown in the date picker?
   *
   * @param date
   *
   * @return is the date currently shown
   */
  public boolean isDateVisible(Date date) {
    CalendarView r = getView();
    Date first = r.getFirstDate();
    Date last = r.getLastDate();
    return (date != null && (CalendarUtil.isSameDate(first, date)
        || CalendarUtil.isSameDate(last, date) || (first.before(date) && last.after(date))));
  }

  /**
   * Can the user navigate through the years?
   *
   * @return is the year navigation is enabled
   */
  public boolean isYearArrowsVisible() {
    return yearArrowsVisible;
  }

  /**
   * Is the year and month selectable via a dropdown?
   */
  public boolean isYearAndMonthDropdownVisible() {
    return yearAndMonthDropdownVisible;
  }

  @Override
  public void onLoad() {
    ShowRangeEvent.fire(this, getFirstDate(), getLastDate());
  }

  /**
   * Removes the styleName from the given dates (even if it is transient).
   */
  public void removeStyleFromDates(String styleName, Date date) {
    styler.setStyleName(date, styleName, false);
    if (isDateVisible(date)) {
      getView().removeStyleFromDate(styleName, date);
    }
  }

  /**
   * Removes the styleName from the given dates (even if it is transient).
   */
  public void removeStyleFromDates(String styleName, Date date,
      Date... moreDates) {
    removeStyleFromDates(styleName, date);
    for (Date d : moreDates) {
      removeStyleFromDates(styleName, d);
    }
  }

  /**
   * Removes the styleName from the given dates (even if it is transient).
   */
  public void removeStyleFromDates(String styleName, Iterable<Date> dates) {
    for (Date d : dates) {
      removeStyleFromDates(styleName, d);
    }
  }

  /**
   * Sets the date picker to show the given month, use {@link #getFirstDate()}
   * and {@link #getLastDate()} to access the exact date range the date picker
   * chose to display.
   * <p>
   * A datepicker <b> may </b> show days not in the current month. It
   * <b>must</b> show all days in the current month.
   * </p>
   *
   * @param month the month to show
   */
  public void setCurrentMonth(Date month) {
    getModel().setCurrentMonth(month);
    refreshAll();
  }

  /**
   * Set the number of years to display in the years selection dropdown. The range of years will be
   * centered on the selected date.
   */
  public void setVisibleYearCount(int numberOfYears) {
    if (numberOfYears <= 0) {
      throw new IllegalArgumentException("The number of years to display must be positive");
    }

    visibleYearCount = numberOfYears;
    getMonthSelector().refresh();
  }

  /**
   * Set if the user can navigate through the years via a set of backward and forward buttons.
   */
  public void setYearArrowsVisible(boolean yearArrowsVisible) {
    this.yearArrowsVisible = yearArrowsVisible;
    getMonthSelector().refresh();
  }

  /**
   * If the <code>dropdownVisible</code> is equal to true, the user will be able to change the current month and
   * the current year of the date picker via two dropdown lists.
   */
  public void setYearAndMonthDropdownVisible(boolean dropdownVisible) {
    this.yearAndMonthDropdownVisible = dropdownVisible;
    getMonthSelector().refresh();
  }

  /**
   * Sets the date picker style name.
   */
  @Override
  public void setStyleName(String styleName) {
    css = new StandardCss(styleName, "datePicker");
    super.setStyleName(styleName);
  }

  /**
   * Sets a visible date to be enabled or disabled. This is only set until the
   * next time the DatePicker is refreshed.
   */
  public final void setTransientEnabledOnDates(boolean enabled, Date date) {
    assert isDateVisible(date) : date + " must be visible";
    getView().setEnabledOnDate(enabled, date);
  }

  /**
   * Sets a visible date to be enabled or disabled. This is only set until the
   * next time the DatePicker is refreshed.
   */
  public final void setTransientEnabledOnDates(boolean enabled, Date date,
      Date... moreDates) {
    setTransientEnabledOnDates(enabled, date);
    for (Date d : moreDates) {
      setTransientEnabledOnDates(enabled, d);
    }
  }

  /**
   * Sets a group of visible dates to be enabled or disabled. This is only set
   * until the next time the DatePicker is refreshed.
   */
  public final void setTransientEnabledOnDates(boolean enabled,
      Iterable<Date> dates) {
    for (Date d : dates) {
      setTransientEnabledOnDates(enabled, d);
    }
  }

  /**
   * Sets the {@link DatePicker}'s value.
   *
   * @param newValue the new value
   */
  public final void setValue(Date newValue) {
    setValue(newValue, false);
  }

  /**
   * Sets the {@link DatePicker}'s value.
   *
   * @param newValue the new value for this date picker
   * @param fireEvents should events be fired.
   */
  public final void setValue(Date newValue, boolean fireEvents) {
    Date oldValue = value;

    if (oldValue != null) {
      removeStyleFromDates(css().dayIsValue(), oldValue);
    }

    value = CalendarUtil.copyDate(newValue);
    if (value != null) {
      addStyleToDates(css().dayIsValue(), value);
    }
    getView().setAriaSelectedCell(newValue);

    if (fireEvents) {
      DateChangeEvent.fireIfNotEqualDates(this, oldValue, newValue);
    }
  }

  /**
   * Gets the {@link CalendarModel} associated with this date picker.
   *
   * @return the model
   */
  protected final CalendarModel getModel() {
    return model;
  }

  /**
   * Gets the {@link MonthSelector} associated with this date picker.
   *
   * @return the month selector
   */
  protected final MonthSelector getMonthSelector() {
    return monthAndYearSelector;
  }

  /**
   * Gets the {@link CalendarView} associated with this date picker.
   *
   * @return the view
   */
  protected final CalendarView getView() {
    return view;
  }

  /**
   * Refreshes all components of this date picker.
   */
  protected final void refreshAll() {
    highlighted = null;
    getModel().refresh();

    getView().refresh();
    getMonthSelector().refresh();
    if (isAttached()) {
      ShowRangeEvent.fire(this, getFirstDate(), getLastDate());
    }
    getView().setAriaSelectedCell(value);
  }

  /**
   * Sets up the date picker.
   */
  protected void setup() {
    /*
     * Use a table (VerticalPanel) to get shrink-to-fit behavior. Divs expand to
     * fill the available width, so we'd need to give it a size.
     */
    VerticalPanel panel = new VerticalPanel();
    initWidget(panel);
    setStyleName(panel.getElement(), css.datePicker());
    setStyleName(css().datePicker());
    panel.add(this.getMonthSelector());
    panel.add(this.getView());
  }

  /**
   * Gets the css associated with this date picker for use by extended month and
   * cell grids.
   *
   * @return the css.
   */
  final StandardCss css() {
    return css;
  }

  /**
   * Sets the highlighted date.
   *
   * @param highlighted highlighted date
   */
  void setHighlightedDate(Date highlighted) {
    this.highlighted = highlighted;
    fireEvent(new DateHighlightEvent(highlighted));
  }
}
