"""
gmlp.mutations
==============
Used for mutating your population. 
\n``More mutations are to come in future versions.``
"""
import random


def ValueEncodingMut(population, mutation_prob):
	"""
	Value Encoding Mutation.

	:param population: the population you will be mutating. The have genes like this -> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

	:param mutation_prob: the mutation probability usually .15 but you'll have to see what's best for you.
	"""
	for pop in range(len(population)):
		if random.random() < mutation_prob:
			random_population_org = random.randint(0, len(population)-1)
			popped_org = population.pop(random_population_org)
			for c in range(len(popped_org)):
				if random.random() < .5:
					popped_org[c] += 1
				else:
					popped_org[c] -= 1
			population.insert(random_population_org, popped_org)
	return population

def ShuffleMut(population, mutation_prob):
	"""
	Shuffle mutation.

	:param population: Your selected population you wish to mutate.

	:param mutation_prob: The probability that your organisms will mutate.
	"""
	if not population == list(population):
		population = list(population)
	for pop in range(len(population)):
		if random.random() < mutation_prob:
			rand_pop_place = random.randint(0, len(population)-1)
			random.shuffle(population[rand_pop_place])
	return population

def BinaryInvertMut(population, mutation_prob):
	"""
	Inverts your binary population.

	:param population: Your selected population you wish to mutate.

	:param mutation_prob: The probability that your organisms will mutate.
	"""
	for n in range(len(population)):
		if random.random() < mutation_prob:
			rand = random.randint(0, len(population)-1)
			if population[rand] == 0:
				population[rand] = 1
			else:
				population[rand] = 0
	return population