package advancedsystemsmanager.flow.elements;
import advancedsystemsmanager.api.network.IPacketProvider;
import advancedsystemsmanager.client.gui.GuiManager;
import advancedsystemsmanager.helpers.CollisionHelper;
import advancedsystemsmanager.reference.Names;
import advancedsystemsmanager.reference.Null;
import advancedsystemsmanager.registry.ThemeHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.List;
public abstract class ScrollController<T>
{
public static final int ITEM_SIZE = 16;
public static final int ITEM_SIZE_WITH_MARGIN = 20;
public static final int ARROW_SIZE_W = 10;
public static final int ARROW_SIZE_H = 9;
public static final int ARROW_SRC_X = 72;
public static final int ARROW_SRC_Y = 0;
public static final int ARROW_X = 105;
public static final int ARROW_Y_UP = 32;
public static final int ARROW_Y_DOWN = 42;
public static final int TEXT_BOX_SIZE_U = 49;
public static final int TEXT_BOX_SIZE_V = 6;
public static final int TEXT_BOX_SIZE_W = 64;
public static final int TEXT_BOX_SIZE_H = 12;
public static final int TEXT_BOX_SRC_X = 113;
public static final int TEXT_BOX_SRC_Y = 72;
public static final int TEXT_BOX_X = 5;
public static final int TEXT_BOX_Y = 5;
public static final int TEXT_BOX_TEXT_X = 3;
public static final int TEXT_BOX_TEXT_Y = 3;
public static final int CURSOR_X = 2;
public static final int CURSOR_Y = 0;
public static final int CURSOR_Z = 5;
public static final int AMOUNT_TEXT_X = 75;
public static final int AMOUNT_TEXT_Y = 9;
public static final int SCROLL_SPEED = 100;
public int offset;
public boolean canScroll;
public int dir;
public boolean clicked;
public boolean selected;
public TextBoxLogic textBox;
public List<T> result;
public boolean hasSearchBox;
public int itemsPerRow = 5;
public int visibleRows = 2;
public int startX = 5;
public int scrollingUpperLimit = TEXT_BOX_Y + TEXT_BOX_SIZE_H;
public boolean disabledScroll;
public long lastUpdate;
public float left;
protected int x, y;
protected ScrollController()
{
this.hasSearchBox = true;
}
public ScrollController(IPacketProvider packetProvider, boolean hasSearchBox)
{
this(packetProvider, hasSearchBox ? "" : null);
}
public ScrollController(IPacketProvider packetProvider, String defaultText)
{
this.hasSearchBox = defaultText != null;
if (hasSearchBox)
{
textBox = new TextBoxLogic(Null.NULL_PACKET, Integer.MAX_VALUE, TEXT_BOX_SIZE_W - TEXT_BOX_TEXT_X * 2)
{
@Override
public void onUpdate()
{
if (getText().length() > 0)
{
updateSearch();
} else
{
result.clear();
updateScrolling();
}
}
};
textBox.setTextAndCursor(defaultText);
}
updateSearch();
}
public void setX(int val)
{
startX = val;
}
public void onClick(int mX, int mY, int button)
{
if (CollisionHelper.inBounds(x + TEXT_BOX_X, y + TEXT_BOX_Y, TEXT_BOX_SIZE_W, TEXT_BOX_SIZE_H, mX, mY))
{
if (button == 0 || !selected)
{
selected = !selected;
} else if (hasSearchBox)
{
textBox.setTextAndCursor("");
}
}
List<Point> points = getItemCoordinates();
for (Point point : points)
{
if (CollisionHelper.inBounds(point.x, point.y, ITEM_SIZE, ITEM_SIZE, mX, mY))
{
onClick(result.get(point.id), mX, mY, button);
return;
}
}
if (inArrowBounds(true, mX, mY))
{
clicked = true;
dir = 1;
} else if (inArrowBounds(false, mX, mY))
{
clicked = true;
dir = -1;
}
}
public List<Point> getItemCoordinates()
{
List<Point> points = new ArrayList<Point>();
int start = getFirstRow();
for (int row = start; row <= start + getVisibleRows(); row++)
{
for (int col = 0; col < itemsPerRow; col++)
{
int id = row * itemsPerRow + col;
if (id >= 0 && id < result.size())
{
int x = getScrollingStartX() + ITEM_SIZE_WITH_MARGIN * col;
int y = row * ITEM_SIZE_WITH_MARGIN - offset;
if (y >= 0 && y + ITEM_SIZE < getVisibleRows() * ITEM_SIZE_WITH_MARGIN + 5)
{
points.add(new Point(id, this.x + x, this.y + y + getScrollingStartY()));
}
}
}
}
return points;
}
@SideOnly(Side.CLIENT)
public abstract void onClick(T t, int mX, int mY, int button);
public boolean inArrowBounds(boolean down, int mX, int mY)
{
return CollisionHelper.inBounds(x + ARROW_X, y + (down ? ARROW_Y_DOWN : ARROW_Y_UP), ARROW_SIZE_W, ARROW_SIZE_H, mX, mY);
}
public int getFirstRow()
{
return (scrollingUpperLimit + offset - getScrollingStartY()) / ITEM_SIZE_WITH_MARGIN;
}
public int getVisibleRows()
{
return visibleRows;
}
public int getScrollingStartX()
{
return startX;
}
public int getScrollingStartY()
{
return scrollingUpperLimit + 3;
}
public void setVisibleRows(int n)
{
visibleRows = n;
}
public void onRelease(int mX, int mY)
{
clicked = false;
}
@SideOnly(Side.CLIENT)
public boolean onKeyStroke(GuiManager gui, char c, int k)
{
if (selected && hasSearchBox)
{
textBox.onKeyStroke(gui, c, k);
return true;
} else
{
return false;
}
}
@SideOnly(Side.CLIENT)
public void draw(GuiManager gui, int mX, int mY)
{
if (hasSearchBox)
{
gui.drawTextBox(x + TEXT_BOX_X, y + TEXT_BOX_Y, TEXT_BOX_SIZE_W, TEXT_BOX_SIZE_H, TEXT_BOX_SRC_X, TEXT_BOX_SRC_Y, TEXT_BOX_SIZE_U, TEXT_BOX_SIZE_V, (selected? ThemeHandler.theme.menus.textBoxes.selected : ThemeHandler.theme.menus.textBoxes.background).getColour(), ThemeHandler.theme.menus.textBoxes.border.getColour());
gui.drawString(textBox.getText(), x + TEXT_BOX_X + TEXT_BOX_TEXT_X, y + TEXT_BOX_Y + TEXT_BOX_TEXT_Y, ThemeHandler.theme.menus.textBoxes.text.getColourInt());
if (selected)
{
gui.drawCursor(x + TEXT_BOX_X + textBox.getCursorPosition(gui) + CURSOR_X, y + TEXT_BOX_Y + CURSOR_Y, CURSOR_Z, ThemeHandler.theme.menus.textBoxes.text.getColourInt());
}
if (textBox.getText().length() > 0 || result.size() > 0)
{
gui.drawStringFormatted(Names.ITEMS_FOUND, x + AMOUNT_TEXT_X, y + AMOUNT_TEXT_Y, 0.7f, 0x404040, result.size());
}
}
if (result.size() > 0)
{
drawArrow(gui, true, mX, mY);
drawArrow(gui, false, mX, mY);
List<Point> points = getItemCoordinates();
for (Point point : points)
{
draw(gui, result.get(point.id), point.x, point.y, CollisionHelper.inBounds(point.x, point.y, ITEM_SIZE, ITEM_SIZE, mX, mY));
}
}
}
@SideOnly(Side.CLIENT)
public void drawArrow(GuiManager gui, boolean down, int mX, int mY)
{
if (canScroll)
{
// int srcArrowX = clicked && down == (dir == 1) ? 2 : inArrowBounds(down, mX, mY) ? 1 : 0;
int srcArrowY = down ? 1 : 0;
gui.drawTexture(x + ARROW_X, y + (down ? ARROW_Y_DOWN : ARROW_Y_UP), ARROW_SRC_X, ARROW_SRC_Y + srcArrowY * ARROW_SIZE_H, ARROW_SIZE_W, ARROW_SIZE_H);
}
}
@SideOnly(Side.CLIENT)
public abstract void draw(GuiManager gui, T t, int x, int y, boolean hover);
public void update(float partial)
{
if (clicked && canScroll)
{
partial += left;
int change = (int)(partial * SCROLL_SPEED);
left = partial - (change / (float)SCROLL_SPEED);
moveOffset(change * dir);
}
}
public void moveOffset(int change)
{
offset += change;
int min = 0;
int max = ((int)(Math.ceil(((float)result.size() / itemsPerRow)) - getVisibleRows())) * ITEM_SIZE_WITH_MARGIN - (ITEM_SIZE_WITH_MARGIN - ITEM_SIZE);
if (offset < min)
{
offset = min;
} else if (offset > max)
{
offset = max;
}
}
@SideOnly(Side.CLIENT)
public void drawMouseOver(GuiManager gui, int mX, int mY)
{
List<Point> points = getItemCoordinates();
for (Point point : points)
{
if (CollisionHelper.inBounds(point.x, point.y, ITEM_SIZE, ITEM_SIZE, mX, mY))
{
drawMouseOver(gui, result.get(point.id), mX, mY);
break;
}
}
}
@SideOnly(Side.CLIENT)
public abstract void drawMouseOver(GuiManager gui, T t, int mX, int mY);
public void setItemsPerRow(int n)
{
itemsPerRow = n;
}
public void setItemUpperLimit(int n)
{
scrollingUpperLimit = n;
}
public List<T> getResult()
{
return result;
}
public String getText()
{
return textBox.getText();
}
public void setText(String s)
{
textBox.setText(s);
updateSearch();
}
public void updateSearch()
{
if (hasSearchBox)
{
result = updateSearch(textBox.getText().toLowerCase(), textBox.getText().toLowerCase().equals(".all"));
} else
{
result = updateSearch("", false);
}
updateScrolling();
}
public abstract List<T> updateSearch(String search, boolean all);
public void updateScrolling()
{
canScroll = result.size() > itemsPerRow * getVisibleRows();
if (!canScroll)
{
offset = 0;
}
}
public void setTextAndCursor(String s)
{
textBox.setTextAndCursor(s);
}
public void doScroll(int scroll)
{
if (canScroll())
{
moveOffset(scroll / -20);
}
}
public boolean canScroll()
{
return !disabledScroll && result.size() > itemsPerRow;
}
public void setDisabledScroll(boolean disabledScroll)
{
this.disabledScroll = disabledScroll;
}
public long getLastUpdate()
{
return lastUpdate;
}
public class Point
{
protected int id, x, y;
public Point(int id, int x, int y)
{
this.id = id;
this.x = x;
this.y = y;
}
}
}