//Program name: Chao Evolution.
//Author: Jeffery Wright
//Date: 2013/06/24
//Description: Class defining the mechanisms of Chao Evolution.

#include <iostream>
#include <cstdlib>
#include <fstream>

#include "Evolution.h"

using namespace std;

//Creates a new evolution.
Evolution::Evolution () {
		evolution = 1;
		heroDark = 0;
		swimFly = 0;
		runPower = 0;
} //end constructor

//Loads an Evolution from the given ifstream.
Evolution::Evolution(ifstream &in) {
		in >> evolution >> heroDark >> swimFly >> runPower;
} //end constructor

//Accessors
	int Evolution::getEvolution() {return evolution;}
	string Evolution::getEvolutionText() {return EVOLUTIONS[evolution];}
	int Evolution::getHeroDark() {return heroDark;}
	int Evolution::getSwimFly() {return swimFly;}
	int Evolution::getRunPower() {return runPower;}

//Determines first Evolution and resets sliders.
void Evolution::evolve() {
	int evolutionValue = 0;
		if (heroDark < -25) {
		evolutionValue += 1;
		} else if (heroDark > 25) {
		evolutionValue += 2;
		}
		if (swimFly < -25 && runPower > swimFly && runPower < -swimFly) {
		evolutionValue +=8;
		} else if (runPower < -25 && swimFly > runPower && swimFly < -runPower) {
		evolutionValue += 14;
		} else if (runPower > 25 && swimFly < runPower && swimFly > -runPower) {
		evolutionValue += 17;
		} else if (swimFly > 25 && runPower < swimFly && runPower > -swimFly) {
		evolutionValue += 11;
		} else {
		evolutionValue += 5;
		} //end if
		swimFly = 0;
		runPower = 0;
		evolution = evolutionValue;
	} //end function

//Returns the Chao to an Egg and resets evolution sliders.
void Evolution::reincarnate() {
		evolution = 1;
		swimFly = 0;
		runPower = 0;
	} //end function

//Hatch the Chao.
void Evolution::hatch() {evolution = 2;}

//Applies effects of an Evolution Item.
void Evolution::giveEvolutionItem(EvolutionItem evo) {
	int strength = evo.getStrength();
	if (evolution == 2) {
		heroDark+=(evo.getAlignment()*evo.getStrength()*2);
		strength*=2;
	} //end if
	if (evo.getColor() == 1) {
		swimFly-=strength;
	} else if (evo.getColor() == 2) {
		swimFly+=strength;
	} else if (evo.getColor() == 3) {
		runPower-=strength;
	} else if (evo.getColor() == 4) {
		runPower+=strength;
	} else if (evo.getColor() >= 5) {
		int random = rand() % 4;
		if (random == 0) {
			swimFly-=strength;
		} else if (random == 1) {
			swimFly+=strength;
	} else if(random == 2) {
			runPower-=strength;	
		} else if (random == 3) {	
			runPower+=strength;	
		} //end if	
	} //end if
} //end function

//Prints a graphical representation of the input slider value.
void Evolution::printSlider(int value) {
		value += 50;
		value /= 10;
		for (int i = 0; i <= 10; i++) {
			if (i == 5 && value ==5) {
				cout << "O";
			} else if (i == 5) {
				cout << "o";
			} else if (i == value) {
				cout << "+";
			} else {
				cout << "=";
			} //end if
		} //end for
	} //end function
		
//Prints Sliders.
void Evolution::printSliders() {
		cout << "Hero\t<";
		printSlider(heroDark);
		cout << ">\tDark" << endl;
		cout << "Swim\t<";
		printSlider(swimFly);
		cout << ">\tFly" << endl;
		cout << "Run\t<";
		printSlider(runPower);
		cout << ">\tPower" << endl;
	} //end function

//Ensures that a slider does not exceed its bounds.
int Evolution::validateSlider(int value) {
		if (value > 50) {
			value = 50;
		} else if (value < -50) {
			value = -50;
		} //end if
		return value;
	} //end function

//Pet the Chao
void Evolution::pet(int alignment) {
		if (evolution == 2) {
			if (alignment == 0 && heroDark > 0) {
				heroDark--;
			} else if (alignment == 0 && heroDark < 0) {
				heroDark++;
				heroDark = validateSlider(heroDark);
			} else {
				heroDark += alignment;
			} //end if
		} //end if
	} //end function

//validates data members.
void Evolution::validate() {
	if (evolution < 0 || evolution > 25) {evolution = 0;}
	heroDark = validateSlider(heroDark);
	swimFly = validateSlider(swimFly);
	runPower = validateSlider(runPower);
} //end function

//Saves the evolution.
void Evolution::save(ofstream &out) {
	validate();
	out << evolution << " " << heroDark << " " << swimFly << " " << runPower << endl;
} //end function
