#include "Soldier.h"
#include "../Graphics/Animation.h"
#include "Wildling.h"
#include "Den.h"

namespace mechanics {

	Soldier::Soldier(Human &generatefrom) : Human(generatefrom.animator, generatefrom.animatorHair, OwnerType::player, generatefrom.gender())
	{
		mStat = generatefrom.stat();
		mLevel = generatefrom.level();
		mXp = generatefrom.xp();
		mName = generatefrom.name();
		mSurname = generatefrom.surname();
		mIsControllable = true;
		mHP = generatefrom.HP();
		mStamina = generatefrom.stamina();

		setAnimation(South, "Stand", false);

		Item &body=*new Item(*assets::Item::list["Unarmored"], *new graphics::Animation(*assets::Item::list["Unarmored"]->animation));
		addItem(body, true);

		log("Yes sir!");

		mAttackCooldown=baseAttackCooldown();
	}

	std::string Soldier::info() {
		std::stringstream out;

		out << "Level " << level() << " XP " << (int)xp() << std::endl
			<< ((gender() == Gender::male) ? "Male" : "Female") << std::endl
			<< stat() << std::endl
			<< "HP: " << HP() << "/" << maximumHP() << "Sta: " << stamina() << "/" << maximumStamina();

		return out.str();
	}

	void Soldier::levelUp() {
		if(mLevel + 1 > assets::constants::leveling::soldierLvlCap) {
			return;
		}

		Human::levelUp();
	}

	unsigned Soldier::lastPaymentCheck() const {
		return mLastPaymentCheck;
	}

	void Soldier::lastPaymentCheck(unsigned value) {
		mLastPaymentCheck = value;
	}

	void Soldier::setAnimation(Direction direction, std::string animationID, bool isLooping, float speed) {
		Human::setAnimation(direction, animationID, isLooping, speed);
		if(mInventory.headArmor)
			mInventory.headArmor->setAnimation(direction, animationID, isLooping, speed);
		if(mInventory.bodyArmor)
			mInventory.bodyArmor->setAnimation(direction, animationID, isLooping, speed);
		if(mInventory.mainHand)
			mInventory.mainHand->setAnimation(direction, animationID, isLooping, speed);
		if(mInventory.offHand)
			mInventory.offHand->setAnimation(direction, animationID, isLooping, speed);
	}

	void Soldier::setDirection(Direction direction, std::string animationID) {
		Human::setDirection(direction, animationID);
		if(mInventory.headArmor)
			mInventory.headArmor->setDirection(direction, animationID);
		if(mInventory.bodyArmor)
			mInventory.bodyArmor->setDirection(direction, animationID);
		if(mInventory.mainHand)
			mInventory.mainHand->setDirection(direction, animationID);
		if(mInventory.offHand)
			mInventory.offHand->setDirection(direction, animationID);
	}

	void Soldier::doAction(gge::utils::Point pnt) {
		mechanics::Object *target=mechanics::Map::current().getPointInfoMap()(pnt).object;

		if(actionType==TRAIN) {
			auto tb=dynamic_cast<mechanics::TrainingBuilding*>(actionTarget);
			tb->release(trainPoint);
			actionType=NONE;
			actionTarget=NULL;
		}

		if(dynamic_cast<mechanics::Wildling*>(target) || dynamic_cast<mechanics::Den*>(target)) {
			if(!mInventory.mainHand) {
				log("No weapon!");
				setAnimation(South, "Stand");
			}
			else {
				log("Chaaarge!");
				attackTo(target);
			}
			return;
		}
		else if(dynamic_cast<mechanics::TrainingBuilding*>(target)) {
			auto tb=dynamic_cast<mechanics::TrainingBuilding*>(target);
			if(!mInventory.mainHand) {
				log("No weapon!");
				setAnimation(South, "Stand");
			}
			else if( (mInventory.mainHand->ranged() && !tb->ranged()) || (mInventory.mainHand->melee() && !tb->melee()) ) {
				log("Cannot train there.");
				setAnimation(South, "Stand");
			}
			else if( level()>=tb->provider().maxLvl ) {
				log("Cannot train there.");
				setAnimation(South, "Stand");
			}
			else if(!tb->isAvailable()) {
				log("No room to train.");
				setAnimation(South, "Stand");
			}
			else {
				log("Yes sir!");
				startTraining(tb);
			}
			return;
		}

		Human::doAction(pnt);
	}

	void Soldier::Killed(Attacker *attacker, BaseWeapon *weapon) {
		Human::Killed(attacker, weapon);
		PlayerGame::current().destroySoldier(this);

		Map::current().getPointInfoMap()(location).walkable=true;
		Map::current().getPointInfoMap()(location).object=NULL;
	}

}