/*
 * Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
 * Copyright 2007-2008 Pierre-Benoît Besse <besse.pb@gmail.com>
 * 
 * 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 2 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 CHARACTER_H
#define CHARACTER_H

#include "element.h"

/**
 * @brief This class describes the common characteristics and behaviour of the game characters (Kapman and the Ghost).
 */
class Character : public Element {

	Q_OBJECT

	public:

		/** Speed on easy level */
		static const qreal LOW_SPEED;

		/** Speed on medium level */
		static const qreal MEDIUM_SPEED;

		/** Speed on hard level */
		static const qreal HIGH_SPEED;

		/** Speed increase on easy level (percentage)  */
		static const qreal LOW_SPEED_INC;

		/** Speed increase on medium level (percentage)  */
		static const qreal MEDIUM_SPEED_INC;

		/** Speed increase on hard level (percentage) */
		static const qreal HIGH_SPEED_INC;

	protected:

		/** The Character x-speed */
		qreal m_xSpeed;

		/** The Character y-speed */
		qreal m_ySpeed;

		/** The character speed */
		qreal m_speed;

		/** Reference to the speed of the character when in "normal" behaviour */
		qreal m_normalSpeed;

		/** The value the character's speed is incremented by when level up */
		qreal m_speedIncrease;

		/** The maximum character speed */
		qreal m_maxSpeed;

	public:

		/**
		 * Creates a new Character instance.
		 * @param p_x the initial x-coordinate
		 * @param p_y the initial y-coordinate
		 * @param p_maze the Maze the Character is on
		 */
		Character(qreal p_x, qreal p_y, Maze* p_maze);

		/**
		 * Deletes the Character instance.
		 */
		~Character();

		/**
		 * Makes the Character go up.
		 */
		virtual void goUp() = 0;

		/**
		 * Makes the Character go down.
		 */
		virtual void goDown() = 0;

		/**
		 * Makes the Character go to the right.
		 */
		virtual void goRight() = 0;

		/**
		 * Makes the Character go to the left.
		 */
		virtual void goLeft() = 0;

		/**
		 * Updates the Character move.
		 */
		virtual void updateMove() = 0;

		/**
		 * Moves the Character function of its current coordinates and speed.
		 * If the character reaches a border, it circles around the maze and continue its way from the other side.
		 */
		void move();

		/**
		 * Manages the character death (essentially blinking).
		 */
		void die();

		/**
		 * Gets the Character x-speed value.
		 * @return the x-speed value
		 */
		qreal getXSpeed() const;

		/**
		 * Gets the Character y-speed value.
		 * @return the y-speed value
		 */
		qreal getYSpeed() const;

		/**
		 * Gets the Character speed.
		 * @return the character speed
		 */
		qreal getSpeed() const;

		/**
		 * Gets the Character normal speed.
		 * @return the character speed reference, when in "normal" behaviour
		 */
		qreal getNormalSpeed() const;
		
		/**
		 * Set the Character x-speed value.
		 * @param p_xSpeed the x-speed to set
		 */
		 void setXSpeed(qreal p_xSpeed);
		 
		/**
		 * Set the Character y-speed value.
		 * @param p_ySpeed the y-speed to set
		 */
		 void setYSpeed(qreal p_ySpeed);

		/**
		 * Initializes the Character speed considering the difficulty level.
		 */
		void initSpeed();

		/**
		 * Checks the Character is in the line of sight of the given other Character.
		 * @param p_character the other Character
		 * @return true if the Character is in the same line than the given one
		 */
		bool isInLineSight(Character* p_character);

		/**
		 * Increases the Character speed with each level completed.
		 */
		void increaseCharactersSpeed();

	protected:

		/**
		 * Initializes the Character speed increment considering the difficulty level.
		 */
		virtual void initSpeedInc() = 0;
		 
		/**
		 * Gets the next Cell the Character is going to reach.
		 * @return the next Cell the Character is going to reach
		 */
		Cell getNextCell();

		/**
		 * Checks the Character gets on a Cell center during its next movement.
		 * @return true if the Character is on a Cell center, false otherwise
		 */
		bool onCenter();

		/**
		 * Moves the character on the center of its current Cell.
		 */
		void moveOnCenter();

	signals:

		/**
		 * Emitted when the character is eaten.
		 */
		void eaten();
};

#endif

