/*
 * 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 {

  // Visible for testing.
  HandlerRegistration rangeChangeHandler;
  HandlerRegistration rowCountChangeHandler;

  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;

  /**
   * 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();
      rowCountChangeHandler = null;
    }

    // Set the new display.
    this.display = display;
    if (display != null) {
      rangeChangeHandler = display.addRangeChangeHandler(new RangeChangeEvent.Handler() {
        @Override
        public void onRangeChange(RangeChangeEvent event) {
          if (AbstractPager.this.display != null) {
            onRangeOrRowCountChanged();
          }
        }
      });
      rowCountChangeHandler = display.addRowCountChangeHandler(new RowCountChangeEvent.Handler() {
        @Override
        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 || display.getRowCount() == 0) {
      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();
  }
}
