/*********************************************************************//**
*	\brief BasePhysics
*	Abstraktni trida definuje entity, na ktere se vztahuji fyzikalni zakony,
*	persneji receno pouzivaji dynamicky model.
*	
*	\author Michal Jirous
*	\date 23.04.2009
*	\file ent_basephysics.h
**********************************************************************/

#ifndef __BASE_PHYSICS_H__
#define __BASE_PHYSICS_H__

#include "ent_baseentity.h"
#include "interpolation.h"

const int NOT_IN_WATER = 0;
const int LEGS_IN_WATER = 1;
const int BODY_IN_WATER = 2;
const int HEAD_IN_WATER = 4;

#include "ctrl_gamevars.h"
extern variable *g_Gravity;
extern variable *g_FrictionNormalGround;

#include "physics.h"

class CBasePhysics : public CBaseEntity
{	
protected:
	Force m_TotalForce;
	Velocity m_Velocity;
	Weight m_Weight;	
	Friction m_TotalFriction;


	byte m_GroundMaterial;
	//bool m_bAddGravity;

	int m_iHullType;
	
	Interpolation m_InterpolatedPosition;	//interpolace pohybu

	Point m_Store_Position, m_Store_Angles;

	void createModel( int hull, bool originIsUp = false );
public:
	CBasePhysics();
	DynamicModel m_Model;	//kolizni model
	int m_iWaterLevel;
	bool m_bIsInAir, m_bStairsMovement;

	virtual void updateForces();
	virtual void prepareForCollision();

	virtual void render(  RenderData &renderData  );
	virtual void compile();
	virtual void update( float seconds );
	virtual bool collisionDetection( CollisionData &collData );
	virtual bool rayTrace( RayTraceData &rayData );	
	
	virtual void onUsage( const RayTraceData &rayData ) {}
	virtual void onPointing( const RayTraceData &rayData ) {}
	virtual void acceptVector( const alg::Vector &v );
	virtual void teleport( const alg::Vector &v, bool interpolation = true );
	virtual void onCollide_Initiator_this( CollisionData &collData, bool ground_normal = false );

	virtual void restart();
	virtual void goBackInTime();
	virtual void updateBackTime();

	void setMoveVector( const alg::Vector &v);
	Vector getMoveVector() { return m_Model.m_vecMovement; }
	virtual Point getRenderOrigin() { return m_InterpolatedPosition.current; }

	bool isInAir()	{ return m_bIsInAir; }
	int getWaterLevel()	{ return m_iWaterLevel; }

	int getHullType() { return m_iHullType; }

	void addForce( const Force &force );
	void addFriction( float friction );
	Force getForceOfMovement();

	Force getForce()	{ return m_TotalForce; }
	Velocity getVelocity()	{ return m_Velocity; }
	Friction getFriction() { return m_TotalFriction; }

	void setForce( const Force &f ) { m_TotalForce = f; }
	void setVelocity( const Velocity &v ) { m_Velocity = v; }
	void setFriction( const Friction &f ) { m_TotalFriction = f; }

	Weight getWeight() { return m_Weight; }

};



#endif /*__BASE_PHYSICS_H__*/
