package com.zivilon.cinder_loe.mixins;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

import net.minecraft.world.gen.layer.GenLayer;
import cpw.mods.fml.common.FMLLog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lotr.common.LOTRDimension;
import lotr.common.world.biome.LOTRBiome;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import java.util.Random;

import lotr.common.world.genlayer.LOTRGenLayerRemoveMapRivers;
import lotr.common.world.genlayer.LOTRGenLayer;
import lotr.common.world.genlayer.LOTRIntCache;
import com.zivilon.cinder_loe.util.Utilities;

@Mixin(LOTRIntCache.class)
public abstract class MixinLOTRIntCache {

    @Shadow
    private static LOTRIntCache SERVER;
    @Shadow
    private static LOTRIntCache CLIENT;
    @Shadow
    private int intCacheSize = 256;
    @Shadow
    private List<int[]> freeSmallArrays;
    @Shadow
    private List<int[]> inUseSmallArrays;
    @Shadow
    private List<int[]> freeLargeArrays;
    @Shadow
    private List<int[]> inUseLargeArrays;

    @Overwrite(remap = false)
    public int[] getIntArray(int size) {
        if (size <= 256) {
            if (this.freeSmallArrays.isEmpty()) {
              int[] arrayOfInt1 = new int[256];
              this.inUseSmallArrays.add(arrayOfInt1);
              return arrayOfInt1 == null ? Utilities.LOTRIntCache : cacheInts(arrayOfInt1);
            }
            int[] arrayOfInt = this.freeSmallArrays.remove(this.freeSmallArrays.size() - 1);
            this.inUseSmallArrays.add(arrayOfInt);
            return arrayOfInt == null ? Utilities.LOTRIntCache : cacheInts(arrayOfInt);
        }
        if (size > this.intCacheSize) {
            this.intCacheSize = size;
            this.freeLargeArrays.clear();
            this.inUseLargeArrays.clear();
            int[] arrayOfInt = new int[this.intCacheSize];
            this.inUseLargeArrays.add(arrayOfInt);
            return arrayOfInt == null ? Utilities.LOTRIntCache : cacheInts(arrayOfInt);
        }
        if (this.freeLargeArrays.isEmpty()) {
            int[] arrayOfInt = new int[this.intCacheSize];
            this.inUseLargeArrays.add(arrayOfInt);
            return arrayOfInt == null ? Utilities.LOTRIntCache : cacheInts(arrayOfInt);
        }
        int[] ints = this.freeLargeArrays.remove(this.freeLargeArrays.size() - 1);
        this.inUseLargeArrays.add(ints);
        return ints == null ? Utilities.LOTRIntCache : cacheInts(ints);
    }

    private int[] cacheInts(int[] ints) {
        Utilities.LOTRIntCache = ints;
        return ints;
    }
}
