//Program name: Chao Object
//Author: Jeffery Wright
//Date: 2017/02/11
//Description: Class defining traits and behavior of a Chao object.

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

#include "Stat.h"
#include "Evolution.h"
#include "Breed.h"
#include "Chao.h"

using namespace std;

	//Constructs a default chao.
	Chao::Chao () {
		name = "_";
		age = 0;
		lastUpdated = time(0);
		reincarnations = 0;
		swim =  Stat();
		run = Stat();
		power = Stat();
		fly = Stat();
		stamina = Stat();
		evolution = Evolution();
		breed = Breed();
	} //end constructor

	//Creates a purebred chao from the chosen traits.
	Chao::Chao(int color, int coat, bool shiny, bool twotone) {
		name = "_";
		age = 0;
		lastUpdated = time(0);
		reincarnations = 0;
		swim =  Stat();
		run = Stat();
		power = Stat();
		fly = Stat();
		stamina = Stat();
		evolution = Evolution();
		breed = Breed(color, coat, shiny, twotone);
	} //end constructor

	//Creates a newborn Chao based on the stats and breed of two parents
	Chao::Chao(Chao parent1, Chao parent2) {
		name = "_";
		age = 0;
		lastUpdated = time(0);
		reincarnations = 0;
		swim =  Stat(parent1.getSwim(), parent2.getSwim());
		run = Stat(parent1.getRun(), parent2.getRun());
		power = Stat(parent1.getPower(), parent2.getPower());
		fly = Stat(parent1.getFly(), parent2.getFly());
		stamina = Stat(parent1.getStamina(), parent2.getStamina());
		evolution = Evolution();
		breed = Breed(parent1.getBreed(), parent2.getBreed());
	} //end constructor

	//Loads a Chao from the given ifstream.
	Chao::Chao(ifstream &in) {
		string labels;
	in >> labels;
		in >> name;
	in >> labels;
		in >> age;
		lastUpdated = time(0);
		in >> labels;
		in >> reincarnations;
	validate();
	in >> labels;
		swim = Stat(in);
	in >> labels;
		run = Stat(in);
	in >> labels;
		power = Stat(in);
	in >> labels;
		fly = Stat(in);
	in >> labels;
		stamina = Stat(in);
	in >> labels;
		evolution = Evolution(in);
		breed = Breed(in);
	} //end constructor

	//Determines a Chao's First Evolution, and reset's the evolution sliders.
	void Chao::evolve() {
		evolution.evolve();
		int statToRankUp = (evolution.getEvolution() - 5) / 3;
	if (statToRankUp == 1) {
			swim.rankUp();
		} else if (statToRankUp == 3) {
			run.rankUp();
		} else if (statToRankUp == 4) {
			power.rankUp();
		} else if (statToRankUp == 2) {
			fly.rankUp();
		} else if (statToRankUp == 0) {
			stamina.rankUp();
		} //end if
	} //end function

	//Returns the Chao to a newborn and reduces their stats to 10%.
	void Chao::reincarnate() {
		age = 0;
		lastUpdated = time(0);
		reincarnations++;
		swim.reincarnate();
		run.reincarnate();
		power.reincarnate();
		fly.reincarnate();
		stamina.reincarnate();
		evolution.reincarnate();
		cout <<name << " reincarnated" << endl;
	} //end function
	
	void Chao::setName(string newName) {name = newName;}
	
	//Updates the Chao's age.
	void Chao::updateAge() {
		int timeAged = time(0) - lastUpdated;
		age+= timeAged;
		lastUpdated = time(0);
	} //end function


	//Prints the Chao's Stats.
	void Chao::printStats() {
		cout << "Swim: ";
		swim.print();
		cout << "Run: ";
		run.print();
		cout << "Power: ";
		power.print();
		cout << "Fly: ";
		fly.print();
		cout << "Stamina: ";
		stamina.print();
	} //end function

	//Pet the Chao.
	void Chao::pet(int alignment) {evolution.pet(alignment);}

//Gives Chao a Fruit.
void Chao::giveFruit(Fruit fruit) {
	while (fruit.getBitesLeft() > 0) {
		giveStatItem(fruit.getStats());
		fruit.takeABite();
	} //end while
} //end function

//GivesChao a Stat Item.
void Chao::giveStatItem(StatItem stats) {
	swim.experienceBoost(stats.getSwim());
	run.experienceBoost(stats.getRun());
	power.experienceBoost(stats.getPower());
	fly.experienceBoost(stats.getFly());
	stamina.experienceBoost(stats.getStamina());
} //end function

//Gives Chao an Evolution Item.
void Chao::giveEvolutionItem(EvolutionItem evo) {
	evolution.giveEvolutionItem(evo);
} //end function

//validates data members.
void Chao::validate() {
	if (name == "" || name == " ") {name = "_";}
	if (age < 0) {age =0;}
	if (reincarnations < 0) {reincarnations = 0;}
} //end function

	//Saves the chao.
	void Chao::save(ofstream &out) {
		validate();
		out << "Name: " << name << endl;
		out << "Age: " << age << endl;
		out << "Reincarnation: " << reincarnations << endl;
		out << "Swim: ";
		swim.save(out);
		out << "Run: ";
		run.save(out);
		out << "Power: ";
		power.save(out);
		out << "Fly: ";
		fly.save(out);
		out << "Stamina: ";
		stamina.save(out);
		out << "Evolution: ";
		evolution.save(out);
		breed.save(out);
	} //end function
