////////////////////////////////////////////////////////////////////////////
//	Module 		: patrol_point.cpp
//	Created 	: 15.06.2004
//  Modified 	: 15.06.2004
//	Author		: Dmitriy Iassenev
//	Description : Patrol point
////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "patrol_point.h"
#include "level_graph.h"
#include "level_graph.h"
#include "game_level_cross_table.h"
#include "game_graph.h"
#include "object_broker.h"

#ifdef XRGAME_EXPORTS
#	include "ai_space.h"
#endif

#ifdef DEBUG
#	include "patrol_path.h"
#endif

CPatrolPoint::CPatrolPoint									(const CPatrolPath *path)
{
#ifdef DEBUG
	m_path				= path;
	m_initialized		= false;
#endif
}

#ifdef DEBUG
void CPatrolPoint::verify_vertex_id							(const CLevelGraph *level_graph, const CGameLevelCrossTable *cross, const CGameGraph *game_graph) const
{
	if (!level_graph)
		return;

	if (level_graph->valid_vertex_id(m_level_vertex_id)) {
		return;
	}

	VERIFY			(m_path);
	string1024		temp;
	xr_sprintf			(temp,"\n! Patrol point %s in path %s is not on the level graph vertex!",*m_name,*m_path->m_name);
	THROW2			(level_graph->valid_vertex_id(m_level_vertex_id),temp);
}
#endif

IC	void CPatrolPoint::correct_position						(const CLevelGraph *level_graph, const CGameLevelCrossTable *cross, const CGameGraph *game_graph)
{
	if (!level_graph || !level_graph->valid_vertex_position(position()) || !level_graph->valid_vertex_id(m_level_vertex_id))
		return;

	if (!level_graph->inside(level_vertex_id(level_graph,cross,game_graph),position()))
		m_position		= level_graph->vertex_position(level_vertex_id(level_graph,cross,game_graph));

	m_game_vertex_id	= cross->vertex(level_vertex_id(level_graph,cross,game_graph)).game_vertex_id();
}

CPatrolPoint::CPatrolPoint									(const CLevelGraph *level_graph, const CGameLevelCrossTable *cross, const CGameGraph *game_graph, const CPatrolPath *path, const Fvector &position, u32 level_vertex_id, u32 flags, shared_str name)
{
#ifdef DEBUG
	VERIFY				(path);
	m_path				= path;
#endif
	m_position			= position;
	m_level_vertex_id	= level_vertex_id;
	m_flags				= flags;
	m_name				= name;
#ifdef DEBUG
	m_initialized		= true;
#endif
	correct_position	(level_graph,cross,game_graph);
}

CPatrolPoint &CPatrolPoint::load_raw						(const CLevelGraph *level_graph, const CGameLevelCrossTable *cross, const CGameGraph *game_graph, IReader &stream)
{
	stream.r_fvector3	(m_position);
	m_flags				= stream.r_u32();
	stream.r_stringZ	(m_name);
	if (level_graph && level_graph->valid_vertex_position(m_position)) {
		Fvector				position = m_position;
		position.y			+= .15f;
		m_level_vertex_id	= level_graph->vertex_id(position);
	}
	else
		m_level_vertex_id	= u32(-1);
#ifdef DEBUG
	m_initialized		= true;
#endif
	correct_position	(level_graph,cross,game_graph);
	return				(*this);
}

void CPatrolPoint::load										(IReader &stream)
{
	load_data			(m_name,stream);
	load_data			(m_position,stream);
	load_data			(m_flags,stream);
	load_data			(m_level_vertex_id,stream);
	load_data			(m_game_vertex_id,stream);

#ifdef DEBUG
	m_initialized		= true;
#endif
}

void CPatrolPoint::save										(IWriter &stream)
{
	save_data			(m_name,stream);
	save_data			(m_position,stream);
	save_data			(m_flags,stream);
	save_data			(m_level_vertex_id,stream);
	save_data			(m_game_vertex_id,stream);
}

#ifdef XRGAME_EXPORTS
const u32 &CPatrolPoint::level_vertex_id					() const
{
	if (ai().game_graph().vertex(m_game_vertex_id)->level_id() == ai().level_graph().level_id())
		return			(level_vertex_id(&ai().level_graph(),&ai().cross_table(),&ai().game_graph()));

	return				(m_level_vertex_id);
}

const GameGraph::_GRAPH_ID &CPatrolPoint::game_vertex_id	() const
{
	CGameGraph::CVertex const*	vertex = ai().game_graph().vertex(m_game_vertex_id);
	VERIFY2				(
		vertex,
		make_string(
			"invalid game vertex id[%d] (level_vertex_id[%d]) for patrol point[%s] in path[%s] in position[%f][%f][%f]",
			m_game_vertex_id,
			m_level_vertex_id,
			m_name.c_str(),
			m_path->m_name.c_str(),
			VPUSH(m_position)
		)
	);

	if (vertex->level_id() == ai().level_graph().level_id())
		return			(game_vertex_id(&ai().level_graph(),&ai().cross_table(),&ai().game_graph()));

	return				(m_game_vertex_id);
}
#endif
