#include "MW4Headers.hpp"
#include "hudcomp.hpp"
#include "HUDMap.hpp"
#include "sensor.hpp"
#include "vehicle.hpp"
#include "mwmission.hpp"
#include <adept\map.hpp>
#include "mwapplication.hpp"
// MSL 5.02 Nav Points
#include "navpoint.hpp"
//sanghoon begin
#include <windows.h>
#include <ddraw.h>
#include <d3d.h>

#include <GameOS\render.hpp>
extern char AssetsDirectory1[MAX_PATH];
//sanghoon end

const Stuff::Time SHOT_TIME = 2.0;

namespace MW4AI
{
		extern Stuff::Scalar MinZ, MaxZ, MinX, MaxX;
}

using namespace MechWarrior4;
using namespace MW4AI;

HUDMap::HUDMap():
	vehiclePtr(NULL),
	m_CurrentTarget (NULL)
{
	const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();

	if (model->m_HudMap[0] == 0)
		AddTexture ("hud\\map",0,28,28,228,228);
    else{
		AddTexture (model->m_HudMap,0,0,0,255,255);
		//sanghoon begin
		radar_device.MapDrawn=false;
		/*
		if(hsh_initialized){
			char temp[256];
			sprintf(temp, "%s\\hsh\\", AssetsDirectory1);
			lstrcat(temp,model->m_HudMap);
			lstrcat(temp,".bmp");
			DrawBitmapToSurface(radar_device.pDDSBackground,140,407,temp);
			radar_device.MapDrawn=true;
		}
		*/
		//sanghoon end
	}

	Location (Point3D (301,399,0.9f));
	Size (Point3D (200,200,0.9f));
	m_Textures[0]->AlphaMode (gos_Alpha_OneZero);
//	AddTexture ("hud\\hud256",10,125,0,245,119);
	AddTexture ("hud\\hud4",11,245,192,250,198);		// current target
	AddTexture ("hud\\hud4",12,245,198,249,202);		// enemy
	AddTexture ("hud\\hud4",13,245,202,252,209);		// shot
	AddTexture ("hud\\hud4",14,245,209,248,213);		// friendly
	AddTexture ("hud\\hud4",15,245,213,248,216);		// neutral
	AddTexture ("hud\\hud4",16,4,101,59,160);		// torso sweep
// MSL 5.00
//	AddTexture ("hud\\hud4",20,245,216,250,222);		// nav a
//	AddTexture ("hud\\hud4",21,245,222,250,228);
//	AddTexture ("hud\\hud4",22,245,228,250,234);
//	AddTexture ("hud\\hud4",23,245,240,250,246);
//	AddTexture ("hud\\hud4",24,250,216,255,222);
//	AddTexture ("hud\\hud4",25,250,222,255,228);
//	AddTexture ("hud\\hud4",26,250,228,255,234);
//	AddTexture ("hud\\hud4",27,250,240,255,246);
//	Point3D size;
//	int i;
//	for (i=20;i<=27;i++)
	AddTexture ("hud\\hud4",20,245,216,250,222);		// nav a
	AddTexture ("hud\\hud4",21,245,222,250,228);
	AddTexture ("hud\\hud4",22,245,228,250,234);
//	AddTexture ("hud\\hud4",23,245,240,250,246);
	AddTexture ("hud\\hud4",23,250,216,255,222);
	AddTexture ("hud\\hud4",24,250,222,255,228);
	AddTexture ("hud\\hud4",25,250,228,255,234);
//	AddTexture ("hud\\hud4",27,250,240,255,246);
	Point3D size;
	int i;
	for (i=20;i<=25;i++)
	{
		size = m_Textures[i]->Size ();
		m_Textures[i]->Origin (size.x,0);
	}

//	Size (m_Textures[0]->Size ());

	size = m_Textures[11]->Size ();
	m_Textures[11]->Origin (size.x/2.0f,size.y/2.0f);

	size = m_Textures[12]->Size ();
	m_Textures[12]->Origin (size.x/2.0f,size.y/2.0f);

	size = m_Textures[13]->Size ();
	m_Textures[13]->Origin (size.x/2.0f,size.y/2.0f);

	size = m_Textures[14]->Size ();
	m_Textures[14]->Origin (size.x/2.0f,size.y/2.0f);

	size = m_Textures[15]->Size ();
	m_Textures[15]->Origin (size.x/2.0f,size.y/2.0f);

	Color (MakeColor (255,255,255,150));
}

HUDMap::~HUDMap()
{
}


void HUDMap::SetVehicle(Vehicle *vehicle)
{
	inherited::SetVehicle (vehicle);

	Sensor *sensor;
	if (m_Vehicle.GetCurrent ())
		sensor = m_Vehicle.GetCurrent ()->GetSensor();
	else
		sensor = NULL;
}

void HUDMap::ConvertMapCoords (float& x,float& y)
{
	y = 399 + 599 - y;
	x = 301 + 501 - x;
}

void HUDMap::ConvertMapCoords (Point3D& pt)
{
	pt.y = 399 + 599 - pt.y;
	pt.x = 301 + 501 - pt.x;
}

void HUDMap::Reset (void)
{
	MWApplication *m_App;
	m_App = MWApplication::GetInstance ();
	m_RadarMode = m_App->GetLocalNetParams()->m_radarMode;
	bool networking = MWApplication::GetInstance()->networkingFlag;
	if (!networking)
		m_RadarMode = 0;
}


void HUDMap::DrawImplementation(void)
{
	Point3D loc,size;
	int i;

	//Draw the map.
	Vehicle *vehicle = m_Vehicle.GetCurrent();

	loc = Location ();
	size = Size ();
//	loc.x -= (size.x/2.0f);
//	loc.y -= (size.y/2.0f);
	m_Textures[0]->Draw (loc,size,MakeColor (255,255,255,255),HUDTexture::NO_FLIP,true);
	
	//Display Torso Sweep (pie-shaped field-of-view indicator).
	if (NULL == vehicle)
		return;
	
	if (NULL == vehicle->GetSensor())
		return;
	
	if (NULL == vehicle->GetTorso())
		return;

	Scalar multx,multz;
	DWORD color;

	multx = MW4AI::MaxX - MW4AI::MinX;
	multz = MW4AI::MaxZ - MW4AI::MinZ;
	multx = size.x / multx;
	multz = size.y / multz;
	Check_Pointer(vehicle);
	Check_Pointer(vehicle->GetSensor());
	loc.x += size.x/2.0f;
	loc.y += size.y/2.0f;

	Stuff::Point3D object_display_pos;
	
	UnitQuaternion quat;
	quat = vehicle->GetLocalToWorld ();
	UnitVector3D vec;
	vehicle->GetLocalToWorld ().GetLocalForwardInWorld (&vec);
	YawPitchRange ypr (vec);
	ypr.yaw -= Pi;

	object_display_pos=vehicle->GetLocalToWorld();
	object_display_pos.y = object_display_pos.z;

	object_display_pos.x *= multx;
	object_display_pos.x += loc.x;
	object_display_pos.y *= multz;
	object_display_pos.y += loc.y;
	ConvertMapCoords (object_display_pos);

	color = MakeColor (0,255,0,150);
	size = m_Textures[16]->Size ();
	m_Textures[16]->Clip (true);
	m_Textures[16]->Origin (29,59);
	m_Textures[16]->Rotate (Pi - ypr.yaw-m_TorsoTwist);
	m_Textures[16]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);

	my_DrawRect ((int) (object_display_pos.x-1),(int) (object_display_pos.y-1),(int) (object_display_pos.x+2),(int) (object_display_pos.y+2),MakeColor (0,0,255,255));


	//Draw Radar Blips
	//Display radar objects.

	MWObject *current_object;
	for(i=0;i<vehicle->GetSensor()->numberOfContacts;i++)
	{
		current_object=vehicle->GetSensor()->GetSensorData()[i]->object.GetCurrent();
		if (current_object != NULL)
		{
			bool draw_contact = true;

			if (current_object->GetAI()==NULL)
				draw_contact = false;

			if (current_object->IsPlayerVehicle())
				draw_contact = true;

			if (current_object->IsDestroyed())
				draw_contact = false;

			int rel_align = vehicle->GetRelativeAlignment(current_object->GetAlignment());
			if ((rel_align == Entity::DefaultAlignment) || (rel_align == Entity::Enemy))
			{
				if ((m_RadarMode != 0) && (m_RadarMode != 3))
					draw_contact = false;
			}
			
			if (m_RadarMode == 2)
				draw_contact = false;

			if(draw_contact)
			{
				object_display_pos=current_object->GetLocalToWorld();
				object_display_pos.y = object_display_pos.z;
				
				object_display_pos.x *= multx;
				object_display_pos.x += loc.x;
				object_display_pos.y *= multz;
				object_display_pos.y += loc.y;
				ConvertMapCoords (object_display_pos);

				{
					switch (vehicle->GetRelativeAlignment(current_object->GetAlignment()))
					{
						case Entity::DefaultAlignment:
						{
							size = m_Textures[14]->Size ();
							color = MakeColor (0,255,0,250);
							m_Textures[14]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							break;
						}
						case Entity::Enemy:
						{
							size = m_Textures[12]->Size ();
							color = MakeColor (255,255,0,250);
							m_Textures[12]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							break;
						}
						default:
						{
							size = m_Textures[15]->Size ();
							color = MakeColor (0,0,255,250);
							m_Textures[15]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							break;
						}
					}

					if (current_object == m_CurrentTarget.GetCurrent ())
					{
						size = m_Textures[11]->Size ();
						color = MakeColor (0,255,0,250);
						m_Textures[11]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
					}
					else if (OnShotList (current_object->objectID))
					{
						size = m_Textures[13]->Size ();
						color = MakeColor (0,255,0,250);
						m_Textures[13]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
					}
				}
			}
		}
	}
// Plot Nav Points on Map
// MSL 5.02 Nav Points
	int j;
	ChainIteratorOf<NavPoint *> iter (NavPoint::s_RevealedNavPoints);
	NavPoint *nav;
	j = 0;
	while ((nav = iter.ReadAndNext ()) != NULL)
	{
		int id;
		if (j == 6)
			break;
		if (!nav->IsVisible ())
			continue;
		id = j;
		if (nav->m_RadarID != -1)
		{
			id = nav->m_RadarID-1;
			Verify (id >=0);
			Verify (id<6);
		}
		else
		{
			j++;
		}
		object_display_pos=nav->GetLocalToWorld();
		object_display_pos.y=object_display_pos.z;
		object_display_pos.x *= multx;
		object_display_pos.x += loc.x;
		object_display_pos.y *= multz;
		object_display_pos.y += loc.y;
		ConvertMapCoords (object_display_pos);
		
		size = m_Textures[id+20]->Size ();
		color = MakeColor (255,255,255,250);
		m_Textures[id+20]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
	}
	//Operation boundary display polygon (orange-red)
	size = Size ();
	loc = Location ();
	Mission *miss;
	int numpts;
	miss = Mission::GetInstance ();
	Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > ptlist;
//	miss->GetWarningPolygon (ptlist);
	miss->GetMissionPolygon (ptlist);
	numpts = ptlist.GetLength ();

	for (i=0;i<numpts;i++)
	{
		Scalar x1,y1,x2,y2;
		x1 = ptlist[i][0];
		y1 = ptlist[i][1];
		if (i==(numpts-1))
		{
			x2 = ptlist[0][0];
			y2 = ptlist[0][1];
		}
		else
		{
			x2 = ptlist[i+1][0];
			y2 = ptlist[i+1][1];
		}
		x1 *= 1280.0f;
		x2 *= 1280.0f;
		y1 *= 1280.0f;
		y2 *= 1280.0f;

		x1 *= multx;
		x1 += loc.x;
		y1 *= multz;
		y1 += loc.y;

		x2 *= multx;
		x2 += loc.x;
		y2 *= multz;
		y2 += loc.y;
		
		ConvertMapCoords (x1,y1);
		ConvertMapCoords (x2,y2);
		DrawLine ((int) x1,(int) y1,(int) x2,(int) y2,MakeColor (255,0,0,255));
	}
	miss->GetWarningPolygon (ptlist);
	numpts = ptlist.GetLength ();
	for (i=0;i<numpts;i++)
	{
		Scalar x1,y1,x2,y2;
		x1 = ptlist[i][0];
		y1 = ptlist[i][1];
		if (i==(numpts-1))
		{
			x2 = ptlist[0][0];
			y2 = ptlist[0][1];
		}
		else
		{
			x2 = ptlist[i+1][0];
			y2 = ptlist[i+1][1];
		}
		x1 *= 1280.0f;
		x2 *= 1280.0f;
		y1 *= 1280.0f;
		y2 *= 1280.0f;

		x1 *= multx;
		x1 += loc.x;
		y1 *= multz;
		y1 += loc.y;

		x2 *= multx;
		x2 += loc.x;
		y2 *= multz;
		y2 += loc.y;

		ConvertMapCoords (x1,y1);
		ConvertMapCoords (x2,y2);
		DrawLine ((int) x1,(int) y1,(int) x2,(int) y2,MakeColor (255,128,0,255));
	}
}

void HUDMap::Update(Stuff::Time till)
{
	stlport::vector<ShotEntry>::iterator iter;
	iter = m_ShotList.begin ();
	while (iter != m_ShotList.end ())
	{
		if ((iter->timeadded+SHOT_TIME) < till)
			iter = m_ShotList.erase (iter);
		else
			iter++;
	}

	inherited::Update (till);
}

bool HUDMap::OnShotList (ObjectID who)
{
	stlport::vector<ShotEntry>::iterator iter;
	
	for (iter = m_ShotList.begin ();iter != m_ShotList.end ();iter++)
	{
		if (iter->entity == who)
			return true;
	}

	return false;
}

void HUDMap::AddShot (ObjectID who)
{
	m_ShotList.push_back (ShotEntry (who,gos_GetElapsedTime ()));
}

