/*
 * Java Genetic Algorithm 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@gmx.at)
 */
package org.jenetics.engine;

import java.util.function.Function;

import org.jenetics.DoubleChromosome;
import org.jenetics.DoubleGene;
import org.jenetics.Gene;
import org.jenetics.Genotype;
import org.jenetics.IntegerChromosome;
import org.jenetics.IntegerGene;
import org.jenetics.LongChromosome;
import org.jenetics.LongGene;
import org.jenetics.util.Factory;

/**
 * A problem {@code Codec} contains the information about.
 *
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @version !__version__!
 * @since !__version__!
 */
public interface Codec<G extends Gene<?, G>, S> {

	/**
	 * Return the genotype factory, which represents the encoded problem domain.
	 *
	 * @return the genotype (factory) representation of the problem domain
	 */
	public Factory<Genotype<G>> encoding();

	/**
	 * Return the <em>decoder</em> function which transforms the genotype back
	 * to the original problem domain representation.
	 *
	 * @return genotype decoder
	 */
	public Function<Genotype<G>, S> decoder();


	public static Codec<IntegerGene, Integer> ofInteger(
		final int min,
		final int max
	) {
		return of(
			Genotype.of(IntegerChromosome.of(IntegerGene.of(min, max))),
			gt -> gt.getChromosome().getGene().getAllele()
		);
	}

	public static Codec<LongGene, Long> ofLong(
		final long min,
		final long max
	) {
		return of(
			Genotype.of(LongChromosome.of(LongGene.of(min, max))),
			gt -> gt.getChromosome().getGene().getAllele()
		);
	}

	public static Codec<DoubleGene, Double> ofDouble(
		final double min,
		final double max
	) {
		return of(
			Genotype.of(DoubleChromosome.of(DoubleGene.of(min, max))),
			gt -> gt.getChromosome().getGene().getAllele()
		);
	}

	/**
	 *
	 * @param encoding
	 * @param decoder
	 * @param <G>
	 * @param <S>
	 * @return
	 */
	public static <G extends Gene<?, G>, S> Codec<G, S> of(
		final Factory<Genotype<G>> encoding,
		final Function<Genotype<G>, S> decoder
	) {
		return new Codec<G, S>() {
			@Override
			public Factory<Genotype<G>> encoding() {
				return encoding;
			}

			@Override
			public Function<Genotype<G>, S> decoder() {
				return decoder;
			}
		};
	}

}

@@ -1161,17 +1161,296 @@
 on about
-.
+ how to encode a given%0A * argument type into a %7B@code Genotype%7D. It also lets convert the encoded%0A * %7B@code Genotype%7D back to the argument type.%0A *%0A * @param %3CT%3E the argument type of a given problem%0A * @param %3CG%3E the %7B@code Gene%7D type used for encoding the argument type %7B@code T%7D
 %0A *%0A * @
@@ -1626,17 +1626,17 @@
 %3C?, G%3E, 
-S
+T
 %3E %7B%0A%0A%09/*
@@ -1713,16 +1713,52 @@
 m domain
+%0A%09 * and argument type, respectively
 .%0A%09 *%0A%09 
@@ -2066,33 +2066,33 @@
 on%3CGenotype%3CG%3E, 
-S
+T
 %3E decoder();%0A%0A%0A%09

Add javadoc.