package com.lucasdnd.ags.ui;
import java.util.ArrayList;
import java.util.Collections;
import org.newdawn.slick.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.util.FontUtils;
import com.lucasdnd.ags.gameplay.Business;
import com.lucasdnd.ags.system.ResourceLoader;
public abstract class List extends UIComponent {
// Headers, List Items, Buttons. Basic stuff
protected ListHeader[] listHeaders;
protected ArrayList<ListRow> listRows;
protected int currentSort; // The column it is being sorted by
protected Button nextPageButton; // The Up Arrow Button, used to scroll the items
protected Button previousPageButton; // The Down Arrow Button, used to scroll the items
// The sizes, padding, margins, etc.
protected float lineSize = 27f; // The size of one row in the list
protected final float leftMargin = 19f; // Left margin, between the List and the left border of the Panel
protected final float topMargin = 3f; // Top margin, between the List and the Tile Bar
// Paging
protected int pageSize = 18; // The amount of items that can fit one page
protected int page = 0; // The current page
/**
* Basic Constructor
* @throws SlickException
*/
public List(float xPos, float yPos, float width, float height) throws SlickException {
this.xPos = xPos;
this.yPos = yPos;
this.width = width;
this.height = height;
// Create the Buttons
nextPageButton = new Button(ResourceLoader.getInstance().nextPageButtonImages,
(int)this.xPos + (int)this.width - lineSize * 2,
(int)this.yPos + (int)this.height - lineSize - lineSize / 3);
previousPageButton = new Button(ResourceLoader.getInstance().previousPageButtonImages,
(int)this.xPos + (int)this.width - lineSize * 6,
(int)this.yPos + (int)this.height - lineSize - lineSize / 3);
}
/**
* Update
* @param container
* @param game
* @param delta
* @param business
* @param leftMouseClicked
* @param mouseX
* @param mouseY
* @throws SlickException
*/
public void update(GameContainer container, StateBasedGame game, int delta, Business business,
boolean leftMouseClicked, boolean leftMouseDown, int mouseX, int mouseY) throws SlickException {
// Button Hover
nextPageButton.update(container, game, delta, leftMouseClicked, leftMouseDown, mouseX, mouseY);
previousPageButton.update(container, game, delta, leftMouseClicked, leftMouseDown, mouseX, mouseY);
// Page Buttons
if(nextPageButton.gotLeftClicked(leftMouseClicked, mouseX, mouseY)) {
if(pageSize * (page + 1) < listRows.size()) {
// Next Page
page++;
updateRowsPositions();
// Then we reset the rectangles around the Rows
for(int i = 0; i < listRows.size(); i++) {
if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) {
listRows.get(i).createRectangle();
}
}
}
} else if (previousPageButton.gotLeftClicked(leftMouseClicked, mouseX, mouseY)) {
if(page > 0) {
// Previous Page
page--;
updateRowsPositions();
// Then we reset the rectangles around the Rows
for(int i = 0; i < listRows.size(); i++) {
if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) {
listRows.get(i).createRectangle();
}
}
}
}
}
/**
* Check for list header clicks (sorting)
*
* @param leftMouseClicked
* @param mouseX
* @param mouseY
*/
protected void checkHeaderClicks(boolean leftMouseClicked, int mouseX, int mouseY) {
for(int i = 0; i < listHeaders.length; i++) {
// Check for clicks
if(listHeaders[i].gotLeftClicked(leftMouseClicked, mouseX, mouseY)) {
sortList(i, (currentSort == i ? true : false));
currentSort = i;
this.updateRowsPositions();
for(ListRow lr : listRows)
lr.createRectangle();
}
}
}
/**
* Render
* @param container
* @param game
* @param g
* @throws SlickException
*/
public void render(GameContainer container, StateBasedGame game, Graphics g, Font panelFont, Font disabledFont, Font shadowFont) throws SlickException {
// Renders the List Headers
if (listHeaders != null) {
for(ListHeader lh : listHeaders) {
lh.render(container, game, g, panelFont, disabledFont, shadowFont);
}
}
// Renders the List Rows
for(int i = 0; i < listRows.size(); i++) {
// Here we make sure we render only what's in the current page
if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) {
listRows.get(i).render(container, game, g, panelFont, disabledFont, shadowFont);
}
}
// Renders the Page Number
int safePageSize = 0;
safePageSize = pageSize;
FontUtils.drawRight(shadowFont,
(page + 1) + "/" + (((listRows.size() - 1) / safePageSize) + 1),
1 + (int)this.xPos + (int)this.width - (int)lineSize * 4 + 4,
1 + (int)this.yPos + (int)this.height - (int)lineSize - (int)lineSize / 2 + 6, 30);
FontUtils.drawRight(panelFont,
(page + 1) + "/" + (((listRows.size() - 1) / safePageSize) + 1),
(int)this.xPos + (int)this.width - (int)lineSize * 4 + 4,
(int)this.yPos + (int)this.height - (int)lineSize - (int)lineSize / 2 + 6, 30);
// Renders the Buttons
nextPageButton.render(container, game, g);
previousPageButton.render(container, game, g);
}
/**
* Updates the position and size of the List Rows. This should be called every time the user changes the page he's browsing
*/
public void updateRowsPositions() {
// Goes through each List Row
for(int i = 0; i < listRows.size(); i++) {
// Define the size and dimension of each List Column inside each List Row
for(int j = 0; j < listRows.get(i).getListColumns().length; j++) {
listRows.get(i).getListColumns()[j].setxPos(listHeaders[j].xPos);
listRows.get(i).getListColumns()[j].setyPos(listHeaders[j].yPos + (i + 1 - (page * pageSize)) * lineSize);
listRows.get(i).getListColumns()[j].setWidth(listHeaders[j].width);
listRows.get(i).getListColumns()[j].setHeight(listHeaders[j].height);
}
// Calculate the combined width of the Headers
float combinedHeadersWidth = 0f;
for(int j = 0; j < listHeaders.length; j++) {
combinedHeadersWidth += listHeaders[j].getWidth();
}
// Define the size and dimension of each List Row
listRows.get(i).setxPos(listHeaders[0].getxPos() - 2f);
listRows.get(i).setyPos(listHeaders[0].getyPos() + (lineSize * (i - (page * pageSize))) + lineSize);
listRows.get(i).setWidth(combinedHeadersWidth + 5f);
listRows.get(i).setHeight(listHeaders[0].getHeight() - 2f);
}
}
/**
* Sorts the list based on a column id
* @param columnSort
* @param descending
*/
public void sortList(int columnSort, boolean descending) {
if(descending) {
Collections.reverse(listRows);
} else {
Collections.sort(listRows, new ListRowComparator(columnSort));
}
}
public ArrayList<ListRow> getListItems() {
return listRows;
}
public void setListItems(ArrayList<ListRow> listItems) {
this.listRows = listItems;
}
public ListHeader[] getListHeaders() {
return listHeaders;
}
public void setListHeaders(ListHeader[] listHeaders) {
this.listHeaders = listHeaders;
}
public ArrayList<ListRow> getListRows() {
return listRows;
}
public void setListRows(ArrayList<ListRow> listRows) {
this.listRows = listRows;
}
public Button getUpArrowButton() {
return nextPageButton;
}
public void setUpArrowButton(Button upArrowButton) {
this.nextPageButton = upArrowButton;
}
public Button getDownArrowButton() {
return previousPageButton;
}
public void setDownArrowButton(Button downArrowButton) {
this.previousPageButton = downArrowButton;
}
public int getCurrentSort() {
return currentSort;
}
public void setCurrentSort(int currentSort) {
this.currentSort = currentSort;
}
}