package com.enderio.core.client.gui.button;

import java.util.List;

import javax.annotation.Nonnull;

import com.enderio.core.api.client.gui.IGuiScreen;
import com.enderio.core.api.client.render.IWidgetIcon;
import com.enderio.core.client.gui.button.CycleButton.ICycleEnum;
import com.enderio.core.common.util.NNList;

import net.minecraft.client.Minecraft;

/**
 * A button which automatically parses enum constants and cycles between them when clicked.
 *
 * @param <T>
 *          The enum type for this button.
 */
public class CycleButton<T extends Enum<T> & ICycleEnum> extends IconButton {

  public interface ICycleEnum {

    /**
     * @return The icon to display when the button has selected this mode.
     */
    @Nonnull
    IWidgetIcon getIcon();

    /**
     * @return Localized tooltip lines.
     */
    @Nonnull
    List<String> getTooltipLines();
  }

  private final @Nonnull NNList<T> modes;

  private @Nonnull T mode;

  public CycleButton(@Nonnull IGuiScreen gui, int id, int x, int y, @Nonnull Class<T> enumClass) {
    super(gui, id, x, y, null);
    modes = NNList.of(enumClass);
    mode = setMode(modes.get(0));
  }

  @Override
  public boolean mousePressed(@Nonnull Minecraft par1Minecraft, int par2, int par3) {
    boolean result = super.mousePressed(par1Minecraft, par2, par3);
    if (result) {
      nextMode();
    }
    return result;
  }

  @Override
  public boolean mousePressedButton(@Nonnull Minecraft mc, int x, int y, int button) {
    boolean result = button == 1 && super.checkMousePress(mc, x, y);
    if (result) {
      prevMode();
    }
    return result;
  }

  private void nextMode() {
    setMode(modes.next(mode));
  }

  private void prevMode() {
    setMode(modes.prev(mode));
  }

  public @Nonnull T setMode(@Nonnull T newMode) {
    if (mode == newMode) {
      return mode;
    }
    mode = newMode;
    List<String> tooltip = mode.getTooltipLines();
    setToolTip(tooltip.toArray(new String[tooltip.size()]));

    icon = mode.getIcon();
    return mode;
  }

  public @Nonnull T getMode() {
    return mode;
  }
}

@@ -94,16 +94,50 @@
 Nonnull;
+%0Aimport javax.annotation.Nullable;
 %0A%0Aimport
@@ -956,22 +956,23 @@
 ivate @N
-onn
 ull
+able
  T mode;
@@ -1140,24 +1140,111 @@
 ass);%0A  
-  mode =
+%7D%0A%0A  @Override%0A  public void onGuiInit() %7B%0A    super.onGuiInit();%0A    if (mode == null) %7B%0A     
  setMode
@@ -1255,24 +1255,30 @@
 es.get(0));%0A
+    %7D%0A
   %7D%0A%0A  @Over
@@ -1787,20 +1787,25 @@
 es.next(
-m
+getM
 ode
+()
 ));%0A  %7D%0A
@@ -1856,20 +1856,25 @@
 es.prev(
-m
+getM
 ode
+()
 ));%0A  %7D%0A
@@ -1883,26 +1883,20 @@
  public 
-@Nonnull T
+void
  setMode
@@ -1953,29 +1953,24 @@
       return
- mode
 ;%0A    %7D%0A    
@@ -2109,17 +2109,20 @@
  icon = 
-m
+newM
 ode.getI
@@ -2128,33 +2128,16 @@
 Icon();%0A
-    return mode;%0A
   %7D%0A%0A  p
@@ -2180,16 +2180,46 @@
 urn mode
+ != null ? mode : modes.get(0)
 ;%0A  %7D%0A%7D%0A

Tweak CycleButton init code to work with inheritance