package com.spbsu.crawl.bl.crawlSystemView;
import com.spbsu.crawl.bl.events.InventoryListener;
import com.spbsu.crawl.data.impl.PlayerInfoMessage;
import com.spbsu.crawl.data.impl.system.EmptyFieldsDefault;
/**
* Created by noxoomo on 16/07/16.
*/
public class InventoryView extends Subscribable.Stub<InventoryListener> implements Subscribable<InventoryListener> {
public final static int INVENTORY_SIZE = 52;
private final Item[] inventory = new Item[INVENTORY_SIZE];
private final int[] counts = new int[INVENTORY_SIZE];
private final Updater updater = new Updater();
public Updater updater() {
return updater;
}
class Updater {
private void emptySlot(final int id) {
final int cnt = counts[id];
counts[id] = 0;
inventory[id] = null;
listeners().forEach(inventoryListener -> inventoryListener.remove(id, cnt));
}
private void updateItemCount(final int id,
final int diff) {
if (diff > 0) {
counts[id] += diff;
if (diff > 0) {
listeners().forEach(inventoryListener -> inventoryListener.add(id, diff));
} else {
listeners().forEach(inventoryListener -> inventoryListener.remove(id, -diff));
}
}
}
private boolean isEmptySlot(final int id) {
return counts[id] == 0;
}
private boolean notEmptySlot(final int id) {
return !isEmptySlot(id);
}
private void putItemInSlot(final int id, final Item item, int count) {
if (inventory[id] != null || counts[id] != 0) {
throw new RuntimeException("Error: slot is not empty");
}
inventory[id] = item;
counts[id] = count;
listeners().forEach(inventoryListener -> inventoryListener.putItem(id, item, count));
}
public void item(final int id,
final PlayerInfoMessage.InventoryThing itemMessage) {
if (itemMessage.quantity() == 0) {
if (notEmptySlot(id)) {
emptySlot(id);
}
return;
}
final Item item = new Item(inventory[id]);
updateItemInfo(item, itemMessage);
if (isSameItem(item, id)) {
final int diff = itemMessage.quantity() - counts[id];
updateItemCount(id, diff);
} else {
emptySlot(id);
putItemInSlot(id, item, itemMessage.quantity());
}
}
private void updateItemInfo(final Item item,
final PlayerInfoMessage.InventoryThing itemMessage) {
if (EmptyFieldsDefault.notEmpty(itemMessage.baseType())) {
item.type = itemMessage.baseType();
}
if (EmptyFieldsDefault.notEmpty(itemMessage.subType())) {
item.subtype = itemMessage.subType();
}
if (EmptyFieldsDefault.notEmpty(itemMessage.name())) {
item.name = itemMessage.name();
}
}
private boolean isSameItem(Item item, int id) {
return counts[id] > 0 && inventory[id].equals(item);
}
}
public static class Item {
private int type;
private int subtype;
private String name;
public Item(Item item) {
if (item != null) {
type = item.type;
subtype = item.subtype;
name = item.name;
}
}
public int type() {
return type;
}
public int subtype() {
return subtype;
}
public String name() {
return name == null ? "Unknown item" : name;
}
public Item(PlayerInfoMessage.InventoryThing item) {
type = item.baseType();
name = item.name();
subtype = item.subType();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (type != item.type) return false;
if (subtype != item.subtype) return false;
return name != null ? name.equals(item.name) : item.name == null;
}
@Override
public int hashCode() {
int result = type;
result = 31 * result + subtype;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
}
}
}