package org.cyclops.integrateddynamics.inventory.container;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import org.cyclops.cyclopscore.helper.Helpers;
import org.cyclops.cyclopscore.helper.MinecraftHelpers;
import org.cyclops.cyclopscore.helper.ValueNotifierHelpers;
import org.cyclops.cyclopscore.inventory.IGuiContainerProvider;
import org.cyclops.cyclopscore.inventory.SimpleInventory;
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
import org.cyclops.integrateddynamics.api.part.IPartContainer;
import org.cyclops.integrateddynamics.api.part.PartTarget;
import org.cyclops.integrateddynamics.api.part.aspect.IAspectWrite;
import org.cyclops.integrateddynamics.api.part.write.IPartStateWriter;
import org.cyclops.integrateddynamics.api.part.write.IPartTypeWriter;
import org.cyclops.integrateddynamics.api.tileentity.ITileCableNetwork;
import org.cyclops.integrateddynamics.core.inventory.container.ContainerMultipartAspects;
import org.cyclops.integrateddynamics.core.inventory.container.slot.SlotVariable;

/**
 * Container for writer parts.
 * @author rubensworks
 */
public class ContainerPartWriter<P extends IPartTypeWriter<P, S> & IGuiContainerProvider, S extends IPartStateWriter<P>>
        extends ContainerMultipartAspects<P, S, IAspectWrite> {

    public static final int ASPECT_BOX_HEIGHT = 18;
    private static final int PAGE_SIZE = 6;
    private static final int SLOT_X = 131;
    private static final int SLOT_Y = 18;

    private final int valueId, colorId;

    /**
     * Make a new instance.
     * @param partTarget    The target.
     * @param player        The player.
     * @param partContainer The part container.
     * @param partType      The part type.
     */
    public ContainerPartWriter(EntityPlayer player, PartTarget partTarget, IPartContainer partContainer, P partType) {
        super(player, partTarget, partContainer, partType, partType.getWriteAspects());
        for(int i = 0; i < getUnfilteredItemCount(); i++) {
            addSlotToContainer(new SlotVariable(inputSlots, i, SLOT_X, SLOT_Y + getAspectBoxHeight() * i));
            disableSlot(i);
        }

        addPlayerInventory(player.inventory, 9, 140);

        this.valueId = getNextValueId();
        this.colorId = getNextValueId();
    }

    @Override
    public int getAspectBoxHeight() {
        return ASPECT_BOX_HEIGHT;
    }

    @Override
    public int getPageSize() {
        return PAGE_SIZE;
    }

    @Override
    protected void enableSlot(int slotIndex, int row) {
        Slot slot = getSlot(slotIndex);
        slot.xDisplayPosition = SLOT_X;
        slot.yDisplayPosition = SLOT_Y + ASPECT_BOX_HEIGHT * row;
    }

    @Override
    protected IInventory constructInputSlotsInventory() {
        SimpleInventory inventory = getPartState().getInventory();
        inventory.addDirtyMarkListener(this);
        return inventory;
    }

    @Override
    public void onDirty() {
        if(!MinecraftHelpers.isClientSide()) {
            getPartType().updateActivation(getTarget(), getPartState());
        }
    }

    @Override
    public void detectAndSendChanges() {
        super.detectAndSendChanges();
        if(!MinecraftHelpers.isClientSide()) {
            String writeValue = "";
            int writeValueColor = 0;
            if(getPartContainer() instanceof ITileCableNetwork && getPartState().hasVariable()) {
                IVariable variable = getPartState().getVariable(((ITileCableNetwork) getPartContainer()).getNetwork());
                if (variable != null) {
                    try {
                        IValue value = variable.getValue();
                        writeValue = value.getType().toCompactString(value);
                        writeValueColor = variable.getType().getDisplayColor();
                    } catch (EvaluationException e) {
                        writeValue = "ERROR";
                        writeValueColor = Helpers.RGBToInt(255, 0, 0);
                    }
                }
            } else {
                writeValue = "";
            }
            setWriteValue(writeValue, writeValueColor);
        }
    }

    public void setWriteValue(String writeValue, int writeColor) {
        ValueNotifierHelpers.setValue(this, valueId, writeValue);
        ValueNotifierHelpers.setValue(this, colorId, writeColor);
    }

    public String getWriteValue() {
        String value = ValueNotifierHelpers.getValueString(this, valueId);
        if(value == null) {
            value = "";
        }
        return value;
    }

    public int getWriteValueColor() {
        return ValueNotifierHelpers.getValueInt(this, colorId);
    }

}

@@ -679,16 +679,80 @@
 riable;%0A
+import org.cyclops.integrateddynamics.api.network.IPartNetwork;%0A
 import o
@@ -3686,111 +3686,206 @@
    I
-Variable variable = getPartState().getVariable(((ITileCableNetwork) getPartContainer()).getN
+PartNetwork network = ((ITileCableNetwork) getPartContainer()).getNetwork();%0A                if (network != null) %7B%0A                    IVariable variable = getPartState().getVariable(n
 etwork
-()
 );%0A
+    
     
@@ -3940,16 +3940,20 @@
         
+    
 try %7B%0A  
@@ -3974,16 +3974,20 @@
         
+    
 IValue v
@@ -4010,24 +4010,28 @@
 getValue();%0A
+    
             
@@ -4111,32 +4111,36 @@
                 
+    
 writeValueColor 
@@ -4199,16 +4199,20 @@
         
+    
 %7D catch 
@@ -4253,32 +4253,36 @@
                 
+    
 writeValue = %22ER
@@ -4287,16 +4287,20 @@
 ERROR%22;%0A
+    
         
@@ -4374,33 +4374,208 @@
                 
-%7D
+    %7D%0A                    %7D%0A                %7D else %7B%0A                    writeValue = %22NETWORK CORRUPTED!%22;%0A                    writeValueColor = Helpers.RGBToInt(255, 100, 0);
 %0A               

Fix crash when interacting with parts when network got corrupted, Closes #25