package joshie.harvest.shops.gui;
import joshie.harvest.api.shops.IPurchasable;
import joshie.harvest.api.shops.IPurchaseableMaterials;
import joshie.harvest.api.shops.IRequirement;
import joshie.harvest.api.shops.Shop;
import joshie.harvest.core.HFTrackers;
import joshie.harvest.core.base.gui.ContainerNull;
import joshie.harvest.core.helpers.MCClientHelper;
import joshie.harvest.core.helpers.StackRenderHelper;
import joshie.harvest.core.helpers.TextHelper;
import joshie.harvest.core.lib.HFModInfo;
import joshie.harvest.npcs.NPCHelper;
import joshie.harvest.npcs.entity.EntityNPC;
import joshie.harvest.npcs.gui.GuiNPCBase;
import joshie.harvest.player.stats.StatsClient;
import joshie.harvest.shops.data.ShopData;
import joshie.harvest.shops.gui.button.*;
import joshie.harvest.shops.purchasable.PurchasableBuilding;
import joshie.harvest.town.TownHelper;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GuiNPCShop extends GuiNPCBase {
static final ResourceLocation SHOP_BACKGROUND = new ResourceLocation(HFModInfo.MODID, "textures/gui/shop.png");
public static final ResourceLocation SHOP_EXTRA = new ResourceLocation(HFModInfo.MODID, "textures/gui/shop_extra.png");
private final List<IPurchasable> contents = new ArrayList<>();
protected final StatsClient stats;
protected final EntityPlayer client;
protected final Shop shop;
public final boolean selling;
protected int start;
private int maxSize;
private ItemStack purchased;
public GuiNPCShop(EntityPlayer player, EntityNPC npc, int nextGui, boolean isSelling) {
super(new ContainerNull(), player, npc, nextGui);
client = player;
shop = npc.getNPC().getShop(player.worldObj, pos, player);
if (shop == null || !NPCHelper.isShopOpen(npc.worldObj, npc, player, npc.getNPC().getShop(npc.worldObj, pos, player))) player.closeScreen();
stats = HFTrackers.getClientPlayerTracker().getStats();
selling = isSelling;
}
@Override
public void initGui() {
super.initGui();
reload();
setStart(0);
}
@Override
protected boolean isChat() {
return false;
}
private boolean isGoldOnly(IPurchasable purchasable) {
if (purchasable instanceof IPurchaseableMaterials) {
IPurchaseableMaterials builder = (IPurchaseableMaterials) purchasable;
return builder.getCost() != 0 && builder.getRequirements().length == 0;
} else return true;
}
private int getPriorityValue(IPurchasable purchasable) {
if (purchasable instanceof PurchasableBuilding) {
if (isGoldOnly(purchasable)) return 10000;
IPurchaseableMaterials materials = ((IPurchaseableMaterials)purchasable);
return (materials.getCost() > 0 ? 10001 : 10000) - materials.getRequirements().length;
} else {
if (isGoldOnly(purchasable)) return 0;
IPurchaseableMaterials materials = ((IPurchaseableMaterials)purchasable);
return (materials.getCost() > 0 ? 1 : 0) + materials.getRequirements().length;
}
}
@SuppressWarnings("all")
public void reload() {
contents.clear();
ShopData data = TownHelper.getClosestTownToEntity(MCClientHelper.getPlayer(), false).getShops();
for (IPurchasable purchasable: shop.getContents()) {
if (isAllowedInShop(purchasable) && purchasable.canList(client.worldObj, client) && data.canList(shop, purchasable)) {
contents.add(purchasable);
}
}
contents.sort((s1, s2)-> ((Integer)getPriorityValue(s2)).compareTo(getPriorityValue(s1)));
setStart(start);
}
private boolean isAllowedInShop(IPurchasable purchasable) {
return (selling && purchasable.getCost() < 0) || (!selling && purchasable.getCost() >= 0);
}
public int getStart() {
return start;
}
private int getMaxSize() {
return maxSize;
}
public Shop getShop() {
return shop;
}
@Override
protected void mouseClicked(int x, int y, int mouseButton) throws IOException {
super.mouseClicked(x, y, mouseButton);
if (selectedButton == null) {
updatePurchased(null, 0);
}
}
@SuppressWarnings("unchecked")
public void setStart(int i) {
buttonList.clear();
//Up arrow
buttonList.add(new ButtonArrow(this, -1, 225, 0, guiLeft + 232, guiTop + 60) {
@Override
protected void updateVisiblity() {
visible = shop.getStart() != 0;
}
});
//Down arrow
buttonList.add(new ButtonArrow(this, +1, 242, 1, guiLeft + 232, guiTop + 210) {
@Override
protected void updateVisiblity() {
visible = shop.getStart() < shop.getMaxSize();
}
});
maxSize = contents.size() - getMax();
start = Math.max(0, Math.min(maxSize, i));
int id = start;
int position = 0;
int pPosition = 0;
ShopData data = TownHelper.getClosestTownToEntity(MCClientHelper.getPlayer(), false).getShops();
Iterator<IPurchasable> it = contents.iterator();
while (it.hasNext() && position <= 180) {
IPurchasable purchasable = it.next();
if (pPosition >= start && purchasable.canList(client.worldObj, client) && data.canList(shop, purchasable)) {
if (purchasable.getCost() < 0) {
buttonList.add(new ButtonListing(this, purchasable, id + 2, guiLeft + 28, 38 + guiTop + position));
position += 20;
} else position += addButton(purchasable, id + 2, guiLeft + 28, 38 + guiTop + position, position);
id++;
}
pPosition++;
}
if (buttonList.size() == 2) buttonList.add(new ButtonListingOutOfStock(this, 3, guiLeft + 28, 38 + guiTop + position));
}
private int addButton(IPurchasable purchasable, int id, int left, int top, int space) {
if (isGoldOnly(purchasable)) {
if (space + 20 <= 200) {
buttonList.add(new ButtonListing(this, purchasable, id, left, top));
return 20;
}
} else {
IPurchaseableMaterials builder = (IPurchaseableMaterials) purchasable;
if (builder.getRequirements().length == 1 && builder.getCost() == 0) {
if (space + 20 <= 200) {
IRequirement requirement = builder.getRequirements()[0];
buttonList.add(new ButtonListingItem(requirement, this, builder, id, left, top));
return 20;
}
} else if (space + 20 <= 200) {
buttonList.add(new ButtonListingBuilding(this, builder, id, left, top));
return 20;
}
}
return 0;
}
private void drawResizableBackground(int x, int y) {
mc.renderEngine.bindTexture(SHOP_BACKGROUND);
if (buttonList.size() < 12) {
drawTexturedModalRect(x, y - 12 + (20 * (buttonList.size())), 0, 228, xSize, 28);
drawTexturedModalRect(x, y, 0, 0, xSize, (20 * (buttonList.size())) - 2);
} else drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
}
public void updatePurchased(ItemStack stack, int amount) {
if (stack == null) purchased = null;
else if (purchased == null || !ItemStack.areItemsEqual(purchased, stack)) purchased = stack.copy();
else purchased.stackSize += amount;
}
@Override
protected void drawTooltip(List<String> list, int x, int y) {
if (purchased == null) super.drawTooltip(list, x, y);
else super.drawTooltip(list, x + 16, y + 16);
}
@Override
public void drawBackground(int x, int y) {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
drawResizableBackground(x, y);
ShopFontRenderer.render(this, x + 20, guiTop + 17, shop.getLocalizedName(), false);
drawCoinage(x, guiTop + 19, stats.getGold());
drawPlayerInventory();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
private void drawPlayerInventory() {
if (selling) ShopFontRenderer.render(this, guiLeft + 250, guiTop + 27, "SELLING", false);
else ShopFontRenderer.render(this, guiLeft + 250, guiTop + 27, "BUYING", false);
mc.renderEngine.bindTexture(SHOP_EXTRA);
drawTexturedModalRect(guiLeft + 240, guiTop + 40, 0, 62, 100, 194);
int x2 = 0, y2 = 0;
boolean first = true;
ShopFontRenderer.render(this, guiLeft + 240, guiTop + 44, "Inventory", false);
for (ItemStack stack: MCClientHelper.getPlayer().inventory.mainInventory) {
if (stack != null) {
StackRenderHelper.drawStack(stack, guiLeft + 253 + y2, guiTop + 61 + x2 * 18, 1F);
}
x2++;
if (x2 >= 9) {
x2 = 0;
if (first) {
y2 += 22;
first = false;
} else {
y2 += 18;
}
}
}
}
public String getCostAsString(long cost) {
if (cost == 0) return TextHelper.translate("shop.free");
if (cost < 0) cost = -cost;
if (cost < 1000) return "" + cost;
long remainder = cost % 1000;
int decimal = remainder == 0 ? 0 : remainder % 100 == 0 ? 1: remainder %10 == 0 ? 2: 3;
int exp = (int) (Math.log(cost) / Math.log(1000));
return String.format("%." + decimal + "f%c", cost / Math.pow(1000, exp), "kMGTPE".charAt(exp-1));
}
private static final DecimalFormat formatter = new DecimalFormat("#,###");
private void drawCoinage(int x, int y, long gold) {
String formatted = String.valueOf(formatter.format(gold));
ShopFontRenderer.render(this, x + 220, y, formatted, true);
GlStateManager.disableDepth();
mc.renderEngine.bindTexture(HFModInfo.ELEMENTS);
mc.ingameGUI.drawTexturedModalRect((x + 224), y - 1, 244, 0, 12, 12);
GlStateManager.enableDepth();
}
@Override
public void drawForeground(int x, int y) {
if (purchased != null) {
StackRenderHelper.drawStack(purchased, mouseX, mouseY, 1F);
}
}
@Override
public void drawOverlay(int x, int y) {}
@Override
protected void keyTyped(char character, int key) throws IOException {
if (key == 208 || character == 's') {
setStart(start + 2);
}
if (key == 200 || character == 'w') {
setStart(start - 2);
}
super.keyTyped(character, key);
}
public void scroll(int amount) {
setStart(start + amount);
}
@Override
public void handleMouseInput() throws IOException {
super.handleMouseInput();
if (mouseWheel != 0) {
if (mouseWheel < 0) setStart(start + 1);
else setStart(start - 1);
}
}
public int getMax() {
return 10;
}
}