package mods.eln.item.electricalinterface;
import cpw.mods.fml.common.FMLCommonHandler;
import mods.eln.Eln;
import mods.eln.misc.Utils;
import mods.eln.sim.IProcess;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class ItemEnergyInventoryProcess implements IProcess {
private static final double energyUpdatePeriod = 0.5;
private double energyUpdateTimout = energyUpdatePeriod;
class Element {
public ItemStack stack;
public IItemEnergyBattery i;
public int p;
public Element(ItemStack stack, IItemEnergyBattery i) {
this.stack = stack;
this.i = i;
p = i.getPriority(stack);
}
}
static class Exclusion {
public double timeout;
public Object o;
public Exclusion(double timeout, Object o) {
this.timeout = timeout;
this.o = o;
Utils.println("new");
}
}
LinkedList<Exclusion> exclude = new LinkedList<ItemEnergyInventoryProcess.Exclusion>();
// HashMap<Object, Double> exclude = new HashMap<Object, Double>();
public void addExclusion(Object o, double timeout) {
Exclusion exclusion = null;
for (Exclusion e : exclude) {
if (e.o == o) {
exclusion = e;
}
}
if (exclusion == null) {
exclusion = new Exclusion(timeout, o);
exclude.add(exclusion);
}
exclusion.timeout = timeout;
}
boolean isExcluded(Object o) {
for (Exclusion e : exclude) {
if (e.o == o) {
Utils.println("Exclude");
return true;
}
}
return false;
}
@Override
public void process(double time) {
Iterator<Exclusion> ie = exclude.iterator();
while (ie.hasNext()) {
Exclusion e = ie.next();
e.timeout -= 0.05;
if (e.timeout < 0) {
ie.remove();
}
}
energyUpdateTimout -= time;
if (energyUpdateTimout > 0)
return;
energyUpdateTimout += energyUpdatePeriod;
time = energyUpdatePeriod;
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
ArrayList<Element> list = new ArrayList<Element>();
for (Object obj : server.getConfigurationManager().playerEntityList) {
EntityPlayerMP player = (EntityPlayerMP) obj;
list.clear();
for (ItemStack stack : player.inventory.armorInventory) {
Object o = Utils.getItemObject(stack);
if (o instanceof IItemEnergyBattery) {
if (isExcluded(o))
continue;
list.add(new Element(stack, (IItemEnergyBattery) o));
}
}
for (ItemStack stack : player.inventory.mainInventory) {
Object o = Utils.getItemObject(stack);
if (o instanceof IItemEnergyBattery) {
if (isExcluded(o))
continue;
list.add(new Element(stack, (IItemEnergyBattery) o));
}
}
for (Element e : list) {
e.i.electricalItemUpdate(e.stack, energyUpdatePeriod);
}
if (Eln.saveConfig.infinitePortableBattery) {
for (Element e : list) {
double chargePower = e.i.getChargePower(e.stack);
double energy = Math.min(e.i.getEnergyMax(e.stack), e.i.getEnergy(e.stack) + e.i.getChargePower(e.stack) * time);
e.i.setEnergy(e.stack, energy);
}
} else {
boolean rememberDst = false;
double rememberDstEToDstMax = 0;
while (true) {
Element src = getMax(list);
if (src == null)
break;
double eFromSrc = Math.min(src.i.getEnergy(src.stack), src.i.getDischagePower(src.stack) * time);
double eStart = eFromSrc;
boolean done = false;
while (eFromSrc != 0) {
Element dst = getMin(list);
if (dst.p == src.p) {
done = true;
break;
}
double eToDstMax;
if (rememberDst) {
eToDstMax = rememberDstEToDstMax;
rememberDst = false;
} else {
eToDstMax = Math.min(dst.i.getEnergyMax(dst.stack) - dst.i.getEnergy(dst.stack), dst.i.getChargePower(dst.stack) * time);
}
double eToDst = Math.min(eFromSrc, eToDstMax);
eFromSrc -= eToDst;
dst.i.setEnergy(dst.stack, dst.i.getEnergy(dst.stack) + eToDst);
eToDstMax -= eToDst;
if (eToDstMax == 0) {
list.remove(dst);
} else {
rememberDst = true;
rememberDstEToDstMax = eToDstMax;
}
}
src.i.setEnergy(src.stack, src.i.getEnergy(src.stack) - (eStart - eFromSrc));
if (done)
break;
list.remove(src);
if (list.size() < 2)
break;
}
}
}
}
Element getElement(List<Element> list, int priority) {
for (Element e : list) {
if (priority == e.p) {
return e;
}
}
return null;
}
Element getMin(List<Element> list) {
Element find = null;
for (Element e : list) {
if (find == null || find.p > e.p) {
find = e;
}
}
return find;
}
Element getMax(List<Element> list) {
Element find = null;
for (Element e : list) {
if (find == null || find.p < e.p) {
find = e;
}
}
return find;
}
}