// Path: prngine/src/main/java/io/jenetics/prngine/Bytes.java
// static int readInt(final byte[] bytes, final int index) {
// 	final int offset = index*Integer.BYTES;
// 	if (offset + Integer.BYTES > bytes.length) {
// 		throw new IndexOutOfBoundsException(format(
// 			"Not enough data to read int value (index=%d, bytes=%d).",
// 			index, bytes.length
// 		));
// 	}
// 
// 	return
// 		((bytes[offset    ] & 255) << 24) +
// 		((bytes[offset + 1] & 255) << 16) +
// 		((bytes[offset + 2] & 255) << 8) +
// 		((bytes[offset + 3] & 255));
// }


import static java.lang.String.format;
import static io.jenetics.prngine.Bytes.readInt;
/*
 * PRNGine - Java PRNG Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
 */
package io.jenetics.prngine;


/**
 * This is a 32-bit version of Mersenne Twister pseudorandom number generator.
 * <p>
 * <i>
 * References: M. Matsumoto and T. Nishimura, "Mersenne Twister: a
 * 623-dimensionally equidistributed uniform pseudorandom number generator".
 * ACM Transactions on Modeling and Computer Simulation 8. (Jan. 1998) 3--30.
 * </i>
 * <p>
 * <em>
 * This is a port of the
 * <a href="https://github.com/rabauke/trng4/blob/master/src/mt19937.hpp">
 * trng::mt19937</a> PRNG class of the
 * <a href="https://github.com/rabauke/trng4/blob/master/doc/trng.pdf">TRNG</a> library created by Heiko
 * Bauke.</em>
 *
 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 * @since 1.0
 * @version 2.0.0
 */
public class MT19937_32Random extends Random32 implements SplittableRandom {

	private static final int N = 624;
	private static final int M = 397;

	private static final int UM = 0x80000000; // most significant bit
	private static final int LM = 0x7FFFFFFF; // least significant 31 bits

	private static final int[] MAG01 = {0, 0x9908b0df};


	/**
	 * The internal state of this PRNG.
	 */
	private static final class State {
		int mti = 0;
		int[] mt = new int[N];

		State(final byte[] seed) {
			setSeed(seed);
		}

		State(final long seed) {
			setSeed(seed);
		}

		void setSeed(final byte[] seed) {
			if (seed.length < SEED_BYTES) {
				throw new IllegalArgumentException(format(
					"Required %d seed bytes, but got %d.",
					SEED_BYTES, seed.length
				));
			}

			for (mti = 0; mti < N; ++mti) {
// Path: prngine/src/main/java/io/jenetics/prngine/Bytes.java
// static int readInt(final byte[] bytes, final int index) {
// 	final int offset = index*Integer.BYTES;
// 	if (offset + Integer.BYTES > bytes.length) {
// 		throw new IndexOutOfBoundsException(format(
// 			"Not enough data to read int value (index=%d, bytes=%d).",
// 			index, bytes.length
// 		));
// 	}
// 
// 	return
// 		((bytes[offset    ] & 255) << 24) +
// 		((bytes[offset + 1] & 255) << 16) +
// 		((bytes[offset + 2] & 255) << 8) +
// 		((bytes[offset + 3] & 255));
// }


// Path: prngine/src/main/java/io/jenetics/prngine/MT19937_32Random.java
import static java.lang.String.format;
import static io.jenetics.prngine.Bytes.readInt;

/*
 * PRNGine - Java PRNG Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
 */
package io.jenetics.prngine;


/**
 * This is a 32-bit version of Mersenne Twister pseudorandom number generator.
 * <p>
 * <i>
 * References: M. Matsumoto and T. Nishimura, "Mersenne Twister: a
 * 623-dimensionally equidistributed uniform pseudorandom number generator".
 * ACM Transactions on Modeling and Computer Simulation 8. (Jan. 1998) 3--30.
 * </i>
 * <p>
 * <em>
 * This is a port of the
 * <a href="https://github.com/rabauke/trng4/blob/master/src/mt19937.hpp">
 * trng::mt19937</a> PRNG class of the
 * <a href="https://github.com/rabauke/trng4/blob/master/doc/trng.pdf">TRNG</a> library created by Heiko
 * Bauke.</em>
 *
 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
 * @since 1.0
 * @version 2.0.0
 */
public class MT19937_32Random extends Random32 implements SplittableRandom {

	private static final int N = 624;
	private static final int M = 397;

	private static final int UM = 0x80000000; // most significant bit
	private static final int LM = 0x7FFFFFFF; // least significant 31 bits

	private static final int[] MAG01 = {0, 0x9908b0df};


	/**
	 * The internal state of this PRNG.
	 */
	private static final class State {
		int mti = 0;
		int[] mt = new int[N];

		State(final byte[] seed) {
			setSeed(seed);
		}

		State(final long seed) {
			setSeed(seed);
		}

		void setSeed(final byte[] seed) {
			if (seed.length < SEED_BYTES) {
				throw new IllegalArgumentException(format(
					"Required %d seed bytes, but got %d.",
					SEED_BYTES, seed.length
				));
			}

			for (mti = 0; mti < N; ++mti) {
				mt[mti] = readInt(seed, mti);