package common.color;

import common.biome.Biome;
import common.util.BlockPos;
import common.world.IWorldAccess;

public enum Colorizer {
	NONE(0xffffff), BASIC(0x37b500), PINE(0x3f993f), BIRCH(0x68a723);

	private interface ColorResolver {
		int getColorAtPos(Biome biome, BlockPos pos);
	}

	private static final ColorResolver GRASS_COLOR = new ColorResolver() {
		public int getColorAtPos(Biome biome, BlockPos pos) {
			return biome.getGrassColorAtPos(pos);
		}
	};
	private static final ColorResolver FOLIAGE_COLOR = new ColorResolver() {
		public int getColorAtPos(Biome biome, BlockPos pos) {
			return biome.getFoliageColorAtPos(pos);
		}
	};
	private static final ColorResolver WATER_COLOR_MULTIPLIER = new ColorResolver() {
		public int getColorAtPos(Biome biome, BlockPos pos) {
			return biome.waterColor;
		}
	};
	private static final int[] GRASS = new int[65536];
	private static final int[] FOLIAGE = new int[65536];

	private final int color;
	
	public static int[] getGrassMap() {
		return GRASS;
	}
	
	public static int[] getFoliageMap() {
		return FOLIAGE;
	}

	public static int getGrassColor(double temp, double rain) {
		rain = rain * temp;
		int i = (int)((1.0D - temp) * 255.0D);
		int j = (int)((1.0D - rain) * 255.0D);
		int k = j << 8 | i;
		return k > GRASS.length ? 0xFFFF00FF : GRASS[k];
	}

	public static int getFoliageColor(double temp, double rain) {
		rain = rain * temp;
		int i = (int)((1.0D - temp) * 255.0D);
		int j = (int)((1.0D - rain) * 255.0D);
		return FOLIAGE[j << 8 | i];
	}

	private static int getColor(IWorldAccess access, BlockPos pos, ColorResolver resolver) {
		int r = 0;
		int g = 0;
		int b = 0;

		for(BlockPos.MutableBlockPos loc : BlockPos.getAllInBoxMutable(pos.add(-1, 0, -1), pos.add(1, 0, 1))) {
			int c = resolver.getColorAtPos(access.getBiomeGenForCoords(loc), loc);
			r += (c & 16711680) >> 16;
			g += (c & 65280) >> 8;
			b += c & 255;
		}

		return (r / 9 & 255) << 16 | (g / 9 & 255) << 8 | b / 9 & 255;
	}

	public static int getGrassColor(IWorldAccess access, BlockPos pos) {
		return getColor(access, pos, GRASS_COLOR);
	}

	public static int getFoliageColor(IWorldAccess access, BlockPos pos) {
		return getColor(access, pos, FOLIAGE_COLOR);
	}

	public static int getWaterColor(IWorldAccess access, BlockPos pos) {
		return getColor(access, pos, WATER_COLOR_MULTIPLIER);
	}

	private Colorizer(int color) {
		this.color = color;
	}

	public int getColor() {
		return this.color;
	}
}
