package common.rng;

class ImprovedGenOld {
	private final int permutations[];
	private final double xCoord;
	private final double yCoord;
	private final double zCoord;

	protected ImprovedGenOld(Random random) {
		this.permutations = new int[512];
		this.xCoord = random.doublev() * 256D;
		this.yCoord = random.doublev() * 256D;
		this.zCoord = random.doublev() * 256D;
		
		for(int n = 0; n < 256; n++) {
			this.permutations[n] = n;
		}

		for(int n = 0; n < 256; n++) {
			int pos = random.zrange(256 - n) + n;
			int value = this.permutations[n];
			this.permutations[n] = this.permutations[pos];
			this.permutations[pos] = value;
			this.permutations[n + 256] = this.permutations[n];
		}
	}

	private final double lerp(double d, double n, double m) {
		return n + d * (m - n);
	}

	private final double grad(int n, double xm, double zm) {
		int i = n & 0xf;
		double v = (double)(1 - ((i & 8) >> 3)) * xm;
		double m = i >= 4 ? i != 12 && i != 14 ? zm : xm : 0.0D;
		return ((i & 1) != 0 ? -v : v) + ((i & 2) != 0 ? -m : m);
	}

	private final double grad(int n, double xm, double ym, double zm) {
		int i = n & 0xf;
		double v = i >= 8 ? ym : xm;
		double m = i >= 4 ? i != 12 && i != 14 ? zm : xm : ym;
		return ((i & 1) != 0 ? -v : v) + ((i & 2) != 0 ? -m : m);
	}

	public void generate(double noise[], double xoff, double yoff, double zoff, int xsize, int ysize, int zsize, double xscale, double yscale,
			double zscale, double scale) {
		if(ysize == 1) {
			boolean flag = false;
			boolean flag1 = false;
			boolean flag2 = false;
			boolean flag3 = false;
			double d8 = 0.0D;
			double d10 = 0.0D;
			int j3 = 0;
			double d12 = 1.0D / scale;
			for(int i4 = 0; i4 < xsize; i4++) {
				double d14 = (xoff + (double)i4) * xscale + this.xCoord;
				int j4 = (int)d14;
				if(d14 < (double)j4) {
					j4--;
				}
				int k4 = j4 & 0xff;
				d14 -= j4;
				double d17 = d14 * d14 * d14 * (d14 * (d14 * 6D - 15D) + 10D);
				for(int l4 = 0; l4 < zsize; l4++) {
					double d19 = (zoff + (double)l4) * zscale + this.zCoord;
					int j5 = (int)d19;
					if(d19 < (double)j5) {
						j5--;
					}
					int l5 = j5 & 0xff;
					d19 -= j5;
					double d21 = d19 * d19 * d19 * (d19 * (d19 * 6D - 15D) + 10D);
					int l = this.permutations[k4] + 0;
					int j1 = this.permutations[l] + l5;
					int k1 = this.permutations[k4 + 1] + 0;
					int l1 = this.permutations[k1] + l5;
					double d9 = lerp(d17, grad(this.permutations[j1], d14, d19), grad(this.permutations[l1], d14 - 1.0D, 0.0D, d19));
					double d11 = lerp(d17, grad(this.permutations[j1 + 1], d14, 0.0D, d19 - 1.0D),
							grad(this.permutations[l1 + 1], d14 - 1.0D, 0.0D, d19 - 1.0D));
					double d23 = lerp(d21, d9, d11);
					noise[j3++] += d23 * d12;
				}

			}

			return;
		}
		int i1 = 0;
		double d7 = 1.0D / scale;
		int i2 = -1;
		boolean flag4 = false;
		boolean flag5 = false;
		boolean flag6 = false;
		boolean flag7 = false;
		boolean flag8 = false;
		boolean flag9 = false;
		double d13 = 0.0D;
		double d15 = 0.0D;
		double d16 = 0.0D;
		double d18 = 0.0D;
		for(int i5 = 0; i5 < xsize; i5++) {
			double d20 = (xoff + (double)i5) * xscale + this.xCoord;
			int k5 = (int)d20;
			if(d20 < (double)k5) {
				k5--;
			}
			int i6 = k5 & 0xff;
			d20 -= k5;
			double d22 = d20 * d20 * d20 * (d20 * (d20 * 6D - 15D) + 10D);
			for(int j6 = 0; j6 < zsize; j6++) {
				double d24 = (zoff + (double)j6) * zscale + this.zCoord;
				int k6 = (int)d24;
				if(d24 < (double)k6) {
					k6--;
				}
				int l6 = k6 & 0xff;
				d24 -= k6;
				double d25 = d24 * d24 * d24 * (d24 * (d24 * 6D - 15D) + 10D);
				for(int i7 = 0; i7 < ysize; i7++) {
					double d26 = (yoff + (double)i7) * yscale + this.yCoord;
					int j7 = (int)d26;
					if(d26 < (double)j7) {
						j7--;
					}
					int k7 = j7 & 0xff;
					d26 -= j7;
					double d27 = d26 * d26 * d26 * (d26 * (d26 * 6D - 15D) + 10D);
					if(i7 == 0 || k7 != i2) {
						i2 = k7;
						int j2 = this.permutations[i6] + k7;
						int k2 = this.permutations[j2] + l6;
						int l2 = this.permutations[j2 + 1] + l6;
						int i3 = this.permutations[i6 + 1] + k7;
						int k3 = this.permutations[i3] + l6;
						int l3 = this.permutations[i3 + 1] + l6;
						d13 = lerp(d22, grad(this.permutations[k2], d20, d26, d24), grad(this.permutations[k3], d20 - 1.0D, d26, d24));
						d15 = lerp(d22, grad(this.permutations[l2], d20, d26 - 1.0D, d24), grad(this.permutations[l3], d20 - 1.0D, d26 - 1.0D, d24));
						d16 = lerp(d22, grad(this.permutations[k2 + 1], d20, d26, d24 - 1.0D), grad(this.permutations[k3 + 1], d20 - 1.0D, d26, d24 - 1.0D));
						d18 = lerp(d22, grad(this.permutations[l2 + 1], d20, d26 - 1.0D, d24 - 1.0D),
								grad(this.permutations[l3 + 1], d20 - 1.0D, d26 - 1.0D, d24 - 1.0D));
					}
					double d28 = lerp(d27, d13, d15);
					double d29 = lerp(d27, d16, d18);
					double d30 = lerp(d25, d28, d29);
					noise[i1++] += d30 * d7;
				}

			}

		}

	}
}
