PageableGUI.java
package it.fulminazzo.yagl.guis;
import it.fulminazzo.yagl.Metadatable;
import it.fulminazzo.yagl.actions.BiGUIAction;
import it.fulminazzo.yagl.actions.GUIAction;
import it.fulminazzo.yagl.contents.GUIContent;
import it.fulminazzo.yagl.contents.ItemGUIContent;
import it.fulminazzo.yagl.items.Item;
import it.fulminazzo.yagl.viewers.Viewer;
import it.fulminazzo.fulmicollection.objects.FieldEquable;
import it.fulminazzo.fulmicollection.structures.tuples.Tuple;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* An implementation of {@link GUI} that allows multiple GUI pages to be added.
*/
public class PageableGUI extends FieldEquable implements Iterable<GUI>, Metadatable, GUI {
protected final @NotNull GUI templateGUI;
private final List<GUI> pages = new LinkedList<>();
private final Map<String, String> variables = new HashMap<>();
protected final Tuple<Integer, GUIContent> previousPage = new Tuple<>();
protected final Tuple<Integer, GUIContent> nextPage = new Tuple<>();
/**
* Instantiates a new Pageable gui.
*/
PageableGUI() {
this.templateGUI = new DefaultGUI();
}
/**
* Instantiates a new Pageable gui.
*
* @param size the size
*/
PageableGUI(final int size) {
this.templateGUI = GUI.newGUI(size);
}
/**
* Instantiates a new Pageable gui.
*
* @param type the type
*/
PageableGUI(final @NotNull GUIType type) {
this.templateGUI = GUI.newGUI(type);
}
/**
* Gets the number of pages
*
* @return the pages
*/
public int pages() {
return this.pages.size();
}
/**
* Gets the {@link GUI} page from the given index.
* The index starts from <b>0</b>.
*
* @param page the page
* @return the corresponding {@link GUI} page
*/
public @NotNull GUI getPage(final int page) {
try {
return this.pages.get(page);
} catch (IndexOutOfBoundsException e) {
throw new IndexOutOfBoundsException(String.format("Could not find page '%s'", page));
}
}
/**
* Sets pages.
*
* @param pages the pages
* @return this gui
*/
public @NotNull PageableGUI setPages(final int pages) {
if (pages < 0) throw new IllegalArgumentException(String.format("Invalid pages '%s'", pages));
int s;
while ((s = this.pages.size()) - pages > 0) this.pages.remove(s - 1);
while (pages - this.pages.size() > 0) this.pages.add(this.templateGUI.copy());
return this;
}
/**
* Sets the previous page content.
* When clicking on it, the previous page will be opened.
*
* @param slot the slot
* @param previousPage the previous page
* @return the previous page
*/
public @NotNull PageableGUI setPreviousPage(final int slot, final @NotNull Item previousPage) {
return setPreviousPage(slot, (GUIContent) ItemGUIContent.newInstance(previousPage));
}
/**
* Sets the previous page content.
* When clicking on it, the previous page will be opened.
*
* @param slot the slot
* @param previousPage the previous page
* @return the previous page
*/
public @NotNull PageableGUI setPreviousPage(final int slot, final @NotNull GUIContent previousPage) {
this.previousPage.set(checkSlot(slot), previousPage);
return this;
}
/**
* Removes the previous page set with {@link #setPreviousPage(int, GUIContent)}.
*
* @return the pageable gui
*/
public @NotNull PageableGUI unsetPreviousPage() {
this.previousPage.set(null, null);
return this;
}
/**
* Sets the next page content.
* When clicking on it, the next page will be opened.
*
* @param slot the slot
* @param nextPage the next page
* @return the next page
*/
public @NotNull PageableGUI setNextPage(final int slot, final @NotNull Item nextPage) {
return setNextPage(slot, (GUIContent) ItemGUIContent.newInstance(nextPage));
}
/**
* Sets the next page content.
* When clicking on it, the next page will be opened.
*
* @param slot the slot
* @param nextPage the next page
* @return the next page
*/
public @NotNull PageableGUI setNextPage(final int slot, final @NotNull GUIContent nextPage) {
this.nextPage.set(checkSlot(slot), nextPage);
return this;
}
/**
* Removes the next page set with {@link #setNextPage(int, GUIContent)}.
*
* @return the pageable gui
*/
public @NotNull PageableGUI unsetNextPage() {
this.nextPage.set(null, null);
return this;
}
private int checkSlot(final int slot) {
if (slot < 0 || slot > size()) {
final String message = String.format("'slot' must be between %s and %s", 0, size());
throw new IllegalArgumentException(message);
}
return slot;
}
@NotNull
@Override
public Iterator<GUI> iterator() {
return this.pages.iterator();
}
/**
* Opens the current GUI for the given viewer at the first page.
*
* @param viewer the viewer
*/
@Override
public void open(final @NotNull Viewer viewer) {
open(viewer, 0);
}
/**
* Opens the current GUI for the given viewer at the specified page.
*
* @param viewer the viewer
* @param page the page
*/
public void open(final @NotNull Viewer viewer, final int page) {
prepareOpenGUI(getPage(page), page).open(viewer);
}
/**
* Prepares the {@link GUI} at the given page for {@link #open(Viewer, int)}.
*
* @param gui the gui
* @param page the page
* @return the gui
*/
protected @NotNull GUI prepareOpenGUI(final @NotNull GUI gui, final int page) {
GUI newGUI = gui.copy().copyFrom(this, false)
.setVariable("page", String.valueOf(page + 1))
.setVariable("previous_page", String.valueOf(page))
.setVariable("next_page", String.valueOf(page + 2))
.setVariable("pages", String.valueOf(pages()));
if (page > 0) this.previousPage.ifPresent((s, p) ->
newGUI.setContents(s, p.copy().onClickItem((v, g, i) -> open(v, page - 1))));
if (page + 1 < pages()) this.nextPage.ifPresent((s, p) ->
newGUI.setContents(s, p.copy().onClickItem((v, g, i) -> open(v, page + 1))));
return newGUI;
}
/**
* Counts the empty slots of the current GUI.
* If {@link #setPreviousPage(int, GUIContent)} or {@link #setNextPage(int, GUIContent)}
* were used, their slots are removed from the final count.
*
* @return the slots
*/
@Override
public @NotNull Set<Integer> emptySlots() {
final Set<Integer> slots = GUI.super.emptySlots();
this.previousPage.ifPresent((i, p) -> slots.remove(i));
this.nextPage.ifPresent((i, p) -> slots.remove(i));
return slots;
}
@Override
public @NotNull PageableGUI setTitle(final @Nullable String title) {
this.templateGUI.setTitle(title);
return this;
}
@Override
public @Nullable String getTitle() {
return this.templateGUI.getTitle();
}
@Override
public int size() {
return this.templateGUI.size();
}
@Override
public boolean isMovable(int slot) {
return this.templateGUI.isMovable(slot);
}
@Override
public @NotNull PageableGUI setMovable(int slot, boolean movable) {
this.templateGUI.setMovable(slot, movable);
return this;
}
@Override
public @NotNull List<GUIContent> getContents(int slot) {
return this.templateGUI.getContents(slot);
}
@Override
public @NotNull List<GUIContent> getContents() {
return this.templateGUI.getContents();
}
@Override
public @NotNull PageableGUI addContent(GUIContent @NotNull ... contents) {
this.templateGUI.addContent(contents);
return this;
}
@Override
public @NotNull PageableGUI setContents(int slot, GUIContent @NotNull ... contents) {
this.templateGUI.setContents(slot, contents);
return this;
}
@Override
public int rows() {
return this.templateGUI.rows();
}
@Override
public int columns() {
return this.templateGUI.columns();
}
@Override
public @NotNull PageableGUI clear() {
this.templateGUI.clear();
return this;
}
@Override
public @NotNull PageableGUI setContents(int slot, @NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setContents(slot, contents);
}
@Override
public @NotNull PageableGUI unsetContent(int slot) {
this.templateGUI.unsetContent(slot);
return this;
}
@Override
public @NotNull PageableGUI onClickOutside(final @NotNull GUIAction action) {
this.templateGUI.onClickOutside(action);
return this;
}
@Override
public @NotNull Optional<GUIAction> clickOutsideAction() {
return this.templateGUI.clickOutsideAction();
}
@Override
public @NotNull PageableGUI onOpenGUI(final @NotNull GUIAction action) {
this.templateGUI.onOpenGUI(action);
return this;
}
@Override
public @NotNull Optional<GUIAction> openGUIAction() {
return this.templateGUI.openGUIAction();
}
@Override
public @NotNull PageableGUI onCloseGUI(final @NotNull GUIAction action) {
this.templateGUI.onCloseGUI(action);
return this;
}
@Override
public @NotNull Optional<GUIAction> closeGUIAction() {
return this.templateGUI.closeGUIAction();
}
@Override
public @NotNull PageableGUI onChangeGUI(final @NotNull BiGUIAction action) {
this.templateGUI.onChangeGUI(action);
return this;
}
@Override
public @NotNull Optional<BiGUIAction> changeGUIAction() {
return this.templateGUI.changeGUIAction();
}
@Override
public @NotNull PageableGUI setAllMovable() {
return (PageableGUI) GUI.super.setAllMovable();
}
@Override
public @NotNull PageableGUI setAllUnmovable() {
return (PageableGUI) GUI.super.setAllUnmovable();
}
@Override
public @NotNull PageableGUI addContent(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.addContent(contents);
}
@Override
public @NotNull PageableGUI addContent(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.addContent(contents);
}
@Override
public @NotNull PageableGUI setContents(int slot, Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setContents(slot, contents);
}
@Override
public @NotNull PageableGUI setContents(int slot, ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setContents(slot, contents);
}
@Override
public @NotNull PageableGUI setAllSides(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setAllSides(contents);
}
@Override
public @NotNull PageableGUI setAllSides(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setAllSides(contents);
}
@Override
public @NotNull PageableGUI setAllSides(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setAllSides(contents);
}
@Override
public @NotNull PageableGUI setAllSides(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setAllSides(contents);
}
@Override
public @NotNull PageableGUI unsetAllSides() {
return (PageableGUI) GUI.super.unsetAllSides();
}
@Override
public @NotNull PageableGUI setTopAndBottomSides(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopAndBottomSides(contents);
}
@Override
public @NotNull PageableGUI setTopAndBottomSides(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopAndBottomSides(contents);
}
@Override
public @NotNull PageableGUI setTopAndBottomSides(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopAndBottomSides(contents);
}
@Override
public @NotNull PageableGUI setTopAndBottomSides(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setTopAndBottomSides(contents);
}
@Override
public @NotNull PageableGUI unsetTopAndBottomSides() {
return (PageableGUI) GUI.super.unsetTopAndBottomSides();
}
@Override
public @NotNull PageableGUI setLeftAndRightSides(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftAndRightSides(contents);
}
@Override
public @NotNull PageableGUI setLeftAndRightSides(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftAndRightSides(contents);
}
@Override
public @NotNull PageableGUI setLeftAndRightSides(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftAndRightSides(contents);
}
@Override
public @NotNull PageableGUI setLeftAndRightSides(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setLeftAndRightSides(contents);
}
@Override
public @NotNull PageableGUI unsetLeftAndRightSides() {
return (PageableGUI) GUI.super.unsetLeftAndRightSides();
}
@Override
public @NotNull PageableGUI setTopSide(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopSide(contents);
}
@Override
public @NotNull PageableGUI setTopSide(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopSide(contents);
}
@Override
public @NotNull PageableGUI setTopSide(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setTopSide(contents);
}
@Override
public @NotNull PageableGUI setTopSide(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setTopSide(contents);
}
@Override
public @NotNull PageableGUI unsetTopSide() {
return (PageableGUI) GUI.super.unsetTopSide();
}
@Override
public @NotNull PageableGUI setLeftSide(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftSide(contents);
}
@Override
public @NotNull PageableGUI setLeftSide(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftSide(contents);
}
@Override
public @NotNull PageableGUI setLeftSide(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setLeftSide(contents);
}
@Override
public @NotNull PageableGUI setLeftSide(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setLeftSide(contents);
}
@Override
public @NotNull PageableGUI unsetLeftSide() {
return (PageableGUI) GUI.super.unsetLeftSide();
}
@Override
public @NotNull PageableGUI setBottomSide(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setBottomSide(contents);
}
@Override
public @NotNull PageableGUI setBottomSide(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setBottomSide(contents);
}
@Override
public @NotNull PageableGUI setBottomSide(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setBottomSide(contents);
}
@Override
public @NotNull PageableGUI setBottomSide(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setBottomSide(contents);
}
@Override
public @NotNull PageableGUI unsetBottomSide() {
return (PageableGUI) GUI.super.unsetBottomSide();
}
@Override
public @NotNull PageableGUI setRightSide(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setRightSide(contents);
}
@Override
public @NotNull PageableGUI setRightSide(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setRightSide(contents);
}
@Override
public @NotNull PageableGUI setRightSide(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setRightSide(contents);
}
@Override
public @NotNull PageableGUI setRightSide(@NotNull Collection<GUIContent> contents) {
return (PageableGUI) GUI.super.setRightSide(contents);
}
@Override
public @NotNull PageableGUI unsetRightSide() {
return (PageableGUI) GUI.super.unsetRightSide();
}
@Override
public @NotNull PageableGUI setNorthWest(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthWest(contents);
}
@Override
public @NotNull PageableGUI setNorthWest(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthWest(contents);
}
@Override
public @NotNull PageableGUI setNorthWest(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthWest(contents);
}
@Override
public @NotNull PageableGUI unsetNorthWest() {
return (PageableGUI) GUI.super.unsetNorthWest();
}
@Override
public @NotNull PageableGUI setNorth(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorth(contents);
}
@Override
public @NotNull PageableGUI setNorth(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorth(contents);
}
@Override
public @NotNull PageableGUI setNorth(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorth(contents);
}
@Override
public @NotNull PageableGUI unsetNorth() {
return (PageableGUI) GUI.super.unsetNorth();
}
@Override
public @NotNull PageableGUI setNorthEast(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthEast(contents);
}
@Override
public @NotNull PageableGUI setNorthEast(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthEast(contents);
}
@Override
public @NotNull PageableGUI setNorthEast(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setNorthEast(contents);
}
@Override
public @NotNull PageableGUI unsetNorthEast() {
return (PageableGUI) GUI.super.unsetNorthEast();
}
@Override
public @NotNull PageableGUI setMiddleWest(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleWest(contents);
}
@Override
public @NotNull PageableGUI setMiddleWest(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleWest(contents);
}
@Override
public @NotNull PageableGUI setMiddleWest(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleWest(contents);
}
@Override
public @NotNull PageableGUI unsetMiddleWest() {
return (PageableGUI) GUI.super.unsetMiddleWest();
}
@Override
public @NotNull PageableGUI setMiddle(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddle(contents);
}
@Override
public @NotNull PageableGUI setMiddle(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddle(contents);
}
@Override
public @NotNull PageableGUI setMiddle(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddle(contents);
}
@Override
public @NotNull PageableGUI unsetMiddle() {
return (PageableGUI) GUI.super.unsetMiddle();
}
@Override
public @NotNull PageableGUI setMiddleEast(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleEast(contents);
}
@Override
public @NotNull PageableGUI setMiddleEast(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleEast(contents);
}
@Override
public @NotNull PageableGUI setMiddleEast(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setMiddleEast(contents);
}
@Override
public @NotNull PageableGUI unsetMiddleEast() {
return (PageableGUI) GUI.super.unsetMiddleEast();
}
@Override
public @NotNull PageableGUI setSouthWest(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthWest(contents);
}
@Override
public @NotNull PageableGUI setSouthWest(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthWest(contents);
}
@Override
public @NotNull PageableGUI setSouthWest(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthWest(contents);
}
@Override
public @NotNull PageableGUI unsetSouthWest() {
return (PageableGUI) GUI.super.unsetSouthWest();
}
@Override
public @NotNull PageableGUI setSouth(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouth(contents);
}
@Override
public @NotNull PageableGUI setSouth(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouth(contents);
}
@Override
public @NotNull PageableGUI setSouth(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouth(contents);
}
@Override
public @NotNull PageableGUI unsetSouth() {
return (PageableGUI) GUI.super.unsetSouth();
}
@Override
public @NotNull PageableGUI setSouthEast(Item @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthEast(contents);
}
@Override
public @NotNull PageableGUI setSouthEast(ItemGUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthEast(contents);
}
@Override
public @NotNull PageableGUI setSouthEast(GUIContent @NotNull ... contents) {
return (PageableGUI) GUI.super.setSouthEast(contents);
}
@Override
public @NotNull PageableGUI unsetSouthEast() {
return (PageableGUI) GUI.super.unsetSouthEast();
}
@Override
public @NotNull PageableGUI fill(@NotNull Item content) {
return (PageableGUI) GUI.super.fill(content);
}
@Override
public @NotNull PageableGUI fill(@NotNull ItemGUIContent content) {
return (PageableGUI) GUI.super.fill(content);
}
@Override
public @NotNull PageableGUI fill(@NotNull GUIContent content) {
return (PageableGUI) GUI.super.fill(content);
}
@Override
public @NotNull PageableGUI onClickOutside(@NotNull String command) {
return (PageableGUI) GUI.super.onClickOutside(command);
}
@Override
public @NotNull PageableGUI onOpenGUI(@NotNull String command) {
return (PageableGUI) GUI.super.onOpenGUI(command);
}
@Override
public @NotNull PageableGUI onCloseGUI(@NotNull String command) {
return (PageableGUI) GUI.super.onCloseGUI(command);
}
@Override
public @NotNull PageableGUI onChangeGUI(@NotNull String command) {
return (PageableGUI) GUI.super.onChangeGUI(command);
}
@Override
public @NotNull PageableGUI setVariable(@NotNull String name, @NotNull String value) {
return (PageableGUI) GUI.super.setVariable(name, value);
}
@Override
public @NotNull PageableGUI unsetVariable(@NotNull String name) {
return (PageableGUI) GUI.super.unsetVariable(name);
}
@Override
public @NotNull PageableGUI copyAll(@NotNull GUI other, boolean replace) {
return (PageableGUI) GUI.super.copyAll(other, replace);
}
@Override
public @NotNull PageableGUI copyFrom(@NotNull GUI other, boolean replace) {
return (PageableGUI) GUI.super.copyFrom(other, replace);
}
@Override
public PageableGUI copy() {
return (PageableGUI) GUI.super.copy();
}
@Override
public @NotNull PageableGUI copyAll(@NotNull Metadatable other, boolean replace) {
return (PageableGUI) GUI.super.copyAll(other, replace);
}
@Override
public @NotNull PageableGUI copyFrom(@NotNull Metadatable other, boolean replace) {
return (PageableGUI) GUI.super.copyFrom(other, replace);
}
/**
* Creates a new {@link PageableGUI} with the given size.
*
* @param size the size
* @return the pageable gui
*/
public static @NotNull PageableGUI newGUI(final int size) {
return new PageableGUI(size);
}
/**
* Creates a new {@link PageableGUI} with the given type.
*
* @param type the type
* @return the pageable gui
*/
public static @NotNull PageableGUI newGUI(final @NotNull GUIType type) {
return new PageableGUI(type);
}
@Override
public @NotNull Map<String, String> variables() {
return this.variables;
}
}