/*
  File name: Enemy.h
  Copyright: (C) 2008 - 2009 Tomasz Kazmierczak

  Creation date: 13.04.2008
  Last modification date: 13.06.2009

  This file is part of Cytadela

 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program. If not, see <http://www.gnu.org/licenses/>.  *

*/

#ifndef _ENEMY_H_
#define _ENEMY_H_

#include "GameObjectsManager.h"

typedef enum {
	EUR_UNDEFINED,
	EUR_WALK,
	EUR_AIMING,
	EUR_SHOT,
	EUR_BURNING,
	EUR_BURNT,
	EUR_DEAD
} EnemyUpdateResult;

//NOTE: the material related calculations in functions across the class depend on data structure
//of the map files (which is not the best solution, I think)
class Enemy : public GOSprite {
private:
	enum {
		CAN_BURN = 2,
		CAN_BE_PARALIZED = 4
	};

	typedef enum {
		ANIM_WALK,
		ANIM_SHOT,
		ANIM_HIT
	} AnimType;

	bool      mBurning;
	uint32_t  mBurningTime;
	int32_t   mFireSoundChannel;
	uint32_t  mDyingTime;
	uint32_t  mBasicMaterialNumber;
	uint8_t   mFlags;
	uint8_t   mWeaponType;
	AnimType  mAnimType;
	uint32_t  mAnimTime;
	uint32_t  mAnimFrame1;
	uint32_t  mAnimFrame2;
	Vector3Dg mDirection;
	Vector3Dg mActualVelocity;
	Vector3Dg mPosition;
	float     mSpeed;
//	uint16_t  mSomething;
	uint16_t  mAgression;
	float     mAmmoXPosShift;
	float     mAmmoYPosShift;

	void finalTransformation();
	int32_t calculateVolume(float distaince);
	void rotateTowardsPlayer(Vector3Dg &playerPosition);
	void randomDirection();

public:
	Enemy(Mesh3Dg *mesh);

	EnemyUpdateResult update(uint32_t timeDiff, Vector3Dg &playerPosition);
	int16_t hit(int16_t power, Vector3Dg &playerPosition);
	bool burn();
	void die();
	void shoot();
	void move();

	void registerSound(int32_t fireSoundChannel) { mFireSoundChannel = fireSoundChannel; }
	void unregisterSound() { mFireSoundChannel = -1; }
	bool isBurning() { return mBurning; }
	bool isAlive() { return mHP >= 0; }

	bool canBurn() { return mFlags & CAN_BURN; }
	bool canBeParalized() { return mFlags & CAN_BE_PARALIZED; }

	void setFlags(uint8_t flags) { mFlags = flags; }
	void setWeaponType(uint8_t weaponType) { mWeaponType = weaponType; }
	void setDirection(Vector3Dg &dir) { mDirection = dir; }
	void setActualVelocity(Vector3Dg &velocity) { mActualVelocity = velocity; }
	void setSpeed(float speed) { mSpeed = speed; }
//	void setSomething(uint16_t something) { mSomething = something; }
	void setAgression(uint16_t agression) { mAgression = agression; }
	void setAmmoYPosShift(float shift) { mAmmoYPosShift = shift; }
	void setAmmoXPosShift(float shift) { mAmmoXPosShift = shift; }

	uint8_t getFlags() { return mFlags; }
	uint8_t getWeaponType() { return mWeaponType; }
	Vector3Dg &getDirection() { return mDirection; }
	Vector3Dg &getActualVelocity() { return mActualVelocity; }
	Vector3Dg &getPosition() { return mPosition; }
	float getSpeed() { return mSpeed; }
//	uint16_t getSomething() { return mSomething; }
	uint16_t getAgression() { return mAgression; }
	float getAmmoXPosShift() { return mAmmoXPosShift; }
	float getAmmoYPosShift() { return mAmmoYPosShift; }
};

#endif //_ENEMY_H_
