content: package gripe._90.appliede.part;
  
  import java.util.List;
  
  import net.minecraft.core.HolderLookup;
  import net.minecraft.nbt.CompoundTag;
  import net.minecraft.resources.ResourceLocation;
  import net.minecraft.world.entity.player.Player;
  import net.minecraft.world.item.ItemStack;
  import net.minecraft.world.phys.Vec3;
  
  import appeng.api.networking.GridHelper;
  import appeng.api.networking.IGridNodeListener;
  import appeng.api.networking.IManagedGridNode;
  import appeng.api.parts.IPartCollisionHelper;
  import appeng.api.parts.IPartItem;
  import appeng.api.parts.IPartModel;
  import appeng.api.util.AECableType;
  import appeng.core.AppEng;
  import appeng.items.parts.PartModels;
  import appeng.menu.locator.MenuLocators;
  import appeng.parts.AEBasePart;
  import appeng.parts.PartModel;
  
  import gripe._90.appliede.AppliedE;
  import gripe._90.appliede.me.misc.EMCInterfaceLogic;
  import gripe._90.appliede.me.misc.EMCInterfaceLogicHost;
  
  public class EMCInterfacePart extends AEBasePart implements EMCInterfaceLogicHost {
      private static final ResourceLocation MODEL_BASE = AppliedE.id("part/emc_interface");
  
      @PartModels
      private static final PartModel MODELS_OFF = new PartModel(MODEL_BASE, AppEng.makeId("part/interface_off"));
  
      @PartModels
      private static final PartModel MODELS_ON = new PartModel(MODEL_BASE, AppEng.makeId("part/interface_on"));
  
      @PartModels
      private static final PartModel MODELS_HAS_CHANNEL =
              new PartModel(MODEL_BASE, AppEng.makeId("part/interface_has_channel"));
  
      private final EMCInterfaceLogic logic = createLogic();
  
      public EMCInterfacePart(IPartItem<?> partItem) {
          super(partItem);
      }
  
      protected EMCInterfaceLogic createLogic() {
          return new EMCInterfaceLogic(getMainNode(), this, getPartItem().asItem());
      }
  
      @Override
      protected IManagedGridNode createMainNode() {
          return GridHelper.createManagedNode(this, NODE_LISTENER);
      }
  
      @Override
      public EMCInterfaceLogic getInterfaceLogic() {
          return logic;
      }
  
      @Override
      public void onMainNodeStateChanged(IGridNodeListener.State reason) {
          super.onMainNodeStateChanged(reason);
  
          if (getMainNode().hasGridBooted()) {
              logic.notifyNeighbours();
          }
      }
  
      @Override
      public void readFromNBT(CompoundTag data, HolderLookup.Provider registries) {
          super.readFromNBT(data, registries);
          logic.readFromNBT(data, registries);
      }
  
      @Override
      public void writeToNBT(CompoundTag data, HolderLookup.Provider registries) {
          super.writeToNBT(data, registries);
          logic.writeToNBT(data, registries);
      }
  
      @Override
      public void addAdditionalDrops(List<ItemStack> drops, boolean wrenched) {
          super.addAdditionalDrops(drops, wrenched);
          logic.addDrops(drops);
      }
  
      @Override
      public void clearContent() {
          super.clearContent();
          logic.clearContent();
      }
  
      @Override
      public void saveChanges() {
          getHost().markForSave();
      }
  
      @Override
      public boolean onUseWithoutItem(Player player, Vec3 pos) {
          if (!player.getCommandSenderWorld().isClientSide()) {
              openMenu(player, MenuLocators.forPart(this));
          }
  
          return true;
      }
  
      @Override
      public void getBoxes(IPartCollisionHelper bch) {
          bch.addBox(2, 2, 14, 14, 14, 16);
          bch.addBox(5, 5, 12, 11, 11, 14);
      }
  
      @Override
      public float getCableConnectionLength(AECableType cable) {
          return 4;
      }
  
      @Override
      public IPartModel getStaticModels() {
          return isActive() ? MODELS_HAS_CHANNEL : isPowered() ? MODELS_ON : MODELS_OFF;
      }
  
      @Override
      public ItemStack getMainMenuIcon() {
          return new ItemStack(getPartItem());
      }
  }
  