package crazypants.enderio.conduit;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import com.enderio.core.api.client.render.IWidgetIcon;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
import crazypants.enderio.api.tool.IConduitControl;
import crazypants.enderio.conduit.item.IItemConduit;
import crazypants.enderio.conduit.liquid.ILiquidConduit;
import crazypants.enderio.conduit.power.IPowerConduit;
import crazypants.enderio.conduit.redstone.IRedstoneConduit;
import static crazypants.enderio.gui.IconEIO.*;
public class ConduitDisplayMode {
public static final ConduitDisplayMode ALL = new ConduitDisplayMode("all", TICK, TICK);
public static final ConduitDisplayMode NONE = new ConduitDisplayMode("none", CROSS, CROSS);
private static final List<ConduitDisplayMode> registrar;
// @formatter:off
static {
registrar = Lists.newArrayList(
NONE,
ALL,
new ConduitDisplayMode(IItemConduit.class, WRENCH_OVERLAY_ITEM, WRENCH_OVERLAY_ITEM_OFF),
new ConduitDisplayMode(ILiquidConduit.class, WRENCH_OVERLAY_FLUID, WRENCH_OVERLAY_FLUID_OFF),
new ConduitDisplayMode(IPowerConduit.class, WRENCH_OVERLAY_POWER, WRENCH_OVERLAY_POWER_OFF),
new ConduitDisplayMode(IRedstoneConduit.class, WRENCH_OVERLAY_REDSTONE, WRENCH_OVERLAY_REDSTONE_OFF)
);
}
// @formatter:on
public static void registerDisplayMode(ConduitDisplayMode mode) {
if (!registrar.contains(mode)) {
registrar.add(mode);
}
}
private final Class<? extends IConduit> conduitType;
private final IWidgetIcon widgetSelected, widgetUnselected;
private String overrideName = null;
/**
* Use this constructor if you have custom display logic, it will use
* {@code IConduit.class} as the conduitType, and the passed name as the
* override name.
*
* @see #ConduitDisplayMode(Class, IWidgetIcon, IWidgetIcon)
*
* @param name
* The override name.
* @param widgetSelected
* The widget to render when this type is selected.
* @param widgetUnselected
* The widget to render when this type is unselected.
*/
public ConduitDisplayMode(String name, IWidgetIcon widgetSelected, IWidgetIcon widgetUnselected) {
this(IConduit.class, widgetSelected, widgetUnselected);
setName(name);
}
/**
* Creates a new display mode for any {@link IConduitControl} wrench. Contains
* data about which conduit type this is for, and the icons to render while
* holding the wrench. wrench.
*
* @param conduitType
* The base class for your conduit type, typically an interface (e.g.
* {@code IPowerConduit}).
* @param widgetSelected
* The widget to render when this type is selected.
* @param widgetUnselected
* The widget to render when this type is unselected.
*/
public ConduitDisplayMode(@Nonnull Class<? extends IConduit> conduitType, IWidgetIcon widgetSelected, IWidgetIcon widgetUnselected) {
this.conduitType = conduitType;
this.widgetSelected = widgetSelected;
this.widgetUnselected = widgetUnselected;
}
@Nullable
public Class<? extends IConduit> getConduitType() {
return conduitType;
}
public boolean renderConduit(Class<? extends IConduit> conduitType) {
if (this == ALL) {
return true;
} else if (this == NONE) {
return false;
} else {
return this.conduitType.isAssignableFrom(conduitType);
}
}
@Nonnull
public String getName() {
return overrideName == null ? conduitType.getSimpleName() : overrideName;
}
/**
* The name is null by default, and will use the simple class name of the
* conduit type.
*
* @param name
* The override name to set.
*/
public void setName(@Nullable String name) {
this.overrideName = name;
}
public IWidgetIcon getWidgetSelected() {
return widgetSelected;
}
public IWidgetIcon getWidgetUnselected() {
return widgetUnselected;
}
public static ConduitDisplayMode next(ConduitDisplayMode mode) {
int index = registrar.indexOf(mode) + 1;
if (index >= registrar.size()) {
index = 0;
}
return registrar.get(index);
}
public static ConduitDisplayMode previous(ConduitDisplayMode mode) {
int index = registrar.indexOf(mode) - 1;
if (index < 0) {
index = registrar.size() - 1;
}
return registrar.get(index);
}
public static ConduitDisplayMode fromName(String name) {
for (ConduitDisplayMode mode : registrar) {
if (mode.getName().equals(name)) {
return mode;
}
}
return null;
}
private static final String NBT_KEY = "enderio.displaymode";
public static ConduitDisplayMode getDisplayMode(ItemStack equipped) {
if (equipped == null || !(equipped.getItem() instanceof IConduitControl)) {
return ALL;
}
initDisplayModeTag(equipped);
String name = equipped.stackTagCompound.getString(NBT_KEY);
ConduitDisplayMode mode = fromName(name);
if (mode == null) { // backwards compat
setDisplayMode(equipped, ALL);
return ALL;
}
return mode;
}
public static void setDisplayMode(ItemStack equipped, ConduitDisplayMode mode) {
if (mode == null || equipped == null || !(equipped.getItem() instanceof IConduitControl)) {
return;
}
initDisplayModeTag(equipped);
equipped.stackTagCompound.setString(NBT_KEY, mode.getName());
}
private static void initDisplayModeTag(ItemStack stack) {
if (stack.stackTagCompound == null) {
stack.stackTagCompound = new NBTTagCompound();
stack.stackTagCompound.setString(NBT_KEY, ConduitDisplayMode.ALL.getName());
}
}
public ConduitDisplayMode next() {
return next(this);
}
public ConduitDisplayMode previous() {
return previous(this);
}
public static int registrySize() {
return registrar.size() - 2;
}
public static Iterable<ConduitDisplayMode> getRenderableModes() {
return FluentIterable.from(registrar).filter(new Predicate<ConduitDisplayMode>() {
@Override
public boolean apply(ConduitDisplayMode input) {
return input != ALL && input != NONE;
}
});
}
@Override
public String toString() {
return getName();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((conduitType == null) ? 0 : conduitType.hashCode());
result = prime * result + ((overrideName == null) ? 0 : overrideName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ConduitDisplayMode other = (ConduitDisplayMode) obj;
if (conduitType == null) {
if (other.conduitType != null)
return false;
} else if (!conduitType.equals(other.conduitType))
return false;
if (overrideName == null) {
if (other.overrideName != null)
return false;
} else if (!overrideName.equals(other.overrideName))
return false;
return true;
}
}