// Path: src/main/java/com/latenighters/runicarcana/common/symbols/SymbolTextures.java
// @Mod.EventBusSubscriber(modid = MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
// public class SymbolTextures {
// 
//     public static final ResourceLocation DEBUG = new ResourceLocation(MODID , "symbols/symbol_x");
//     public static final ResourceLocation EXPEL = new ResourceLocation(MODID , "symbols/symbol_expel");
//     public static final ResourceLocation INSERT = new ResourceLocation(MODID , "symbols/symbol_insert");
//     public static final ResourceLocation REDSTONE = new ResourceLocation(MODID , "symbols/symbol_redstone");
//     public static final ResourceLocation BOOLEAN_LOGIC = new ResourceLocation(MODID , "symbols/symbol_boolean_logic");
//     public static final ResourceLocation DETECT= new ResourceLocation(MODID , "symbols/symbol_detect");
// 
// 
// 
//     @SubscribeEvent
//     public static void onStitchEvent(TextureStitchEvent.Pre event)
//     {
//         ResourceLocation stitching = event.getMap().getTextureLocation();
//         if(!stitching.equals(AtlasTexture.LOCATION_BLOCKS_TEXTURE))
//         {
//             return;
//         }
//         for (ResourceLocation tex:textureList)
//         {
//             event.addSprite(tex);
//         }
//     }
// 
//     public static void consolidateTextures(final RegistryEvent.Register<Symbol> evt)
//     {
// 
//         for(Symbol symbol : evt.getRegistry().getValues())
//         {
//             if(!textureList.contains(symbol.getTexture()))
//             {
//                 textureList.add(symbol.getTexture());
//             }
//         }
//     }
// 
//     private static ArrayList<ResourceLocation> textureList = new ArrayList<ResourceLocation>();
// 
// }
// 
// Path: src/main/java/com/latenighters/runicarcana/common/symbols/categories/SymbolCategory.java
// public class SymbolCategory {
// 
//     public static SymbolCategory DEFAULT = new SymbolCategory(Symbols.DEBUG, MODID+".symbol.category.default");
// 
//     private Symbol displaySymbol;
//     private final String unlocalizedName;
// 
//     public static void generateCategories()
//     {
//         //TODO figure out why static initialization isn't working
//         DEFAULT.setDisplaySymbol(Symbols.EXPULSION);
//     }
// 
//     public SymbolCategory(Symbol displaySymbol, String unlocalizedName) {
//         this.displaySymbol = displaySymbol;
//         this.unlocalizedName = unlocalizedName;
//     }
// 
//     public Symbol getDisplaySymbol() {
//         return displaySymbol;
//     }
// 
//     public void setDisplaySymbol(Symbol displaySymbol) {
//         this.displaySymbol = displaySymbol;
//     }
// 
//     public String getUnlocalizedName() {
//         return unlocalizedName;
//     }
// }
// 
// Path: src/main/java/com/latenighters/runicarcana/RunicArcana.java
// public static final String MODID = "runicarcana";


import com.latenighters.runicarcana.common.symbols.SymbolTextures;
import com.latenighters.runicarcana.common.symbols.categories.SymbolCategory;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import java.util.ArrayList;
import java.util.List;
import static com.latenighters.runicarcana.RunicArcana.MODID;
        //repeat for outputs
        for (IFunctional function : outputs)
        {
            //synchronize the inputs from all the functions
            for(HashableTuple<String,DataType> input : inputs) {
                //check to see if inputs already has the same DataType and String registered
                if(function.getRequiredInputs()==null)return;
                function.getRequiredInputs().removeIf(finput ->
                {
                    if (function.getRequiredInputs().contains(finput)) return false;
                    if (input.getA().equals(finput.getA()) && input.getB().type.equals(finput.getB().type)) {
                        //if we do, remove the input from the function and replace it with the already registered input
                        function.getRequiredInputs().add(input);
                        return true;
                    }
                    return false;
                });
            }

            //add each input into the object inputs
            if(function.getRequiredInputs()!=null)
                function.getRequiredInputs().forEach(finput->{
                    if(!inputs.contains(finput))
                        inputs.add(finput);
                });
        }
    }

    public Symbol(String name)
    {
// Path: src/main/java/com/latenighters/runicarcana/common/symbols/SymbolTextures.java
// @Mod.EventBusSubscriber(modid = MODID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
// public class SymbolTextures {
// 
//     public static final ResourceLocation DEBUG = new ResourceLocation(MODID , "symbols/symbol_x");
//     public static final ResourceLocation EXPEL = new ResourceLocation(MODID , "symbols/symbol_expel");
//     public static final ResourceLocation INSERT = new ResourceLocation(MODID , "symbols/symbol_insert");
//     public static final ResourceLocation REDSTONE = new ResourceLocation(MODID , "symbols/symbol_redstone");
//     public static final ResourceLocation BOOLEAN_LOGIC = new ResourceLocation(MODID , "symbols/symbol_boolean_logic");
//     public static final ResourceLocation DETECT= new ResourceLocation(MODID , "symbols/symbol_detect");
// 
// 
// 
//     @SubscribeEvent
//     public static void onStitchEvent(TextureStitchEvent.Pre event)
//     {
//         ResourceLocation stitching = event.getMap().getTextureLocation();
//         if(!stitching.equals(AtlasTexture.LOCATION_BLOCKS_TEXTURE))
//         {
//             return;
//         }
//         for (ResourceLocation tex:textureList)
//         {
//             event.addSprite(tex);
//         }
//     }
// 
//     public static void consolidateTextures(final RegistryEvent.Register<Symbol> evt)
//     {
// 
//         for(Symbol symbol : evt.getRegistry().getValues())
//         {
//             if(!textureList.contains(symbol.getTexture()))
//             {
//                 textureList.add(symbol.getTexture());
//             }
//         }
//     }
// 
//     private static ArrayList<ResourceLocation> textureList = new ArrayList<ResourceLocation>();
// 
// }
// 
// Path: src/main/java/com/latenighters/runicarcana/common/symbols/categories/SymbolCategory.java
// public class SymbolCategory {
// 
//     public static SymbolCategory DEFAULT = new SymbolCategory(Symbols.DEBUG, MODID+".symbol.category.default");
// 
//     private Symbol displaySymbol;
//     private final String unlocalizedName;
// 
//     public static void generateCategories()
//     {
//         //TODO figure out why static initialization isn't working
//         DEFAULT.setDisplaySymbol(Symbols.EXPULSION);
//     }
// 
//     public SymbolCategory(Symbol displaySymbol, String unlocalizedName) {
//         this.displaySymbol = displaySymbol;
//         this.unlocalizedName = unlocalizedName;
//     }
// 
//     public Symbol getDisplaySymbol() {
//         return displaySymbol;
//     }
// 
//     public void setDisplaySymbol(Symbol displaySymbol) {
//         this.displaySymbol = displaySymbol;
//     }
// 
//     public String getUnlocalizedName() {
//         return unlocalizedName;
//     }
// }
// 
// Path: src/main/java/com/latenighters/runicarcana/RunicArcana.java
// public static final String MODID = "runicarcana";


// Path: src/main/java/com/latenighters/runicarcana/common/symbols/backend/Symbol.java
import com.latenighters.runicarcana.common.symbols.SymbolTextures;
import com.latenighters.runicarcana.common.symbols.categories.SymbolCategory;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import java.util.ArrayList;
import java.util.List;
import static com.latenighters.runicarcana.RunicArcana.MODID;

        //repeat for outputs
        for (IFunctional function : outputs)
        {
            //synchronize the inputs from all the functions
            for(HashableTuple<String,DataType> input : inputs) {
                //check to see if inputs already has the same DataType and String registered
                if(function.getRequiredInputs()==null)return;
                function.getRequiredInputs().removeIf(finput ->
                {
                    if (function.getRequiredInputs().contains(finput)) return false;
                    if (input.getA().equals(finput.getA()) && input.getB().type.equals(finput.getB().type)) {
                        //if we do, remove the input from the function and replace it with the already registered input
                        function.getRequiredInputs().add(input);
                        return true;
                    }
                    return false;
                });
            }

            //add each input into the object inputs
            if(function.getRequiredInputs()!=null)
                function.getRequiredInputs().forEach(finput->{
                    if(!inputs.contains(finput))
                        inputs.add(finput);
                });
        }
    }

    public Symbol(String name)
    {
        this(name, SymbolTextures.DEBUG, SymbolCategory.DEFAULT);