#include "Move.h"
#include <time.h>

	Move::Move(const char* name, int id) : currPose(0), active(false), struck(false), attackLimb(NULL), target(NULL), moveId(id)
	{
		m_name = new char[256];
		strcpy(m_name, name);
	}

	void Move::addConfiguration(Configuration *c)
	{
		poses.append(c);
		currPose = poses.size() - 1;
	}

	void Move::deleteConfiguration(int index)	{	poses.fastRemove(index);	}

	int Move::deleteCurrentConfiguration()
	{
		poses.fastRemove(currPose);
		currPose = 0;
		return poses.size();
	}

	// Note: returns NULL if index is out of range
	Configuration* Move::getConfiguration(int index)
	{
		if (0 <= index && index < poses.size()) {
			return poses[index];
		}
		return NULL;
	}

	// Note: Does nothing if index is out of range
	void Move::setConfiguration(int index, Configuration *c)
	{
		if (0 <= index && index < poses.size()) {
			poses[index] = c;
			currPose = index;
		}
	}

	// WARNING: May be NULL if not initialized
	Configuration *Move::getCurrentConfiguration(void)	{	return poses[currPose];	}

	void Move::setCurrentConfiguration(Configuration *c) {	poses[currPose] = c;	}

	void Move::selectConfiguration(int index)
	{
		if (0 <= index && index < poses.size()) {
			currPose = index;
		}
	}

	Configuration *Move::nextPose(void)
	{
		if (active) {
			currPose++;
			if (currPose >= poses.size()) {
				if (struck || !strike()) {
					this->reset();
				} else {
					currPose--;
				}
			}
		}
		return poses[currPose];
	}

	bool Move::isStriking(void)	{	return struck;	}

	char *Move::name(void)	{	return m_name;	}

	int Move::numPoses(void)	{	return poses.size();	}

	void Move::activate()	{	active = true;	}

	bool Move::isActive(void)	{	return active;	}

	void Move::reset(void)
	{
		currPose = 0;
		active = false;
		struck = false;
	}

	void Move::setAttackLimb(PullPoint* limb)	{	attackLimb = limb;	}

	void Move::setTarget(Entity::Part* t)	{	target = t;	}

	PullPoint* Move::getAttackLimb(void)	{	return attackLimb;	}

	Entity::Part* Move::getTarget(void)	{	return target;	}

	void Move::setTargetName(std::string name)	{	targetName = name;	}

	std::string Move::getTargetName(void) {	return targetName;	}

	int Move::getId(void)		{	return moveId;	}

	bool Move::strike(void)
	{
		if (NULL != attackLimb && NULL != target) {
			Vector3 dist = (attackLimb->frame().translation - target->frame().translation);
			if (abs(dist.x) > 2 || abs(dist.y) > 2 || abs(dist.z) > 2) return false;
			attackLimb->moveTo(target->frame().translation);
			attackLimb->attackForce();
			struck = true;
			return true;
		}
		return false;
	}

	bool Move::inConfiguration(void)	{	return poses[currPose]->inPosition();	}

	Move::~Move(void)
	{
		delete m_name;
		for (int i = 0; i < poses.size(); i++) {
			delete poses[i];
		}
	}