/*
 * 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.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.view.client.HasRows;
import com.google.gwt.view.client.Range;
import com.google.gwt.view.client.RangeChangeEvent;
import com.google.gwt.view.client.RowCountChangeEvent;

/**
 * An abstract pager that exposes many methods useful for paging.
 */
public abstract class AbstractPager extends Composite {

  private HasRows display;

  /**
   * If true, all operations should be limited to the data size.
   */
  private boolean isRangeLimited = true;

  /**
   * The last row count.
   */
  private int lastRowCount;

  private HandlerRegistration rangeChangeHandler;
  private HandlerRegistration rowCountChangeHandler;

  /**
   * Get the {@link HasRows} being paged.
   *
   * @return the {@link HasRows}
   * @see #setDisplay(HasRows)
   */
  public HasRows getDisplay() {
    return display;
  }

  /**
   * Get the page size.
   *
   * @return the page size, or -1 if the display is not set
   * @see #setPageSize(int)
   */
  public int getPageSize() {
    return display == null ? -1 : display.getVisibleRange().getLength();
  }

  /**
   * Get the page start index.
   *
   * @return the page start index, or -1 if the display is not set
   * @see #setPageStart(int)
   */
  public int getPageStart() {
    return display == null ? -1 : display.getVisibleRange().getStart();
  }

  /**
   * Check if the page should be limited to the actual data size. Defaults to
   * true.
   *
   * @return true if the range is limited to the data size
   * @see #setRangeLimited(boolean)
   */
  public boolean isRangeLimited() {
    return isRangeLimited;
  }

  /**
   * Set whether or not the page range should be limited to the actual data
   * size. If true, all operations will adjust so that there is always data
   * visible on the page.
   *
   * @param isRangeLimited true to limit the range, false not to
   * @see #isRangeLimited()
   */
  public void setRangeLimited(boolean isRangeLimited) {
    this.isRangeLimited = isRangeLimited;
  }

  /**
   * Set the {@link HasRows} to be paged.
   *
   * @param display the {@link HasRows}
   * @see #getDisplay()
   */
  public void setDisplay(HasRows display) {
    // Remove the old handlers.
    if (rangeChangeHandler != null) {
      rangeChangeHandler.removeHandler();
      rangeChangeHandler = null;
    }
    if (rowCountChangeHandler != null) {
      rowCountChangeHandler.removeHandler();
      rangeChangeHandler = null;
    }

    // Set the new display.
    this.display = display;
    if (display != null) {
      rangeChangeHandler = display.addRangeChangeHandler(
          new RangeChangeEvent.Handler() {
            public void onRangeChange(RangeChangeEvent event) {
              if (AbstractPager.this.display != null) {
                onRangeOrRowCountChanged();
              }
            }
          });
      rowCountChangeHandler = display.addRowCountChangeHandler(
          new RowCountChangeEvent.Handler() {
            public void onRowCountChange(RowCountChangeEvent event) {
              if (AbstractPager.this.display != null) {
                handleRowCountChange(
                    event.getNewRowCount(), event.isNewRowCountExact());
              }
            }
          });

      // Initialize the pager.
      onRangeOrRowCountChanged();
    }
  }

  /**
   * Go to the first page.
   */
  protected void firstPage() {
    setPage(0);
  }

  /**
   * <p>
   * Get the current page index.
   * </p>
   * <p>
   * Since the page start index can be set to any value, its possible to be
   * between pages. In this case, the return value is the number of times
   * {@link #previousPage()} can be called.
   * </p>
   *
   * @return the page index, or -1 if the display is not set
   * @see #setPage(int)
   */
  protected int getPage() {
    if (display == null) {
      return -1;
    }
    Range range = display.getVisibleRange();
    int pageSize = range.getLength();
    return (range.getStart() + pageSize - 1) / pageSize;
  }

  /**
   * Get the number of pages based on the data size.
   *
   * @return the page count, or -1 if the display is not set
   */
  protected int getPageCount() {
    if (display == null) {
      return -1;
    }
    int pageSize = getPageSize();
    return (display.getRowCount() + pageSize - 1) / pageSize;
  }

  /**
   * Returns true if there is enough data such that a call to
   * {@link #nextPage()} will succeed in moving the starting point of the table
   * forward.
   *
   * @return true if there is a next page
   */
  protected boolean hasNextPage() {
    if (display == null) {
      return false;
    } else if (!display.isRowCountExact()) {
      return true;
    }
    Range range = display.getVisibleRange();
    return range.getStart() + range.getLength() < display.getRowCount();
  }

  /**
   * Returns true if there is enough data to display a given number of
   * additional pages.
   *
   * @param pages the number of pages to query
   * @return true if there are {@code pages} next pages
   */
  protected boolean hasNextPages(int pages) {
    if (display == null) {
      return false;
    }
    Range range = display.getVisibleRange();
    return range.getStart() + pages * range.getLength() < display.getRowCount();
  }

  /**
   * Returns true if there is enough data such that the specified page is within
   * range.
   *
   * @param index the page index
   * @return true if the specified page is in range
   */
  protected boolean hasPage(int index) {
    return display == null ? false : getPageSize() * index
        < display.getRowCount();
  }

  /**
   * Returns true if there is enough data such that a call to
   * {@link #previousPage()} will succeed in moving the starting point of the
   * table backward.
   *
   * @return true if there is a previous page
   */
  protected boolean hasPreviousPage() {
    return display == null ? false : getPageStart() > 0
        && display.getRowCount() > 0;
  }

  /**
   * Returns true if there is enough data to display a given number of previous
   * pages.
   *
   * @param pages the number of previous pages to query
   * @return true if there are {@code pages} previous pages
   */
  protected boolean hasPreviousPages(int pages) {
    if (display == null) {
      return false;
    }
    Range range = display.getVisibleRange();
    return (pages - 1) * range.getLength() < range.getStart();
  }

  /**
   * Go to the last page.
   */
  protected void lastPage() {
    setPage(getPageCount() - 1);
  }

  /**
   * Set the page start to the last index that will still show a full page.
   */
  protected void lastPageStart() {
    if (display != null) {
      setPageStart(display.getRowCount() - getPageSize());
    }
  }

  /**
   * Advance the starting row by 'pageSize' rows.
   */
  protected void nextPage() {
    if (display != null) {
      Range range = display.getVisibleRange();
      setPageStart(range.getStart() + range.getLength());
    }
  }

  /**
   * Called when the range or row count changes. Implement this method to update
   * the pager.
   */
  protected abstract void onRangeOrRowCountChanged();

  /**
   * Move the starting row back by 'pageSize' rows.
   */
  protected void previousPage() {
    if (display != null) {
      Range range = display.getVisibleRange();
      setPageStart(range.getStart() - range.getLength());
    }
  }

  /**
   * Go to a specific page.
   *
   * @param index the page index
   * @see #getPage()
   */
  protected void setPage(int index) {
    if (display != null
        && (!isRangeLimited || !display.isRowCountExact() || hasPage(index))) {
      // We don't use the local version of setPageStart because it would
      // constrain the index, but the user probably wants to use absolute page
      // indexes.
      int pageSize = getPageSize();
      display.setVisibleRange(pageSize * index, pageSize);
    }
  }

  /**
   * Set the page size of the display.
   *
   * @param pageSize the new page size
   * @see #getPageSize()
   */
  protected void setPageSize(int pageSize) {
    if (display != null) {
      Range range = display.getVisibleRange();
      int pageStart = range.getStart();
      if (isRangeLimited && display.isRowCountExact()) {
        pageStart = Math.min(pageStart, display.getRowCount() - pageSize);
      }
      pageStart = Math.max(0, pageStart);
      display.setVisibleRange(pageStart, pageSize);
    }
  }

  /**
   * Set the page start index.
   *
   * @param index the index
   * @see #getPageStart()
   */
  protected void setPageStart(int index) {
    if (display != null) {
      Range range = display.getVisibleRange();
      int pageSize = range.getLength();
      if (isRangeLimited && display.isRowCountExact()) {
        index = Math.min(index, display.getRowCount() - pageSize);
      }
      index = Math.max(0, index);
      if (index != range.getStart()) {
        display.setVisibleRange(index, pageSize);
      }
    }
  }

  /**
   * Called when the row count changes. Only called if display is non-null.
   *
   * @param rowCount the new row count
   * @param isExact true if the row count is exact
   */
  private void handleRowCountChange(int rowCount, boolean isExact) {
    int oldRowCount = lastRowCount;
    lastRowCount = display.getRowCount();

    // If the row count has changed, limit the range.
    if (isRangeLimited && oldRowCount != lastRowCount) {
      setPageStart(getPageStart());
    }

    // Call user methods.
    onRangeOrRowCountChanged();
  }
}
