/*
 * Copyright 2010 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.cellview.client;

import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.i18n.client.LocalizableResource.DefaultLocale;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ImageResource.ImageOptions;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.user.client.Event;
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.Image;
import com.google.gwt.view.client.HasRows;
import com.google.gwt.view.client.Range;

/**
 * A pager for controlling a {@link HasRows} that only supports simple page
 * navigation.
 *
 * <p>
 * <h3>Example</h3>
 * {@example com.google.gwt.examples.cellview.SimplePagerExample}
 * </p>
 */
public class SimplePager extends AbstractPager {
  /**
   * Constant for labeling the simple pager navigational {@link ImageButton}s
   */
  @DefaultLocale("en_US")
  public interface ImageButtonsConstants extends Constants {
    @DefaultStringValue("Fast forward")
    String fastForward();
    @DefaultStringValue("First page")
    String firstPage();
    @DefaultStringValue("Last page")
    String lastPage();
    @DefaultStringValue("Next page")
    String nextPage();
    @DefaultStringValue("Previous page")
    String prevPage();
  }

  /**
   * A ClientBundle that provides images for this widget.
   */
  public static interface Resources extends ClientBundle {

    /**
     * The image used to skip ahead multiple pages.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerFastForward();

    /**
     * The disabled "fast forward" image.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerFastForwardDisabled();

    /**
     * The image used to go to the first page.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerFirstPage();

    /**
     * The disabled first page image.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerFirstPageDisabled();

    /**
     * The image used to go to the last page.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerLastPage();

    /**
     * The disabled last page image.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerLastPageDisabled();

    /**
     * The image used to go to the next page.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerNextPage();

    /**
     * The disabled next page image.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerNextPageDisabled();

    /**
     * The image used to go to the previous page.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerPreviousPage();

    /**
     * The disabled previous page image.
     */
    @ImageOptions(flipRtl = true)
    ImageResource simplePagerPreviousPageDisabled();

    /**
     * The styles used in this widget.
     */
    @Source("SimplePager.css")
    Style simplePagerStyle();
  }

  /**
   * Styles used by this widget.
   */
  public static interface Style extends CssResource {

    /**
     * Applied to buttons.
     */
    String button();

    /**
     * Applied to disabled buttons.
     */
    String disabledButton();

    /**
     * Applied to the details text.
     */
    String pageDetails();
  }

  /**
   * The location of the text relative to the paging buttons.
   */
  public static enum TextLocation {
    CENTER, LEFT, RIGHT;
  }

  /**
   * An {@link Image} that acts as a button.
   */
  private static class ImageButton extends Image {
    private boolean disabled;
    private final ImageResource resDisabled;
    private final ImageResource resEnabled;
    private final String styleDisabled;

    public ImageButton(ImageResource resEnabled, ImageResource resDiabled,
        String disabledStyle, String label) {
      super(resEnabled);
      this.resEnabled = resEnabled;
      this.resDisabled = resDiabled;
      this.styleDisabled = disabledStyle;
      Roles.getButtonRole().set(getElement());
      Roles.getButtonRole().setAriaLabelProperty(getElement(), label);
    }

    public boolean isDisabled() {
      return disabled;
    }

    @Override
    public void onBrowserEvent(Event event) {
      // Ignore events if disabled.
      if (disabled) {
        return;
      }

      super.onBrowserEvent(event);
    }

    public void setDisabled(boolean isDisabled) {
      if (this.disabled == isDisabled) {
        return;
      }

      this.disabled = isDisabled;
      if (disabled) {
        setResource(resDisabled);
        getElement().getParentElement().addClassName(styleDisabled);
      } else {
        setResource(resEnabled);
        getElement().getParentElement().removeClassName(styleDisabled);
      }
      Roles.getButtonRole().setAriaDisabledState(getElement(), disabled);
    }
  }

  private static final int DEFAULT_FAST_FORWARD_ROWS = 1000;
  private static Resources DEFAULT_RESOURCES;

  private static Resources getDefaultResources() {
    if (DEFAULT_RESOURCES == null) {
      DEFAULT_RESOURCES = GWT.create(Resources.class);
    }
    return DEFAULT_RESOURCES;
  }

  private final ImageButton fastForward;

  private final int fastForwardRows;

  private final ImageButton firstPage;

  /**
   * We use an {@link HTML} so we can embed the loading image.
   */
  private final HTML label = new HTML();

  private final ImageButton lastPage;
  private final ImageButton nextPage;
  private final ImageButton prevPage;

  /**
   * The {@link Resources} used by this widget.
   */
  private final Resources resources;

  /**
   * The {@link Style} used by this widget.
   */
  private final Style style;

  /**
   * Construct a {@link SimplePager} with the default text location.
   */
  public SimplePager() {
    this(TextLocation.CENTER);
  }

  /**
   * Construct a {@link SimplePager} with the specified text location.
   *
   * @param location the location of the text relative to the buttons
   */
  @UiConstructor
  // Hack for Google I/O demo
  public SimplePager(TextLocation location) {
    this(location, getDefaultResources(), true, DEFAULT_FAST_FORWARD_ROWS,
        false);
  }

  /**
   * Construct a {@link SimplePager} with the default resources, fast forward rows and
   * default image button names.
   *
   * @param location the location of the text relative to the buttons
   * @param showFastForwardButton if true, show a fast-forward button that
   *          advances by a larger increment than a single page
   * @param showLastPageButton if true, show a button to go the the last page
   */
  public SimplePager(TextLocation location, boolean showFastForwardButton,
      boolean showLastPageButton) {
    this(location, showFastForwardButton, DEFAULT_FAST_FORWARD_ROWS,
        showLastPageButton);
  }

  /**
   * Construct a {@link SimplePager} with the default resources and default image button names.
   *
   * @param location the location of the text relative to the buttons
   * @param showFastForwardButton if true, show a fast-forward button that
   *          advances by a larger increment than a single page
   * @param fastForwardRows the number of rows to jump when fast forwarding
   * @param showLastPageButton if true, show a button to go the the last page
   */
  public SimplePager(TextLocation location, boolean showFastForwardButton,
      final int fastForwardRows, boolean showLastPageButton) {
    this(location, getDefaultResources(), showFastForwardButton, fastForwardRows,
        showLastPageButton);
  }

  /**
   * Construct a {@link SimplePager} with the specified resources.
   *
   * @param location the location of the text relative to the buttons
   * @param resources the {@link Resources} to use
   * @param showFastForwardButton if true, show a fast-forward button that
   *          advances by a larger increment than a single page
   * @param fastForwardRows the number of rows to jump when fast forwarding
   * @param showLastPageButton if true, show a button to go the the last page
   * @param imageButtonConstants Constants that contain the image button names
   */
  public SimplePager(TextLocation location, Resources resources,
      boolean showFastForwardButton, final int fastForwardRows,
      boolean showLastPageButton, ImageButtonsConstants imageButtonConstants) {
    this.resources = resources;
    this.fastForwardRows = fastForwardRows;
    this.style = resources.simplePagerStyle();
    this.style.ensureInjected();

    // Create the buttons.
    String disabledStyle = style.disabledButton();
    firstPage = new ImageButton(resources.simplePagerFirstPage(),
        resources.simplePagerFirstPageDisabled(), disabledStyle, imageButtonConstants.firstPage());
    firstPage.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        firstPage();
      }
    });
    nextPage = new ImageButton(resources.simplePagerNextPage(),
        resources.simplePagerNextPageDisabled(), disabledStyle, imageButtonConstants.nextPage());
    nextPage.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        nextPage();
      }
    });
    prevPage = new ImageButton(resources.simplePagerPreviousPage(),
        resources.simplePagerPreviousPageDisabled(), disabledStyle,
        imageButtonConstants.prevPage());
    prevPage.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        previousPage();
      }
    });
    if (showLastPageButton) {
      lastPage = new ImageButton(resources.simplePagerLastPage(),
          resources.simplePagerLastPageDisabled(), disabledStyle, imageButtonConstants.lastPage());
      lastPage.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          lastPage();
        }
      });
    } else {
      lastPage = null;
    }
    if (showFastForwardButton) {
      fastForward = new ImageButton(resources.simplePagerFastForward(),
          resources.simplePagerFastForwardDisabled(), disabledStyle,
          imageButtonConstants.fastForward());
      fastForward.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
          setPage(getPage() + getFastForwardPages());
        }
      });
    } else {
      fastForward = null;
    }

    // Construct the widget.
    HorizontalPanel layout = new HorizontalPanel();
    layout.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
    initWidget(layout);
    if (location == TextLocation.LEFT) {
      layout.add(label);
    }
    layout.add(firstPage);
    layout.add(prevPage);
    if (location == TextLocation.CENTER) {
      layout.add(label);
    }
    layout.add(nextPage);
    if (showFastForwardButton) {
      layout.add(fastForward);
    }
    if (showLastPageButton) {
      layout.add(lastPage);
    }
    if (location == TextLocation.RIGHT) {
      layout.add(label);
    }

    // Add style names to the cells.
    firstPage.getElement().getParentElement().addClassName(style.button());
    prevPage.getElement().getParentElement().addClassName(style.button());
    label.getElement().getParentElement().addClassName(style.pageDetails());
    nextPage.getElement().getParentElement().addClassName(style.button());
    if (showFastForwardButton) {
      fastForward.getElement().getParentElement().addClassName(style.button());
    }
    if (showLastPageButton) {
      lastPage.getElement().getParentElement().addClassName(style.button());
    }

    // Disable the buttons by default.
    setDisplay(null);
  }

  /**
   * Construct a {@link SimplePager} with the specified resources and default image button names.
   *
   * @param location the location of the text relative to the buttons
   * @param resources the {@link Resources} to use
   * @param showFastForwardButton if true, show a fast-forward button that
   *          advances by a larger increment than a single page
   * @param fastForwardRows the number of rows to jump when fast forwarding
   * @param showLastPageButton if true, show a button to go the the last page
   */
  public SimplePager(TextLocation location, Resources resources,
      boolean showFastForwardButton, final int fastForwardRows,
      boolean showLastPageButton) {
    this(location, resources, showFastForwardButton, fastForwardRows, showLastPageButton,
        GWT.<ImageButtonsConstants>create(ImageButtonsConstants.class));
  }

  @Override
  public void firstPage() {
    super.firstPage();
  }

  @Override
  public int getPage() {
    return super.getPage();
  }

  @Override
  public int getPageCount() {
    return super.getPageCount();
  }

  @Override
  public boolean hasNextPage() {
    return super.hasNextPage();
  }

  @Override
  public boolean hasNextPages(int pages) {
    return super.hasNextPages(pages);
  }

  @Override
  public boolean hasPage(int index) {
    return super.hasPage(index);
  }

  @Override
  public boolean hasPreviousPage() {
    return super.hasPreviousPage();
  }

  @Override
  public boolean hasPreviousPages(int pages) {
    return super.hasPreviousPages(pages);
  }

  @Override
  public void lastPage() {
    super.lastPage();
  }

  @Override
  public void lastPageStart() {
    super.lastPageStart();
  }

  @Override
  public void nextPage() {
    super.nextPage();
  }

  @Override
  public void previousPage() {
    super.previousPage();
  }

  @Override
  public void setDisplay(HasRows display) {
    // Enable or disable all buttons.
    boolean disableButtons = (display == null);
    setFastForwardDisabled(disableButtons);
    setNextPageButtonsDisabled(disableButtons);
    setPrevPageButtonsDisabled(disableButtons);
    super.setDisplay(display);
  }

  @Override
  public void setPage(int index) {
    super.setPage(index);
  }

  @Override
  public void setPageSize(int pageSize) {
    super.setPageSize(pageSize);
  }

  @Override
  public void setPageStart(int index) {
    super.setPageStart(index);
  }

  /**
   * Let the page know that the table is loading. Call this method to clear all
   * data from the table and hide the current range when new data is being
   * loaded into the table.
   */
  public void startLoading() {
    getDisplay().setRowCount(0, true);
    label.setHTML("");
  }

  /**
   * Get the text to display in the pager that reflects the state of the pager.
   *
   * @return the text
   */
  protected String createText() {
    // Default text is 1 based.
    NumberFormat formatter = NumberFormat.getFormat("#,###");
    HasRows display = getDisplay();
    Range range = display.getVisibleRange();
    int pageStart = range.getStart() + 1;
    int pageSize = range.getLength();
    int dataSize = display.getRowCount();
    int endIndex = Math.min(dataSize, pageStart + pageSize - 1);
    endIndex = Math.max(pageStart, endIndex);
    boolean exact = display.isRowCountExact();
    return formatter.format(pageStart) + "-" + formatter.format(endIndex)
        + (exact ? " of " : " of over ") + formatter.format(dataSize);
  }

  @Override
  protected void onRangeOrRowCountChanged() {
    HasRows display = getDisplay();
    label.setText(createText());

    // Update the prev and first buttons.
    setPrevPageButtonsDisabled(!hasPreviousPage());

    // Update the next and last buttons.
    if (isRangeLimited() || !display.isRowCountExact()) {
      setNextPageButtonsDisabled(!hasNextPage());
      setFastForwardDisabled(!hasNextPages(getFastForwardPages()));
    }
  }

  /**
   * Check if the next button is disabled. Visible for testing.
   */
  boolean isNextButtonDisabled() {
    return nextPage.isDisabled();
  }

  /**
   * Check if the previous button is disabled. Visible for testing.
   */
  boolean isPreviousButtonDisabled() {
    return prevPage.isDisabled();
  }

  /**
   * Get the number of pages to fast forward based on the current page size.
   *
   * @return the number of pages to fast forward
   */
  private int getFastForwardPages() {
    int pageSize = getPageSize();
    return pageSize > 0 ? fastForwardRows / pageSize : 0;
  }

  /**
   * Enable or disable the fast forward button.
   *
   * @param disabled true to disable, false to enable
   */
  private void setFastForwardDisabled(boolean disabled) {
    if (fastForward == null) {
      return;
    }
    if (disabled) {
      fastForward.setResource(resources.simplePagerFastForwardDisabled());
      fastForward.getElement().getParentElement().addClassName(
          style.disabledButton());
    } else {
      fastForward.setResource(resources.simplePagerFastForward());
      fastForward.getElement().getParentElement().removeClassName(
          style.disabledButton());
    }
  }

  /**
   * Enable or disable the next page buttons.
   *
   * @param disabled true to disable, false to enable
   */
  private void setNextPageButtonsDisabled(boolean disabled) {
    nextPage.setDisabled(disabled);
    if (lastPage != null) {
      lastPage.setDisabled(disabled);
    }
  }

  /**
   * Enable or disable the previous page buttons.
   *
   * @param disabled true to disable, false to enable
   */
  private void setPrevPageButtonsDisabled(boolean disabled) {
    firstPage.setDisabled(disabled);
    prevPage.setDisabled(disabled);
  }
}
