// This file is part of ThriceBall.
//
// Author: Kai Hillenbrand (AnTeevY)
// © Copyright, 2009 by Kai Hillenbrand, http://www.anteevy.de

// --------------------------------------------------

#pragma once
#ifndef PLAYER_H
#define PLAYER_H

// intern includes
#include "renderer.h"
#include "audio.h"

class CRenderer;
class CAudio;
class CInterface;

// --------------------------------------------------

class CPlayer
{
public:
	CPlayer(CRenderer *renderer, OGRE3DRenderSystem *rendersys);

	void update(float winWidth, float winHeight);		// update player, called each frame
	void updateArrow(float winWidth, float winHeight);	// repositions the direction arrow
	void updateEnergy();								// update the player's energy
	void gameWin();										// made it to the finish
	void gameOver();									// time ran out
	void restart();										// restart the level
	Vector3 realToVec(NxOgre::Real3 real)				// Real3 to Vector3
		{return Vector3(real.x, real.y, real.z);}

	// ball functions
	void switchBall();									// switch through the balls	
	void updateCurPower();								// charge shot
	void applyMove();									// give the current ball a shot
	void cancelShot();									// cancel the currently charged shot	
	void updateBrake();									// stop the ball smoothly	
	void respawn();										// respawn at last checkpoint

	// get functions
	float getCurPower(){return m_fCurPower;}			// current shot power
	float getCurPowerMult();							// current shot power multiplier
	float getEnergy(){return m_fEnergy;}				// current energy
	int getCurBallNum(){return m_iCurBallNum;}			// current ball's number
	int getPeriod();									// current period in the level (has 3 periods depending on time)
	bool isInShotMode(){return (getCurBall()->getLinearVelocity().magnitude() < m_fSpeedEdge);}	// in shot mode?
	bool isCharging(){return m_bCharging;}				// is charging?
	bool isBraking(){return m_bBraking;}				// is braking?
	bool isStillPlaying(){if (m_iGameState == 0) return true; else return false;}	// player still playing?
	SceneNode* getArrowNode(){return m_pArrowNode;}		// get the arrow scene node
	OGRE3DBody* getCurBall();							// get the current ball as an OGRE3DBody pointer
	Vector3 getCurBallPos();							// get the current ball's position
	NxOgre::Vec3 getRespawnPos(){return m_vRespawnPos;}	// get the respawn position (1 above the checkpoint)
	String getQuitMsg();								// returns the quit message (game won/lost/aborted)
	
	// set functions	
	void reduceEnergy(float amount);									// reduce energy by certain amount
	void setEnergies(float shot, float brake, float death, float time);	// set the level energy attributes
	void setCurBall(int num);											// change the ball number
	void canChangeType(bool can){m_bCanChangeType = can;}				// is the player able to change the ball number?
	void setBallPos(NxOgre::Vec3 pos);									// move current ball to position
	void setRespawnPos(NxOgre::Vec3 pos, int color);					// set the new respawn position
	void setCharging(bool charge);										// set true, if charging
	void setBraking(bool brake);										// set true, if braking
	void refillEnergy(){m_fEnergy = m_fPossibleEnergy = 100.f;}			// set the energy back to 100%

private:
	// private functions
	void createBalls();		// setup the balls
	void createArrow();		// setup the arrow
	void calcMouseDir(float winWidth, float winHeight);	// calculates the mouse direction vector
	void resetCurPower(){m_fCurPower = m_fMinShotPower; m_bCharging = false;}	// reset the shot power

	// OGRE variables
	OGRE3DRenderSystem	*m_pRenderSystem;	// render system
	SceneManager		*m_pSceneMgr;		// scene manager
	Camera				*m_pCamera;			// pointer to main camera
	SceneNode			*m_pArrowNode;		// the direction arrow's scene node
	OGRE3DBody			*m_pBallRed,		// the player balls
						*m_pBallGreen, 
						*m_pBallBlue;	

	// pointers to instances
	CRenderer	*m_pRenderer;
	CAudio		*m_pAudio;
	CInterface	*m_pInterface;
	
	// general variables
	float	m_fSpeedEdge;			// if speed below, enable shot mode, else, enable break mode
	int		m_iCurBallNum;			// currently controlled ball (1: red; 2: green; 3: blue)
	int		m_iGameState;			// current game state (0: playing; 1: lost; 2: won)
	bool	m_bBallShadows;			// shall the balls cast shadows? (hardware expensive)		
	bool	m_bCanChangeType;		// is the player able to change the ball number?
	bool	m_bCharging;			// currently charging the ball's shot power?
	bool	m_bBraking;				// currently braking the ball?
	Vector3 m_vMouseDir;			// normalized ball to mouse direction vector
	NxOgre::Vec3	m_vCurBallPos,	// the ball's current position
					m_vRespawnPos;	// and it's respawm position

	// shot variables
	float	m_fCurPower,			// current shot-power
			m_fMaxShotPower,		// maximum charge power, constant
			m_fMinShotPower,		// minimum (reset) charge power, constant
			m_fIncreasePercentage,	// how fast the shot shall be charged, constant
			m_fPowerMult,			// final force multiplier, constant
			m_fBrakePower,			// the break power, the lower, the more effective, constant
			m_fRedPowerMult,		// red ball's shot power multiplier
			m_fGreenPowerMult,		// green ball's shot power multiplier
			m_fBluePowerMult;		// blue ball's shot power multiplier

	// energy variables
	float	m_fEnergy,				// current energy
			m_fPossibleEnergy,		// the energy after a shot
			m_fShotEnergyCost,		// the amount of energy a full shot costs, constant
			m_fDeathEnergyCost,		// the amount of energy that is withdrawn when the ball "dies"
			m_fBrakeEnergyCost,		// the amount of energy that is withdrawn per frame while braking
			m_fTimeEnergyCost;		// the amount of energy that is withdrawn per frame all the time
};

#endif