package org.cyclops.integrateddynamics.core.network.diagnostics;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.cyclops.integrateddynamics.api.part.PartPos;
import org.cyclops.integrateddynamics.core.helper.PartHelpers;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * @author rubensworks
 */
public class NetworkDiagnosticsPartOverlayRenderer {

    private static final NetworkDiagnosticsPartOverlayRenderer _INSTANCE = new NetworkDiagnosticsPartOverlayRenderer();
    private final Set<PartPos> partPositions = Sets.newHashSet();

    private NetworkDiagnosticsPartOverlayRenderer() {

    }

    public static NetworkDiagnosticsPartOverlayRenderer getInstance() {
        return _INSTANCE;
    }

    public synchronized void addPos(PartPos pos) {
        partPositions.add(pos);
    }

    public synchronized void removePos(PartPos pos) {
        partPositions.remove(pos);
    }

    public synchronized void clearPositions() {
        partPositions.clear();
    }

    public synchronized boolean hasPartPos(PartPos pos) {
        return partPositions.contains(pos);
    }

    @SubscribeEvent
    public void onRender(RenderWorldLastEvent event) {
        EntityPlayer player = Minecraft.getMinecraft().thePlayer;
        float partialTicks = event.getPartialTicks();

        double offsetX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
        double offsetY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
        double offsetZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;

        GlStateManager.enableBlend();
        GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
        GlStateManager.glLineWidth(6.0F);
        GlStateManager.disableTexture2D();
        GlStateManager.depthMask(false);

        List<PartPos> partList = Lists.newArrayList(partPositions);
        for (Iterator<PartPos> it = partList.iterator(); it.hasNext();) {
            PartPos partPos = it.next();
            if (partPos.getPos().getWorld() == player.worldObj && partPos.getPos().getBlockPos().distanceSq(player.getPosition()) < 10000) {
                PartHelpers.PartStateHolder<?, ?> partStateHolder = PartHelpers.getPart(partPos);
                if (partStateHolder != null) {
                    AxisAlignedBB bb = partStateHolder.getPart().getPartRenderPosition().getBoundingBox(partPos.getSide())
                            .offset(partPos.getPos().getBlockPos())
                            .offset(-offsetX, -offsetY, -offsetZ)
                            .expand(0.05, 0.05, 0.05);
                    RenderGlobal.func_189697_a(bb, 1.0F, 0.2F, 0.1F, 0.8F);
                } else {
                    it.remove();
                }
            }
        }

        GlStateManager.depthMask(true);
        GlStateManager.enableTexture2D();
        GlStateManager.disableBlend();
    }

}

@@ -1587,24 +1587,68 @@
 nt event) %7B%0A
+        if (!partPositions.isEmpty()) %7B%0A    
         Enti
@@ -1709,16 +1709,20 @@
         
+    
 float pa
@@ -1760,32 +1760,36 @@
 cks();%0A%0A        
+ 
+   
 double offsetX =
@@ -1849,32 +1849,33 @@
 PosX) * (double)
+ 
 partialTicks;%0A  
@@ -1872,32 +1872,36 @@
 lTicks;%0A        
+ 
+   
 double offsetY =
@@ -1961,32 +1961,33 @@
 PosY) * (double)
+ 
 partialTicks;%0A  
@@ -1984,32 +1984,36 @@
 lTicks;%0A        
+ 
+   
 double offsetZ =
@@ -2081,16 +2081,17 @@
 (double)
+ 
 partialT
@@ -2097,32 +2097,36 @@
 Ticks;%0A%0A        
+ 
+   
 GlStateManager.e
@@ -2135,24 +2135,28 @@
 bleBlend();%0A
+    
         GlSt
@@ -2339,32 +2339,36 @@
 .ZERO);%0A        
+    
 GlStateManager.g
@@ -2385,32 +2385,36 @@
 (6.0F);%0A        
+   
+ 
 GlStateManager.d
@@ -2432,32 +2432,36 @@
 re2D();%0A        
+    
 GlStateManager.d
@@ -2486,16 +2486,20 @@
         
+  
+  
 List%3CPar
@@ -2546,24 +2546,28 @@
 Positions);%0A
+    
         for 
@@ -2624,20 +2624,25 @@
 sNext();
+ 
 ) %7B%0A
+    
         
@@ -2678,32 +2678,36 @@
 ();%0A            
+    
 if (partPos.getP
@@ -2831,24 +2831,28 @@
             
+    
 PartHelpers.
@@ -2929,32 +2929,36 @@
                 
+   
+ 
 if (partStateHol
@@ -2968,24 +2968,28 @@
  != null) %7B%0A
+    
             
@@ -3119,32 +3119,36 @@
                 
+    
 .offset(partPos.
@@ -3191,32 +3191,36 @@
                 
+  
+  
 .offset(-offsetX
@@ -3269,16 +3269,20 @@
         
+    
 .expand(
@@ -3300,16 +3300,20 @@
  0.05);%0A
+    
         
@@ -3396,16 +3396,20 @@
         
+    
 %7D else %7B
@@ -3409,16 +3409,20 @@
  else %7B%0A
+    
         
@@ -3454,34 +3454,42 @@
                 
+   
+ 
 %7D%0A
+    
             %7D%0A  
@@ -3490,24 +3490,28 @@
   %7D%0A        
+    
 %7D%0A%0A        G
@@ -3501,32 +3501,36 @@
      %7D%0A%0A        
+ 
+   
 GlStateManager.d
@@ -3545,32 +3545,36 @@
 (true);%0A        
+   
+ 
 GlStateManager.e
@@ -3583,32 +3583,36 @@
 bleTexture2D();%0A
+    
         GlStateM
@@ -3630,21 +3630,31 @@
 bleBlend();%0A
+        %7D%0A
     %7D%0A%0A%7D%0A

Improve network diagnostics efficiency when not in use