package eu.dnetlib.domain.functionality;

import java.util.SortedSet;

/**
 * This class represents a single page of objects which is part of a multi-page sequence.
 * @author thanos
 * @see eu.dnetlib.api.functionality.NotificationService
 * @see eu.dnetlib.api.functionality.AlertService
 * @param <E> the type of the objects contained in this page
 * 
 */
public class ObjectPage<E> {
	private int pageNumber;
	private int pageSize;
	private int totalObjects;
	private SortedSet<E> objects;

	/**
	 * Construct a new object page.
	 * @param pageNumber the number of this page
	 * @param pageSize the size of this page
	 * @param totalObjects the total number of available objects
	 * @param objects the objects contained in this page
	 */
	public ObjectPage(final int pageNumber, final int pageSize, final int totalObjects, final SortedSet<E> objects) {
		this.pageNumber = pageNumber;
		this.pageSize = pageSize;
		this.totalObjects = totalObjects;
		this.objects = objects;
	}
	
	/**
	 * Construct a new object page with page number, page size and total objects set to zero and objects set to null.
	 */
	public ObjectPage() {
		this(0, 0, 0, null);
	}

	/**
	 * Get the page number.
	 * @return the page number of this object page
	 */
	public int getPageNumber() {
		return pageNumber;
	}
	
	/**
	 * Set the page number.
	 * @param pageNumber the page number of this object page
	 */
	public void setPageNumber(final int pageNumber) {
		this.pageNumber = pageNumber;
	}

	/**
	 * Get the page size.
	 * @return the page size of this object page
	 */
	public int getPageSize() {
		return pageSize;
	}
	
	/**
	 * Set the page size.
	 * @param pageSize the page size of this object page
	 */
	public void setPageSize(final int pageSize) {
		this.pageSize = pageSize;
	}

	/**
	 * Get the total objects.
	 * @return the total objects of this page
	 */
	public int getTotalObjects() {
		return totalObjects;
	}
	
	/**
	 * Set the total objects.
	 * @param totalObjects the total objects of this page
	 */
	public void setTotalObjects(final int totalObjects) {
		this.totalObjects = totalObjects;
	}

	/**
	 * Get the objects.
	 * @return the objects of this page
	 */
	public SortedSet<E> getObjects() {
		return objects;
	}
	
	/**
	 * Set the objects.
	 * @param objects the objects of this page
	 */
	public void setObjects(SortedSet<E> objects) {
		this.objects = objects;
	}
	
	/**
	 * Get the first object.
	 * @return the number of the first object of this page
	 */
	public int getFrom() {
		return pageNumber * pageSize;
	}
	
	/**
	 * Get the last object.
	 * @return the number of the last object of this page
	 */
	public int getTo() {
		final int to = (pageNumber + 1) * pageSize;
		return (to > totalObjects) ? totalObjects : to;
	}
	
	/**
	 * Get the total pages.
	 * @return the total number of available pages
	 */
	public int getTotalPages() {
		return (int) Math.ceil((float) totalObjects / pageSize);
	}
	
	@Override
	public String toString() {
		return getFrom() + " - " + getTo() + " of " + totalObjects + " (page " + pageNumber + " of " + getTotalPages() + ", page size " + pageSize + ")";
	}
}
