#include "doomtype.h"
#include "doomstat.h"
#include "d_player.h"
#include "g_game.h"
#include "d_net.h"
#include "p_local.h"
#include "gi.h"
#include "i_system.h"
#include "c_dispatch.h"
#include "st_stuff.h"
#include "m_argv.h"
#include "p_effect.h"
#include "c_console.h"
#include "cl_main.h"

void P_MovePlayer (player_t *player);
void P_CalcHeight (player_t *player);
void P_DeathThink (player_t *player);


angle_t cl_angle[MAXSAVETICS];
fixed_t cl_viewheight[MAXSAVETICS];
fixed_t cl_deltaviewheight[MAXSAVETICS];
fixed_t cl_jumpTics[MAXSAVETICS];
int     reactiontime[MAXSAVETICS];

bool predicting;

//
// CL_PredicMove
//
void CL_PredictMove (void)
{
	player_t *p = &players[consoleplayer];
	int       tic;
	fixed_t   pitch;

	if (!p->tic)
		return;

	// Save player angle, viewheight,deltaviewheight and jumpTics.
	// Will use it later to predict movements
	cl_angle[gametic%MAXSAVETICS] = p->mo->angle;
	cl_viewheight[gametic%MAXSAVETICS] = p->viewheight;
	cl_deltaviewheight[gametic%MAXSAVETICS] = p->deltaviewheight;
	cl_jumpTics[gametic%MAXSAVETICS] = p->jumpTics;
	reactiontime[gametic%MAXSAVETICS] = p->mo->reactiontime;
	pitch = p->mo->pitch;

	if (noservermsgs)
		return;
	
	// set the position
	CL_MoveThing (p->mo, p->real_origin[0], 
		          p->real_origin[1], p->real_origin[2]);
	
	// set the velocity
	p->mo->momx = p->real_velocity[0];
	p->mo->momy = p->real_velocity[1];
	p->mo->momz = p->real_velocity[2];
	
	tic = p->tic + 1;
	
	if (p->playerstate == PST_DEAD)
	{
		// predict forward until tic <= gametic
		while (tic < gametic)
		{
			predicting = true; // disable bobbing, sounds
			p->mo->RunThink();				
			tic++;
		}

		// [BC] To properly tic players
		oldgametic = gametic;

		predicting = false;
		P_DeathThink (p);
		p->mo->RunThink();

		return;
	}

	p->mo->angle = cl_angle[tic%MAXSAVETICS];
	p->viewheight = cl_viewheight[tic%MAXSAVETICS];
	p->deltaviewheight = cl_deltaviewheight[tic%MAXSAVETICS];
	p->jumpTics = cl_jumpTics[tic%MAXSAVETICS];
	p->mo->reactiontime = reactiontime[tic%MAXSAVETICS];
	
	// predict forward until tic <= gametic
	while (tic <= gametic)
	{
		int buf = tic%MAXSAVETICS;
		ticcmd_t *cmd = &players[consoleplayer].cmd;
		memcpy (cmd, &localcmds[buf], sizeof(ticcmd_t));

		if (tic < gametic)
		{
			predicting = true; // disable bobbing, sounds
			P_MovePlayer(p);
			P_CalcHeight(p);
			p->mo->RunThink();			
		}

		tic++;
	}
	

	if (!p->mo->reactiontime)
		p->mo->angle = cl_angle[gametic%MAXSAVETICS];
	p->mo->pitch = pitch;
	predicting = false; // allow bobbing, sounds

	// [BC] To properly tic players
	oldgametic = gametic;

	P_MovePlayer(p);
	P_CalcHeight(p);
	P_PlayerThink (p);
	p->mo->RunThink();
}