#include "MW4Headers.hpp"

#include "vehicleinterface.hpp"
#include "GUIRadarManager.hpp"
#include "MWGUIManager.hpp"
#include "Vehicle.hpp"
#include "Torso.hpp"
#include "MWMission.hpp"
#include "MWPlayer.hpp"
#include <Adept\Map.hpp>
#include "navpoint.hpp"

#include "mwapplication.hpp"
#include "..\missionlang\resource.h"
#include "hudscore.hpp"

#include <MLR\MLR.hpp>
#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRTexture.hpp>

#include "MWObject.hpp"
//sanghoon begin
#include <windows.h>
#include <ddraw.h>
#include <d3d.h>

#include <GameOS\render.hpp>
#define RADAR_SCALE	2.8f
//sanghoon end

int m_gCool; // hyun: coolant

namespace MW4AI
{
		extern Stuff::Scalar MinZ, MaxZ, MinX, MaxX;
}
const Stuff::Time SHOT_TIME = 2.0;

#ifdef LAB_ONLY
	#include "AI_Log.hpp"
#endif

using namespace MidLevelRenderer;

//#######################################################################
//###########################    GUIRadarManager   #####################
//#######################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//


GUIRadarManager::GUIRadarManager() :
	m_CurrentTarget (NULL)
{
	m_RotateTime = 0;
	zrot = 0;
	radarRange=800.0f;
	m_TorsoTwist = 0;
	m_RangeText = new HUDText ();
	m_RangeText->Justification (HUDText::LEFT_ALIGN);

	Location (Stuff::Point3D(336,451,0.9f));
	
	AddTexture ("hud\\hud4",0,236,246,245,256);			// active A

	AddTexture ("hud\\hud4",10,107,131,232,256); 			// main background
	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

	AddTexture ("hud\\hud4",20,245,216,250,222);		// nav a
	AddTexture ("hud\\hud4",21,245,222,250,228);    // nav b
	AddTexture ("hud\\hud4",22,245,228,250,234);    // nav c
//	AddTexture ("hud\\hud4",23,245,234,250,240);    // nav d

	AddTexture ("hud\\hud4",23,250,216,255,222);    // nav d
	AddTexture ("hud\\hud4",24,250,222,255,228);    // nav e
	AddTexture ("hud\\hud4",25,250,228,255,234);    // nav f
//	AddTexture ("hud\\hud4",27,250,234,255,240);    // nav h

	Point3D size;
	int i;
	for (i=20;i<=25;i++)
	{
		size = m_Textures[i]->Size ();
		m_Textures[i]->Origin (0,size.y);
	}

	Size (m_Textures[10]->Size ());

	size = m_Textures[10]->Size ();
	m_Textures[10]->Origin (61.0f,61.0f);

	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);
	
	size = m_Textures[16]->Size ();
	m_Textures[16]->Origin (29,59);

	Color (MakeColor (0,175,0,150));


}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

//sanghoon
extern bool sh_game_started;

GUIRadarManager::~GUIRadarManager()
{
	//sanghoon begin
	sh_game_started=false;
	//sanghoon end
	delete m_RangeText;

}

void DrawMapBoundary()
{
	//Extracted from DrawImplementation..
	//Drawn only once after mission start (operation area on map does not change..)
	Scalar multx,multz;

	multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
	multz = 200.0f/(MW4AI::MaxZ - MW4AI::MinZ);

	Mission *miss=Mission::GetInstance ();
	Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > ptlist;
	miss->GetMissionPolygon (ptlist);
	int numpts = ptlist.GetLength ();

	HDC hdcBackImage;
	radar_device.pDDSBackground->GetDC( &hdcBackImage);//Image for back buffer preparation..
	HPEN hpenold=(HPEN)SelectObject(hdcBackImage,CreatePen(PS_SOLID,1,RGB(255,0,0)));
	
	for (int i=0;i<numpts;i++){
		Scalar x1,y1,x2,y2;
		x1 = ptlist[i][0]* 1280.0f * multx;
		y1 = ptlist[i][1]* 1280.0f * multz;

		x2 = ptlist[(i+1)%numpts][0]* 1280.0f * multx;
		y2 = ptlist[(i+1)%numpts][1]* 1280.0f * multz;

		MoveToEx(hdcBackImage,(int)(340-x1),(int)(606-y1),NULL);
		LineTo(hdcBackImage,(int)(340-x2),(int)(606-y2));
	}

	DeleteObject(SelectObject(hdcBackImage,CreatePen(PS_SOLID,1,RGB(255,128,0))));
	miss->GetWarningPolygon (ptlist);
	numpts = ptlist.GetLength ();

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

		x2 = ptlist[(i+1)%numpts][0]* 1280.0f * multx;
		y2 = ptlist[(i+1)%numpts][1]* 1280.0f * multz;

		MoveToEx(hdcBackImage,(int)(340-x1),(int)(606-y1),NULL);
		LineTo(hdcBackImage,(int)(340-x2),(int)(606-y2));
	}
	DeleteObject(SelectObject(hdcBackImage,hpenold));
	radar_device.pDDSBackground->ReleaseDC( hdcBackImage);
}

void GUIRadarManager::Reset (void)
{
	//sanghoon

	MWApplication *m_App;
	m_App = MWApplication::GetInstance ();
	m_RadarMode = m_App->GetLocalNetParams()->m_radarMode;
	bool networking = MWApplication::GetInstance()->networkingFlag;
	if (!networking)
		m_RadarMode = 0;
	//sanghoon
	if(hsh_initialized)
		DrawMapBoundary();
}

//sanghoon begin
/*
char * radar_text[]={
	"JUMP\nJET","SHUT\nDOWN","OVER\nRIDE","FLUSH","CROUCH","",
		"RANGE","RADAR\nMODE","LIGHT\nAMP","SEARCH\nLIGHT","AUTO\nCENTER"
};
*/
//sanghoon end

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
const sh_radar_len=152;
bool IsRadarRange(int posx,int posy)
{
	//int posx=(int)(RADAR_SCALE*(object_display_pos.x-display_center.x))+240-6;
	//int posy=(int)(RADAR_SCALE*(object_display_pos.y-display_center.y))+185-6;
	posx-=240;
	posy-=185;
	return ((posx*posx+posy*posy)<(sh_radar_len*sh_radar_len));
}
void GUIRadarManager::DrawImplementation(void)
{
if(!hsh_initialized){
	Check_Object(this);
	int i;
	
	Vehicle *vehicle = m_Vehicle.GetCurrent();

	if (NULL == vehicle)
		return;
	
	if (NULL == vehicle->GetSensor())
		return;
	
	if (NULL == vehicle->GetTorso())
		return;
	

	#ifdef LAB_ONLY
	if ((MWMission::GetInstance() != 0) &&
		(MW4AI::DiagnosticsInterface::GetInstance().GetEnabled() == true))
	{
		return;
	}
	#endif
	
	Check_Pointer(vehicle);
	Check_Pointer(vehicle->GetSensor());
/*
	//sanghoon begin: map
	Scalar multx,multz;

	multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
	multz = 200.0f/(MW4AI::MaxZ - MW4AI::MinZ);
*/	
	
	radarx = 401;
	radary = 526;
	radarw = 106;
	radarh = 106;

	DWORD color = MakeColor (255,255,255,128);
	Point3D size;
	size = m_Textures[10]->Size ();
	m_Textures[10]->BlendMode (gos_BlendModulate);
	m_Textures[10]->AlphaMode (gos_Alpha_AlphaInvAlpha);
	m_Textures[10]->Draw (Point3D ((Scalar) radarx,(Scalar) radary,0.9f),size,color,HUDTexture::NO_FLIP,true);
	Location (Point3D (radarx-(59.0f),radary-(60.0f),0.9f));
	Point3D loc;
	loc = Location ();

	Stuff::Point3D display_center((Scalar) radarx,(Scalar) radary,0.9f);
	Stuff::LinearMatrix4D vehicle_to_world,world_to_vehicle;
	Stuff::LinearMatrix4D object_to_world,object_to_vehicle;
	Stuff::Point3D object_display_pos;
	Point3D vehicle_uvpoint,world_uvpoint,tmp_point;
	
	vehicle_to_world=vehicle->GetLocalToWorld();	
	world_to_vehicle.Invert(vehicle_to_world);


	// draw mission bounds

	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 += MW4AI::MinX;
		x2 += MW4AI::MinX;
		y1 += MW4AI::MinZ;
		y2 += MW4AI::MinZ;

		Point3D pt1,pt2;
		pt1.x = x1;
		pt1.y = 0;
		pt1.z = y1;

		pt2.x = x2;
		pt2.y = 0;
		pt2.z = y2;

		object_display_pos.Multiply(pt1,world_to_vehicle);

		x1=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
		y1=(-object_display_pos.z*(radarh/(radarRange*2.0f)));
		
		object_display_pos.Multiply(pt2,world_to_vehicle);

		x2=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
		y2=(-object_display_pos.z*(radarh/(radarRange*2.0f)));

		ClipLine (x1,y1,x2,y2,0,0,57.0f);
		if (x1 != -1.0f)
		{
			x1 += display_center.x;
			y1 += display_center.y;
			x2 += display_center.x;
			y2 += display_center.y;
			DrawLine ((int) x1,(int) y1,(int) x2,(int) y2,MakeColor (255,0,0,255));
		}
	}
	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 += MW4AI::MinX;
		x2 += MW4AI::MinX;
		y1 += MW4AI::MinZ;
		y2 += MW4AI::MinZ;

		Point3D pt1,pt2;
		pt1.x = x1;
		pt1.y = 0;
		pt1.z = y1;

		pt2.x = x2;
		pt2.y = 0;
		pt2.z = y2;

		object_display_pos.Multiply(pt1,world_to_vehicle);

		x1=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
		y1=(-object_display_pos.z*(radarh/(radarRange*2.0f)));
		
		object_display_pos.Multiply(pt2,world_to_vehicle);

		x2=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
		y2=(-object_display_pos.z*(radarh/(radarRange*2.0f)));

		ClipLine (x1,y1,x2,y2,0,0,57.0f);
		if (x1 != -1.0f)
		{
			x1 += display_center.x;
			y1 += display_center.y;
			x2 += display_center.x;
			y2 += display_center.y;
			DrawLine ((int) x1,(int) y1,(int) x2,(int) y2,MakeColor (255,128,0,255));
		}
	}


	color = MakeColor (0,175,0,150);
	size = m_Textures[16]->Size ();
	m_Textures[16]->Rotate (-m_TorsoTwist);
	m_Textures[16]->Draw (Point3D ((Scalar) radarx,(Scalar) radary,0.9f),size,color,HUDTexture::NO_FLIP,true);

	m_RangeText->Color (MakeColor (255,255,255,255));
	char text[10];
    if (radarRange != radarRangeOrg)
        sprintf (text,"NoLmt");
    else
	    sprintf (text,"%4.0f",radarRange);
	m_RangeText->UpdateText (text);
	m_RangeText->Draw (Point3D (loc.x+220-130,loc.y+108,0.9f));
	if (vehicle->GetSensor ()->GetSensorMode () == Sensor::ActiveMode)
	{
		Point3D size;
		size = m_Textures[0]->Size ();
		DWORD color = MakeColor (255,255,255,255);
		m_Textures[0]->Draw (Point3D (loc.x+236-125,loc.y+93,0.9f),size,color);
	}
	MWObject *current_object;
	for(i=0;i<vehicle->GetSensor()->numberOfBuildingContacts;i++)
	{
		current_object=vehicle->GetSensor()->GetBuildingData()[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) && (m_RadarMode != 3))
				draw_contact = false;
			Point3D fredpt(current_object->GetLocalToWorld ());
			if (fredpt.y < -1000)
				draw_contact = false;

			if(draw_contact)
			{
				object_to_world=current_object->GetLocalToWorld();
				object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
				object_display_pos=object_to_vehicle;
				
				object_display_pos.x=(-object_display_pos.x*(radarw/(radarRange*2.0f)))+display_center.x;
				object_display_pos.y=(-object_display_pos.z*(radarh/(radarRange*2.0f)))+display_center.y;

				if(object_display_pos.x>(m_Location.x+8) && object_display_pos.y>(m_Location.y+8) &&
					object_display_pos.x<(m_Location.x+m_Size.x-16) &&
					object_display_pos.y<(m_Location.y+m_Size.y-16) )
				{
					switch (vehicle->GetRelativeAlignment(current_object->GetAlignment()))
					{
						case Entity::DefaultAlignment:
						{
							size = m_Textures[14]->Size ();
							color = MakeColor (0,255,0,255);
							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,0,0,255);
							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,255);
							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,255);
						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,255);
						m_Textures[13]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
					}
				}
			}
		}
	}
	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) &&
				(MWApplication::GetInstance()->networkingFlag == false))
				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_to_world=current_object->GetLocalToWorld();
				object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
				object_display_pos=object_to_vehicle;
				
				object_display_pos.x=(-object_display_pos.x*(radarw/(radarRange*2.0f)))+display_center.x;
				object_display_pos.y=(-object_display_pos.z*(radarh/(radarRange*2.0f)))+display_center.y;

				if(object_display_pos.x>(m_Location.x+8) && object_display_pos.y>(m_Location.y+8) &&
					object_display_pos.x<(m_Location.x+m_Size.x-16) &&
					object_display_pos.y<(m_Location.y+m_Size.y-16) )
				{
					switch (vehicle->GetRelativeAlignment(current_object->GetAlignment()))
					{
						case Entity::DefaultAlignment:
						{
							size = m_Textures[14]->Size ();
							color = MakeColor (0,255,0,255);
							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:
						{
// MSL 5.02 SubSystems
							if ((current_object->GetIFF_Jammer()) && (current_object->GetDistanceFrom (vehicle) > 200))
							{
								size = m_Textures[14]->Size ();
								color = MakeColor (0,255,0,255);
								m_Textures[14]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							}
							else
							{
								size = m_Textures[12]->Size ();
								color = MakeColor (255,0,0,255);
								m_Textures[12]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							}
							break;
						}
						default:
						{
// MSL 5.02 SubSystems
							if ((current_object->GetIFF_Jammer()) && (current_object->GetDistanceFrom (vehicle) > 200))
							{
								size = m_Textures[14]->Size ();
								color = MakeColor (0,255,0,255);
								m_Textures[14]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
							}
							else
							{
								size = m_Textures[15]->Size ();
								color = MakeColor (0,0,255,255);
								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,255);
						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,255);
						m_Textures[13]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
					}
				}
			}
		}
	}

	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_to_world=nav->GetLocalToWorld();
		object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
		object_display_pos=object_to_vehicle;

		object_display_pos.x=(-object_display_pos.x*(radarw/(radarRange*2.0f)))+display_center.x;
		object_display_pos.y=(-object_display_pos.z*(radarh/(radarRange*2.0f)))+display_center.y;
		
		if(object_display_pos.x>(m_Location.x+8) && object_display_pos.y>(m_Location.y+16) &&
			object_display_pos.x<(m_Location.x+m_Size.x-24) &&
			object_display_pos.y<(m_Location.y+m_Size.y-8) )
		{
			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);
		}
	}
}else if(sh_step==0){
	Check_Object(this);
	int i;

	// Secondary Maps
	//Draw map and boundary. (Drawn once since it does not change during game.)

	if(!radar_device.MapDrawn){
		extern char AssetsDirectory1[MAX_PATH];
		const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
		char temp[256];
		sprintf(temp, "%s\\hsh\\", AssetsDirectory1);
        lstrcat(temp,model->m_HudMap);
		lstrcat(temp,".bmp");
		DrawBitmapToSurface(radar_device.pDDSBackground,140,407,temp);
		DrawMapBoundary();
		radar_device.MapDrawn=true;
	}
	
	radar_device.pD3DDevice->SetTexture(0,0);
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,	D3DBLEND_SRCALPHA );
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );

/*
	for(i=0;i<11;i++){
		int x=(i/6)*440+20;
		int y=(i%6)*105+56;
		if(i==10){
			DWORD color;
			if(MechWarrior4::VehicleInterface::perminateTorsoMode!=
				MechWarrior4::VehicleInterface::LeaveTorsoAlone){
				radar_device.DrawQuad(x-20,y-50,x+20,y+50,0XFFFFFFFF);
				color=0xFF000000;
			}else{
				color=0xFFFFFFFF;
			}
			radar_device.pFont[3].DrawTextVerticalOrg(x,y,color,radar_text[i]);
		}else{
			radar_device.pFont[3].DrawTextVerticalOrg(x,y,0xFFFFFFFF,radar_text[i]);
		}
	}
	radar_device.pFont[3].DrawTextMultiLine(460,530+40/2,0xFFFFFFFF,"Pilot\nMode",TEXTALIGN_ORG);
	radar_device.DrawQuad(440,570+1+g_nInputMode*20,480,590-1+g_nInputMode*20,0xFFFFFFFF);
	DWORD color;
	color=(g_nInputMode==0)?0xFF000000:0xFFFFFFFF;
	radar_device.pFont[3].DrawText(460,570+20/2,color,"BAS",TEXTALIGN_ORG);
	color=(g_nInputMode==1)?0xFF000000:0xFFFFFFFF;
	radar_device.pFont[3].DrawText(460,590+20/2,color,"MID",TEXTALIGN_ORG);
	color=(g_nInputMode==2)?0xFF000000:0xFFFFFFFF;
	radar_device.pFont[3].DrawText(460,610+20/2,color,"ADV",TEXTALIGN_ORG);

	radar_device.DrawFrame(440,530+1,480,570-1,0xFFFFFFFF);
	radar_device.DrawFrame(440,570+1,480,590-1,0xFFFFFFFF);
	radar_device.DrawFrame(440,590+1,480,610-1,0xFFFFFFFF);
	radar_device.DrawFrame(440,610+1,480,630-1,0xFFFFFFFF);
*/
	//setup state bits
    MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();
    if (p->GetGUIRadarStates(radar_device.recent_state) > 0) {
	    radar_device.DrawBackText(radar_device.recent_state);
	    radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
    }
	
	Vehicle *vehicle = m_Vehicle.GetCurrent();

	if (NULL == vehicle)return;
	if (NULL == vehicle->GetSensor())return;
	if (NULL == vehicle->GetTorso())return;
	
	Check_Pointer(vehicle);
	Check_Pointer(vehicle->GetSensor());

	
	///////////////////// MAP BEGIN //////////////////////
	/////Torso Sweep draw.. begin
	Scalar multx,multz;

	multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
	multz = 200.0f/(MW4AI::MaxZ - MW4AI::MinZ);
	{

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

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

		pos.x *= multx;
		pos.y *= multz;

		radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
		radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTFG_LINEAR);
		radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTFG_LINEAR);
		//HSH_RenderMapTorsoView(pos.x,pos.y,Pi - ypr.yaw-m_TorsoTwist);
		radar_device.DrawTextureRotate(85,195,143,253,143,253,-pos.x+240,-pos.y+508,Pi - ypr.yaw-m_TorsoTwist+3.1415926f/4.0f,0xC080C080);
		//HSH_DrawMapRectangle(pos.x-2,pos.y-1,pos.x+1,pos.y+2,0x001F);
		radar_device.pD3DDevice->SetTexture(0,0);
		radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTFG_POINT);
		radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTFG_POINT);
		radar_device.DrawQuad(-pos.x+240-1,-pos.y+508-1,-pos.x+240+2,-pos.y+508+2,0xFF0000C0);
	}

	/////Torso Sweep draw.. end

	//Draw objects on map.
	{
		radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
		MWObject *hsh_current_object;
		for(i=0;i<vehicle->GetSensor()->numberOfContacts;i++){
			hsh_current_object=vehicle->GetSensor()->GetSensorData()[i]->object.GetCurrent();
			if (hsh_current_object != NULL){
				bool draw_contact = true;//Flag: whether to draw this object..

// MSL 5.02 Bot on Map
				if (hsh_current_object->GetAI()==NULL && (MWApplication::GetInstance()->networkingFlag == false))draw_contact = false;
				if (hsh_current_object->IsPlayerVehicle())draw_contact = true;
				if (hsh_current_object->IsDestroyed())draw_contact = false;

				int rel_align = vehicle->GetRelativeAlignment(hsh_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){
					Stuff::Point3D map_object_display_pos;
					map_object_display_pos=hsh_current_object->GetLocalToWorld();
					map_object_display_pos.y = map_object_display_pos.z;
					map_object_display_pos.x *= multx;
					map_object_display_pos.y *= multz;
					int posx=-map_object_display_pos.x+240-3;
					int posy=-map_object_display_pos.y+508-3;
					switch (vehicle->GetRelativeAlignment(hsh_current_object->GetAlignment())){
					case Entity::DefaultAlignment:
						//HSH_DrawMapTexture (14-11,map_object_display_pos.x,map_object_display_pos.y);
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,24,12,24+8,19);
						break;
					case Entity::Enemy:
						//HSH_DrawMapTexture (12-11,map_object_display_pos.x,map_object_display_pos.y);
// MSL 5.02 SubSystems
						if ((hsh_current_object->GetIFF_Jammer()) && (hsh_current_object->GetDistanceFrom (vehicle) > 200))
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,24,12,24+8,19);
							}
							else
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,8,12,8+8,19);
							}
						break;
					default:
						//HSH_DrawMapTexture (15-11,map_object_display_pos.x,map_object_display_pos.y);
// MSL 5.02 SubSystems
						if ((hsh_current_object->GetIFF_Jammer()) && (hsh_current_object->GetDistanceFrom (vehicle) > 200))
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,24,12,24+8,19);
							}
							else
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,32,12,32+8,19);
							}
						break;
					}

					if (hsh_current_object == m_CurrentTarget.GetCurrent ()){
						//HSH_DrawMapTexture (11-11,map_object_display_pos.x,map_object_display_pos.y);
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,0,12,0+8,19);
					}else if (OnShotList (hsh_current_object->objectID)){
						//HSH_DrawMapTexture (13-11,map_object_display_pos.x,map_object_display_pos.y);
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,16,12,16+8,19);
					}
				}
			}
		}
	}

	///////////////////// MAP END //////////////////////
	

	///////////////////// RADAR BEGIN //////////////////////

	radar_device.pD3DDevice->SetTexture(0,0);

	radarx = 401;
	radary = 526;
	radarw = 106;
	radarh = 106;

	Stuff::Point3D display_center((Scalar) radarx,(Scalar) radary,0.9f);
	Stuff::LinearMatrix4D vehicle_to_world,world_to_vehicle;
	Stuff::LinearMatrix4D object_to_world,object_to_vehicle;
	Stuff::Point3D object_display_pos;
	Point3D vehicle_uvpoint,world_uvpoint,tmp_point;
	
	vehicle_to_world=vehicle->GetLocalToWorld();	
	world_to_vehicle.Invert(vehicle_to_world);


	// Draw boundary line..

	Mission *miss;
	miss = Mission::GetInstance ();
	Stuff::DynamicArrayOf<Stuff::Vector2DOf<Stuff::Scalar> > ptlist;

	for(int j=0;j<2;j++){
		DWORD color;
		if(j==0){
			miss->GetMissionPolygon (ptlist);
			color=0xFFFF0000;
		}else{
			miss->GetWarningPolygon (ptlist);
			color=0xFFFF8000;
		}
		int numpts = ptlist.GetLength ();

		for (i=0;i<numpts;i++){

			Scalar x1,y1,x2,y2;
			x1 = ptlist[i][0]* 1280.0f +MW4AI::MinX;
			y1 = ptlist[i][1]* 1280.0f +MW4AI::MinZ;

			x2 = ptlist[(i+1)%numpts][0]* 1280.0f +MW4AI::MinX;
			y2 = ptlist[(i+1)%numpts][1]* 1280.0f +MW4AI::MinZ;

			Point3D pt1=Point3D(x1,0,y1);
			Point3D pt2=Point3D(x2,0,y2);

			object_display_pos.Multiply(pt1,world_to_vehicle);
			x1=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
			y1=(-object_display_pos.z*(radarh/(radarRange*2.0f)));

			object_display_pos.Multiply(pt2,world_to_vehicle);
			x2=(-object_display_pos.x*(radarw/(radarRange*2.0f)));
			y2=(-object_display_pos.z*(radarh/(radarRange*2.0f)));

			ClipLine (x1,y1,x2,y2,0,0,57.0f);
			if (x1 != -1.0f)
				radar_device.DrawLine((int)(x1*(RADAR_SCALE))+240,(int)(y1*(RADAR_SCALE)+185),
					(int)(x2*(RADAR_SCALE))+240,(int)(y2*(RADAR_SCALE)+185),color);
		}
	}


	//Draw Torso View..
	//HSH_RenderRadarTorsoView(-m_TorsoTwist);
	radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,	D3DBLEND_SRCALPHA );
	radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
	radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTFG_LINEAR);
	radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTFG_LINEAR);
    
	radar_device.DrawTextureRotate(92,34,252,194,252,194,240,185,-m_TorsoTwist+3.1415926f/4.0f,0xC080C080);

	radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTFG_POINT );
	radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTFG_POINT );

	//Draw Radar range.
	char text[10];
    if (radarRange != radarRangeOrg)
        sprintf (text,"NoLmt");
    else
	    sprintf (text,"%4.0f",radarRange);
	//HSH_DrawRadarNumber(345,386,text,1);
	radar_device.pFont[1].DrawText(80,350,0xFFFFFFFF,text,TEXTALIGN_ORG);

	//Draw ActiveMode..
	char* modechar=(vehicle->GetSensor ()->GetSensorMode () == Sensor::ActiveMode)?"Active":"Passive";
	radar_device.pFont[1].DrawText(395,350,0xFFFFFF,modechar,TEXTALIGN_ORG);

	//Draw buildings.
	MWObject *current_object;
	for(i=0;i<vehicle->GetSensor()->numberOfBuildingContacts;i++)
	{
		current_object=vehicle->GetSensor()->GetBuildingData()[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;
			Point3D fredpt(current_object->GetLocalToWorld ());
			if (fredpt.y < -1000)
				draw_contact = false;

			if(draw_contact){
				object_to_world=current_object->GetLocalToWorld();
				object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
				object_display_pos=object_to_vehicle;
				
				object_display_pos.x=-object_display_pos.x*(radarw/(radarRange*2.0f));
				object_display_pos.y=-object_display_pos.z*(radarh/(radarRange*2.0f));

				int posx=(int)(RADAR_SCALE*object_display_pos.x)+240-6;
				int posy=(int)(RADAR_SCALE*object_display_pos.y)+185-6;
				if(IsRadarRange(posx+6,posy+6)){
					switch (vehicle->GetRelativeAlignment(current_object->GetAlignment())){
						case Entity::DefaultAlignment:
							//HSH_DrawRadarTexture(14-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
							radar_device.DrawTexture(posx,posy,0xFFFFFFFF,36,0,36+12,12);
							break;
						case Entity::Enemy:
							//HSH_DrawRadarTexture(12-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
							radar_device.DrawTexture(posx,posy,0xFFFFFFFF,12,0,12+12,12);
							break;
						default:
							//HSH_DrawRadarTexture(15-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
							radar_device.DrawTexture(posx,posy,0xFFFFFFFF,48,0,48+12,12);
							break;
					}

					int t;
					if (current_object == m_CurrentTarget.GetCurrent ()){
						t=0;
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,t,0,t+12,12);
					}else if (OnShotList (current_object->objectID)){
						t=24;
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,t,0,t+12,12);
					}

					//HSH_DrawRadarTexture(texturenum,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
				}
			}
		}
	}
	
	//Draw Objects.
	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) &&
				(MWApplication::GetInstance()->networkingFlag == false))
				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_to_world=current_object->GetLocalToWorld();
				object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
				object_display_pos=object_to_vehicle;
				
				object_display_pos.x=-object_display_pos.x*(radarw/(radarRange*2.0f));
				object_display_pos.y=-object_display_pos.z*(radarh/(radarRange*2.0f));

				int posx=(int)(RADAR_SCALE*object_display_pos.x)+240-6;
				int posy=(int)(RADAR_SCALE*object_display_pos.y)+185-6;

				if(IsRadarRange(posx+6,posy+6)){
				
					switch (vehicle->GetRelativeAlignment(current_object->GetAlignment()))
					{
						case Entity::DefaultAlignment:
							//HSH_DrawRadarTexture(14-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
							radar_device.DrawTexture(posx,posy,0xFFFFFFFF,36,0,36+12,12);
							break;
						case Entity::Enemy:
							//HSH_DrawRadarTexture(12-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
// MSL 5.02 SubSystems
							if ((current_object->GetIFF_Jammer()) && (current_object->GetDistanceFrom (vehicle) > 200))
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,36,0,36+12,12);
							}
							else
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,12,0,12+12,12);
							}
							break;
						default:
							//HSH_DrawRadarTexture(15-11,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
// MSL 5.02 SubSystems
							if ((current_object->GetIFF_Jammer()) && (current_object->GetDistanceFrom (vehicle) > 200))
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,36,0,36+12,12);
							}
							else
							{
								radar_device.DrawTexture(posx,posy,0xFFFFFFFF,48,0,48+12,12);
							}
							break;
					}

					int t;
					if (current_object == m_CurrentTarget.GetCurrent ()){
						t=0;
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,t,0,t+12,12);
					}else if (OnShotList (current_object->objectID)){
						t=24;
						radar_device.DrawTexture(posx,posy,0xFFFFFFFF,t,0,t+12,12);
					}
                    if (current_object->IsDerivedFrom(Mech::DefaultData)) {
                        Mech* pMech = Cast_Object(Mech*, current_object);

                        if (gos_GetElapsedTime() < pMech->m_fTimeMsgSentEnd) {
                            //pMech->m_nMsgKind;
                            radar_device.DrawTexture(posx,posy,0xFFFFFFFF,0,24,24,24+24);
                        }
                    }
				}
			}
		}
	}

	//Draw Navigation Points.
	j=0;
	ChainIteratorOf<NavPoint *> iter (NavPoint::s_RevealedNavPoints);
	NavPoint *nav;
	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_to_world=nav->GetLocalToWorld();
		object_to_vehicle.Multiply(object_to_world,world_to_vehicle);
		object_display_pos=object_to_vehicle;

		object_display_pos.x=-object_display_pos.x*(radarw/(radarRange*2.0f));
		object_display_pos.y=-object_display_pos.z*(radarh/(radarRange*2.0f));

		int posx=(int)(RADAR_SCALE*object_display_pos.x)+240-1;
		int posy=(int)(RADAR_SCALE*object_display_pos.y)+185-2;

// MSL 5.02 Nav Points
		Stuff::Point3D map_object_display_pos;
		map_object_display_pos=nav->GetLocalToWorld();
		map_object_display_pos.y = map_object_display_pos.z;
		map_object_display_pos.x *= multx;
		map_object_display_pos.y *= multz;
		int posx2=-map_object_display_pos.x+240-3;
		int posy2=-map_object_display_pos.y+508-3;
		
		
		if(IsRadarRange(posx+1,posy+2))
		{
			//HSH_DrawRadarTexture(id+5,(int)(object_display_pos.x-display_center.x),(int)(object_display_pos.y-display_center.y));
			radar_device.DrawTexture(posx,posy,0xFFFFFFFF,60+id*12,0,60+id*12+12,12);
		}

// MSL 5.02 Nav Points
		radar_device.DrawTexture(posx2,posy2,0xFFFFFFFF,(60+id*12),0,(60+id*12)+12,12);
	}

	///////////////////// RADAR END //////////////////////
}
}

void GUIRadarManager::Update(Stuff::Time till)
{
	if (m_RotateTime == 0)
		m_RotateTime = till;

	while (m_RotateTime <= till)
	{
		zrot += 0.26f;
		if (zrot > (2*Pi))
			zrot = 0;
		m_RotateTime += 1.0/26.0;
	}
	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);
}


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

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

void GUIRadarManager::SetRange(Stuff::Scalar range)
{
    radarRangeOrg = range;
    if (range > 1200.f)
        radarRange = 1200.f;
    else
        radarRange = range;
}

Stuff::Scalar GUIRadarManager::GetRange(bool bOrg/* = true*/) const
{
    if (bOrg)
        return radarRangeOrg;
    return radarRange;
}

bool GUIRadarManager::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 GUIRadarManager::AddShot (ObjectID who)
{
	m_ShotList.push_back (ShotEntry (who,gos_GetElapsedTime ()));
}

#if 1
void GUIRadarManager::ClipLine (Scalar& xpt1,Scalar& ypt1,Scalar& xpt2,Scalar& ypt2,Scalar cx,Scalar cy,Scalar rad)
{
	Stuff::Point3D extra,destloc1,destloc2,center;
	Stuff::Point3D d1vec,d2vec,third;
	Stuff::Scalar slope,intercept,a,b,c,inner,root,x1,x2,t1,t2,y,w;
	bool p1in,p2in;

	destloc1 = Point3D (xpt1,0,ypt1);
	destloc2 = Point3D (xpt2,0,ypt2);
	p1in = (((destloc1.x*destloc1.x)+(destloc1.z*destloc1.z)) <= (rad*rad));
	p2in = (((destloc2.x*destloc2.x)+(destloc2.z*destloc2.z)) <= (rad*rad));

	if (p1in && p2in)
		return;

	if (abs ((int) (xpt1 - xpt2)) < 1)
	{
		if ((xpt1 < -rad) || (xpt1 > rad))
		{
			xpt1 = -1;
			xpt2 = -1;
			ypt1 = -1;
			ypt2 = -1;
			return;
		}
		Scalar temp;
		temp = (float) sqrt ((rad*rad) - (xpt1*xpt1));
		if (!p1in)
		{
			if (ypt1 < 0)
				ypt1 = -temp;
			else
				ypt1 = temp;
		}
		if (!p2in)
			if (ypt2 < 0)
				ypt2 = -temp;
			else
				ypt2 = temp;
		return;
	}

	rad *= rad;
	center.x = cx;
	center.y = 0;
	center.z = cy;

	slope = (destloc2.z-destloc1.z)/(destloc2.x-destloc1.x);
	intercept = destloc2.z-(slope*destloc2.x);

	w = intercept-center.z;
	a = (slope*slope)+1.0f;
	b = (2.0f*slope*w)-(2.0f*center.x);
	c = (w*w)-(rad)+(center.x*center.x);
	inner = (b*b) - (4.0f*a*c);
	if (inner < 0)
	{
		xpt1 = -1;
		xpt2 = -1;
		ypt1 = -1;
		ypt2 = -1;
	}
	else
	{
		root = (float) sqrt (inner);
		x1 = (-b+root)/(2*a);
		x2 = (-b-root)/(2*a);

		t1 = (x1-destloc1.x)/(destloc2.x-destloc1.x);
		t2 = (x2-destloc1.x)/(destloc2.x-destloc1.x);

		if (p1in || p2in)
		{
			if ((t1 >= 0) && (t1<=1))
			{
				y= slope*x1 + intercept;
				if (p1in)
				{
					xpt2 = x1;
					ypt2 = y;
				}
				else
				{
					xpt1 = x1;
					ypt1 = y;
				}
			}
			else if ((t2 >= 0) && (t2<=1))
			{
				y= slope*x2 + intercept;
				if (p1in)
				{
					xpt2 = x2;
					ypt2 = y;
				}
				else
				{
					xpt1 = x2;
					ypt1 = y;
				}
			}
			else
			{
				y= slope*x1 + intercept;
				xpt1 = x1;
				ypt1 = y;
				y= slope*x2 + intercept;
				xpt2 = x2;
				ypt2 = y;
			}
		}
		else
		{
			y= slope*x1 + intercept;
			xpt1 = x1;
			ypt1 = y;
			y= slope*x2 + intercept;
			xpt2 = x2;
			ypt2 = y;
		}
#if 0
		else
		{
			if (((destloc1.x*destloc1.x)+(destloc1.z*destloc1.z)) > rad2)
			{
				xpt1 = ypt1 = -1;
			}
		}
#endif
#if 0
		else
		{
			if (((destloc2.x*destloc2.x)+(destloc2.z*destloc2.z)) > rad2)
			{
				xpt2 = ypt2 = -1;
			}
		}
#endif
	}
}
#else
void ClipLine2 (double& xpt1,double& ypt1,double& xpt2,double& ypt2,double cx,double cy,double rad);

void GUIRadarManager::ClipLine (Scalar& xpt1,Scalar& ypt1,Scalar& xpt2,Scalar& ypt2,Scalar cx,Scalar cy,Scalar rad)
{
	double d_xpt1 = xpt1, d_ypt1 = ypt1, d_xpt2 = xpt2, d_ypt2 = ypt2;
	ClipLine2(d_xpt1, d_ypt1, d_xpt2, d_ypt2, cx, cy, rad);
	xpt1 = d_xpt1, ypt1 = d_ypt1, xpt2 = d_xpt2, ypt2 = d_ypt2;
}

void ClipLine2 (double& xpt1,double& ypt1,double& xpt2,double& ypt2,double cx,double cy,double rad)
{
	Stuff::Point3D extra,destloc1,destloc2,center;
	Stuff::Point3D d1vec,d2vec,third;
	//Stuff::Scalar
	double slope,intercept,a,b,c,inner,root,x1,x2,t1,t2,y,w;
	bool p1in,p2in;

	destloc1 = Point3D (xpt1,0,ypt1);
	destloc2 = Point3D (xpt2,0,ypt2);
	p1in = (((destloc1.x*destloc1.x)+(destloc1.z*destloc1.z)) <= (rad*rad));
	p2in = (((destloc2.x*destloc2.x)+(destloc2.z*destloc2.z)) <= (rad*rad));

	if (p1in && p2in)
		return;

	if (abs ((int) (xpt1 - xpt2)) < 1)
	{
		if ((xpt1 < -rad) || (xpt1 > rad))
		{
			xpt1 = -1;
			xpt2 = -1;
			ypt1 = -1;
			ypt2 = -1;
			return;
		}
		//Scalar 
		double temp;
		temp = (float) sqrt ((rad*rad) - (xpt1*xpt1));
		if (!p1in)
		{
			if (ypt1 < 0)
				ypt1 = -temp;
			else
				ypt1 = temp;
		}
		if (!p2in)
			if (ypt2 < 0)
				ypt2 = -temp;
			else
				ypt2 = temp;
		return;
	}

	rad *= rad;
	center.x = cx;
	center.y = 0;
	center.z = cy;

	slope = (destloc2.z-destloc1.z)/(destloc2.x-destloc1.x);
	intercept = destloc2.z-(slope*destloc2.x);

	w = intercept-center.z;
	a = (slope*slope)+1.0f;
	b = (2.0f*slope*w)-(2.0f*center.x);
	c = (w*w)-(rad)+(center.x*center.x);
	inner = (b*b) - (4.0f*a*c);
	if (inner < 0)
	{
		xpt1 = -1;
		xpt2 = -1;
		ypt1 = -1;
		ypt2 = -1;
	}
	else
	{
		root = (float) sqrt (inner);
		x1 = (-b+root)/(2*a);
		x2 = (-b-root)/(2*a);

		t1 = (x1-destloc1.x)/(destloc2.x-destloc1.x);
		t2 = (x2-destloc1.x)/(destloc2.x-destloc1.x);

		if (p1in || p2in)
		{
			if ((t1 >= 0) && (t1<=1))
			{
				y= slope*x1 + intercept;
				if (p1in)
				{
					xpt2 = x1;
					ypt2 = y;
				}
				else
				{
					xpt1 = x1;
					ypt1 = y;
				}
			}
			else if ((t2 >= 0) && (t2<=1))
			{
				y= slope*x2 + intercept;
				if (p1in)
				{
					xpt2 = x2;
					ypt2 = y;
				}
				else
				{
					xpt1 = x2;
					ypt1 = y;
				}
			}
			else
			{
				y= slope*x1 + intercept;
				xpt1 = x1;
				ypt1 = y;
				y= slope*x2 + intercept;
				xpt2 = x2;
				ypt2 = y;
			}
		}
		else
		{
			y= slope*x1 + intercept;
			xpt1 = x1;
			ypt1 = y;
			y= slope*x2 + intercept;
			xpt2 = x2;
			ypt2 = y;
		}
#if 0
		else
		{
			if (((destloc1.x*destloc1.x)+(destloc1.z*destloc1.z)) > rad2)
			{
				xpt1 = ypt1 = -1;
			}
		}
#endif
#if 0
		else
		{
			if (((destloc2.x*destloc2.x)+(destloc2.z*destloc2.z)) > rad2)
			{
				xpt2 = ypt2 = -1;
			}
		}
#endif
	}
}
#endif




namespace NHUDHEAT
{
	const int heat_box[23] = {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88};
	const int heat_color[23] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2};
};
HUDHeat::HUDHeat ()
{
	AddTexture ("hud\\hud4",0,93,0,103,87);			// main heat bar
	AddTexture ("hud\\hud4",1,92,89,103,177);			// background heat bar
	Location (Point3D (317.0f,501.0f,0.9f));
	Size (m_Textures[0]->Size ());
	m_BaseBottom = 88;
	m_Alpha = 255;
	m_AlphaTime = 0;
	m_HeatColor[2] = MakeColor (255,0,0,255);
	m_HeatColor[1] = MakeColor (255,255,0,255);
	m_HeatColor[0] = MakeColor (0,144,0,255);
	m_Heat = 0;
	m_HeatText = new HUDText ();
	m_HeatText->TopLeft (231,517);
	m_HeatText->BottomRight (288,540);
	m_HeatText->Justification (HUDText::LEFT_ALIGN);
	m_HeatText->Color (MakeColor (255,255,255,255));
	m_HeatText->UpdateText ("0 %");
}

HUDHeat::~HUDHeat ()
{
	delete m_HeatText;
}

void HUDHeat::Update (Stuff::Time till)
{
	if (m_AlphaTime == 0)
		m_AlphaTime = till;

	while (m_AlphaTime <= till)
	{
		if (m_TargetHeat != m_Heat)
		{
			m_Heat += m_TargetHeat<m_Heat ? -1:1;
		}
		m_AlphaTime += 1.0/52.0;
	}

	inherited::Update (till);
}

void HUDHeat::DrawImplementation(void)
{
if(!hsh_initialized){
	Point3D loc,size;
	Scalar heaty;
	int heatcolor;

	size = Size ();
	loc = Location ();

	int targetyval = (int) ((m_Heat * 23)/100.0f);
	Clamp (targetyval,0,22);
	heatcolor = NHUDHEAT::heat_color[targetyval];
	targetyval = NHUDHEAT::heat_box[targetyval];

	Scalar fred = (m_TargetHeat * 23)/100.0f;
	Clamp (fred,0,22);
	fred = (Scalar) NHUDHEAT::heat_box[(int) fred];
	heaty = loc.y + size.y - fred;


	DWORD color = MakeColor (64,64,64,255);
	//Bar gauge background baseline..
	m_Textures[1]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
	color = MakeColor (255,255,255,255);
	loc.y += size.y - targetyval;
	size.y = (Scalar) targetyval;
	m_Textures[0]->TopLeft (m_Textures[0]->Left (),(Scalar) (m_BaseBottom - targetyval));
	m_Textures[0]->BlendMode (gos_BlendDecal);
	//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)

	m_Textures[0]->Draw (loc,size,color,HUDTexture::NO_FLIP);
	color = MakeColor (0,125,0,250);
	size = Size ();
	loc = Location ();
	//Bar gauge frame.
	DrawFrame ((int) (loc.x-2),(int) (loc.y-2),(int) (loc.x+size.x),(int) (loc.y+size.y),color);

	//Temperature text frame..
	DrawFrame (261,542,303,560,color);
	m_HeatText->TopLeft (261,542);
	m_HeatText->BottomRight (303,560);

	m_HeatText->Color (m_HeatColor[heatcolor]);
	DWORD textw,texth;
	m_HeatText->DrawSize (textw,texth);

	//Display temperature in its designated color. (Gauge is a texture, no color spec needed.)
	m_HeatText->Draw (Point3D (282.0f - (textw/2.0f),551.0f - (texth/2.0f),0.9f));
	DrawLine (304,549,310,549,color);
	DrawLine (309,(int) heaty,309,549,color);
	DrawLine ((int) (loc.x-2),(int) (heaty),309,(int) (heaty),color);
}else if(sh_step==1){
	//radar manager is not called on shutdown.. state updated additionally here.
    MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();
    p->GetGUIRadarStates(radar_device.recent_state);

	int targetyval = (int) ((m_Heat * 23)/100.0f);
	Clamp (targetyval,0,22);
	//What is the range of heat??? 0~100???

	//Draw current temperature only, without the target.
	float sizey=256;
	//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)
	{
		radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
		//backbground image
		//HSH_DrawTexture(0,630-188,400,512+68,480+256-78,512+256,480+256-52);
		//		256-78,68,256-52,256,
		radar_device.DrawTexture(54,630-188,0xFFFFFFFF,52,68, 78,256);
		//color heat bar
		//HSH_DrawTexture(0,54,(int)(630-targetyval*188/sizey),400,
		//	(int)(512+256-targetyval*188/sizey),480+256-26,512+256,480+256-0);
		radar_device.DrawTexture(54,630-m_Heat*188.0f/100.0f,0xFFFFFFFF,0,256-m_Heat*188.0f/100.0f,25,256);
		//HSH_DrawFrame(0,,0xFFFF);
		radar_device.pD3DDevice->SetTexture(0,0);
		radar_device.DrawFrame(54-1,630-188-3,80+1,630+3,0xFFFFFFFF);
	}
	//Text
	{
		char buf[16];
// MSL 5.02 Heat Scale Header
		//		sprintf (buf,"%5.0fK",m_Heat*100.0f);
		sprintf (buf,"%5.0f %%",m_Heat*1.0f);
		//HSH_DrawRadarNumber(409,388,buf,1);
		radar_device.pFont[1].DrawText(100,412,0xFFFFFFFF,buf,TEXTALIGN_VCENTER|TEXTALIGN_RIGHT);
	}
}
}


HUDJump::HUDJump ()
{
	m_Alpha = 255;
	m_BaseBottom = 109;
	m_AlphaTime = 0;
	m_Jump = -1.0f;
  m_TargetJump = -1.0f;
	Location (Point3D (467,539,0.9f));
	Size (Point3D (7,49,0.9f));
	//Small 'j' character... <==actually barely visible.
	AddTexture ("hud\\hud4",0,98,200,106,207);
}

HUDJump::~HUDJump ()
{
}

void HUDJump::Update (Stuff::Time till)
{
	if (m_AlphaTime == 0)
		m_AlphaTime = till;

	while (m_AlphaTime <= till)
	{
//		if (m_TargetJump != m_Jump)
//		{
//			m_Jump += m_TargetJump<m_Jump ? -0.1f : 0.1f;
//			Clamp (m_Jump,-1.0f,1.0f);
//		}
		m_Alpha -=20;
		if (m_Alpha < 0)
			m_Alpha = 0;
		m_AlphaTime += 1.0/26.0;
	}

	inherited::Update (till);
}

void HUDJump::DrawImplementation(void)
{
if(!hsh_initialized){
	Point3D loc,size;

	if (m_Jump == -1.0f)
		return;
	size = Size ();
	loc = Location ();

	DWORD color = MakeColor (255,255,255,250); // was originally 255,255,255,250
	//Small 'j' character...
	m_Textures[0]->Draw (Point3D (loc.x+2,loc.y - m_Textures[0]->Size().y-2.0f,0.9f),m_Textures[0]->Size (),color);
	int targetyval = (int) (m_Jump * size.y);

	color = MakeColor (0,125,0,250);

	//Green gauge..
	my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
	if ((m_Jump != 0) && (m_Alpha != 0))
	{
		color = MakeColor (255,255,255,m_Alpha);
		my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
	}

	//White line at the top of gauge..
	color = MakeColor (255,255,255,200);
	DrawLine ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y-targetyval),color);
	
	//Draw border..
	color = MakeColor (0,125,0,250);
	DrawFrame ((int) loc.x,(int) (loc.y),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
}else if(sh_step==1){
	if (m_Jump == -1.0f)return;

	DWORD color=((m_Jump != 0) && (m_Alpha != 0)) ? 0xFFFFFFFF:0xFF1E9A32;

	radar_device.pD3DDevice->SetTexture(0,0);
	radar_device.DrawQuad(364,632-m_Jump*160,376,632,color);
	radar_device.DrawFrame(364,632-160,376,632,0xFFFFFFFF);
}
}

//Overall almost identical to jumpjet.
HUDCoolant::HUDCoolant ()
{
	m_Alpha = 255;
	m_BaseBottom = 109;
	m_AlphaTime = 0;
	m_Cool = 100;
	Location (Point3D (332,539,0.9f));
	Size (Point3D (7,49,0.9f));
	//Small 'C' character..
	AddTexture ("hud\\hud4",0,88,200,96,207);
}

HUDCoolant::~HUDCoolant ()
{
}

void HUDCoolant::Update (Stuff::Time till)
{
	if (m_AlphaTime == 0)
		m_AlphaTime = till;

	while (m_AlphaTime <= till)
	{
		if (m_TargetCool != m_Cool)
		{
			m_Cool += m_TargetCool<m_Cool ? -1:1;
		}
		m_Alpha -=20;
		if (m_Alpha < 0)
			m_Alpha = 0;
		m_AlphaTime += 1.0/26.0;
	}

	inherited::Update (till);
}

void HUDCoolant::DrawImplementation(void)
{
if(!hsh_initialized){
	Point3D loc,size;

	size = Size ();
	loc = Location ();

	DWORD color = MakeColor (0,125,0,250);
	//Small 'C' character..
	m_Textures[0]->Draw (Point3D (loc.x+2,loc.y - m_Textures[0]->Size().y-2.0f,0.9f),m_Textures[0]->Size (),color);

	m_gCool = m_Cool;
	int targetyval = (int) ((m_Cool * size.y)/100.0f);
	Clamp (targetyval,0,(int) size.y);

	color = MakeColor (0,100,255,250);
	//Draw gauge..
	my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
	if ((m_Cool != 0) && (m_Alpha != 0))
	{
		//When flushed.. draw white blinking effect...
		color = MakeColor (255,255,255,m_Alpha);
		my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
	}
	color = MakeColor (255,255,255,200);
	//White line above gauge..
	DrawLine ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y-targetyval),color);

	//Frame surrounding gauge..
	color = MakeColor (0,125,0,250);
	DrawFrame ((int) loc.x,(int) (loc.y),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
}else if(sh_step==1){
	DWORD color=(m_Cool != 0) && (m_Alpha != 0) ? 0xFFFFFFFF:0xFF5694FA;

	m_gCool = m_Cool;

	radar_device.pD3DDevice->SetTexture(0,0);
	radar_device.DrawQuad(104,632-m_Cool/100.0f*160,116,632,color);
	radar_device.DrawFrame(104,632-160,116,632,0xFFFFFFFF);
}
}


//HUD Component displaying speed...
namespace NHUDSPEED
{
//	const int for_speed_box[12] = {0,4,8,12,16,20,24,28,32,36,40,44};
//	const int rev_speed_box[12] = {0,4,8,12,16,20,24,28,32,36,40,44};
	const int for_speed_box[16] = {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56};
	const int rev_speed_box[9] = {0,4,8,12,16,20,24,28,32};
};
HUDSpeed::HUDSpeed ()
{
	AddTexture ("hud\\hud4",0,105,0,116,87);
	AddTexture ("hud\\hud4",1,92,89,103,177);			// background speed bar
	Location (Point3D (480.0f,500.0f,0.9f));
	Size (m_Textures[0]->Size ());
	m_BaseBottom = 88;
//	m_Middle = 44;
	m_Alpha = 255;
	m_AlphaTime = 0;
	m_Speed = 0;
	m_TargetSpeed = 0;
	m_MaxForwardSpeed = 1.0f;
	m_MaxReverseSpeed = 1.0f;
	m_SpeedText = new HUDText ();
	m_SpeedText->TopLeft (513,517);
	m_SpeedText->BottomRight (570,540);
	m_SpeedText->Justification (HUDText::LEFT_ALIGN);
	m_SpeedText->Color (MakeColor (255,255,255,255));
	m_SpeedText->UpdateText ("0kph");
}

HUDSpeed::~HUDSpeed ()
{
	delete m_SpeedText;
}

void HUDSpeed::Update (Stuff::Time till)
{
	if (m_AlphaTime == 0)
		m_AlphaTime = till;

	while (m_AlphaTime <= till)
	{
		if (m_TargetSpeed != m_Speed)
		{

// MSL 5.00 Speed Bar
// Changed this due to Speed Bar serious lagging behind actual speed.
			if ((abs(m_TargetSpeed-m_Speed)) > 5)
				m_Speed += m_TargetSpeed<m_Speed ? -5:5;
			else
			m_Speed += m_TargetSpeed<m_Speed ? -1:1;
		}
		m_AlphaTime += 1.0/26.0;
	}

	if (m_Vehicle.GetCurrent ())
	{
		m_Vehicle.GetCurrent ()->GetMaxSpeedKPH (m_MaxForwardSpeed,m_MaxReverseSpeed);
	}
	else
	{
		m_MaxForwardSpeed = 1.0f;
		m_MaxReverseSpeed = 1.0f;
	}
	inherited::Update (till);
}

void HUDSpeed::DrawImplementation(void)
{
if(!hsh_initialized){
	Point3D loc,size;
	Scalar speedy;
	Scalar top,bottom;

	size = Size ();
	loc = Location ();
	int targetyval;
	if (m_Speed >=0)
	{
		targetyval = (int) ((m_Speed * 15)/m_MaxForwardSpeed);
		Clamp (targetyval,0,14);
		targetyval = NHUDSPEED::for_speed_box[targetyval];
		top = 56.0f-targetyval;
		bottom =  56.0f;
	}
	else
	{
		targetyval = (int) ((m_Speed * 9)/m_MaxReverseSpeed);
		Clamp (targetyval,0,8);
		targetyval = NHUDSPEED::rev_speed_box[targetyval];
		bottom = 56.0f+targetyval;
		top =  56.0f;
	}

	Scalar fred;
	if (m_TargetSpeed >= 0)
	{
		fred = ((m_TargetSpeed * 15)/m_MaxForwardSpeed);
		Clamp (fred,0,14);
		fred = (Scalar) NHUDSPEED::for_speed_box[(int) fred];
	}
	else
	{
		fred = ((m_TargetSpeed * 9)/m_MaxReverseSpeed);
		Clamp (fred,0,8);
		fred = (Scalar) NHUDSPEED::rev_speed_box[(int) fred];
		fred *= -1.0f;
	}
	speedy = loc.y + 56 - fred;

	DWORD color = MakeColor (255,255,255,255);
	//Gauge background tick marks..
	m_Textures[1]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
	loc.y += top;
	size.y = (Scalar) bottom - top;

	//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)

	m_Textures[0]->TopLeft (m_Textures[0]->Left (),(Scalar) (top));
	m_Textures[0]->BottomRight (m_Textures[0]->Right (),(Scalar) (bottom));
	m_Textures[0]->BlendMode (gos_BlendDecal);
	//Colored gauge.. currently green.
	m_Textures[0]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
	color = MakeColor (0,125,0,250);
	size = Size ();
	loc = Location ();
	//Draw frame surrounding gauge..
	DrawFrame ((int) (loc.x-2),(int) (loc.y-2),(int) (loc.x+size.x),(int) (loc.y+size.y),color);

	//Speed display frame...
	DrawFrame (506,537,548,555,color);
	m_SpeedText->TopLeft (506,537);
	m_SpeedText->BottomRight (548,555);

	if (m_TargetSpeed >= 0)
		m_SpeedText->Color (0,255,0,255);
	else
		m_SpeedText->Color (0,0,255,255);

	DWORD textw,texth;
	m_SpeedText->DrawSize (textw,texth);
	//Speed text.. color is green/blue depending on forward/backward direction.....
	m_SpeedText->Draw (Point3D (527.0f - (textw/2.0f),546.0f - (texth/2.0f),0.9f));
	//3-segment line connecting speed frame to gauge frame..
	DrawLine (498,549,506,549,color);
	DrawLine (498,(int) speedy,498,549,color);
	DrawLine ((int) (loc.x+size.x+2),(int) (speedy),498,(int) (speedy),color);
}else if(sh_step==1){
	//Not ideal, but draw mission time alongside speed display.
	//Draw mission timer... taken from DrawImplementation in hudtimer.cpp..
	{
		MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
		Verify (mwmiss);
		Stuff::Scalar scalar_time=mwmiss->GetEndMissionTime();//-mwmiss->GetMissionTime();
		int time = (int)scalar_time;

		if (time < 0)time *= -1;
		int min = time / 60;
		int sec = time % 60;

		char buf[32];
		wsprintf(buf,"%02d:%02d",min,sec);
		radar_device.pFont[1].DrawText(400,36,0xFFFFFFFF,buf,TEXTALIGN_ORG);
	}

	float offset;
	//126,62.. speed 188.. divided 2:1..

	//backbground image
	radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
	radar_device.DrawTexture(394,630-188,0xFFFFFFFF,52,68,78,256);

	if (m_Speed >=0){
		offset=m_Speed/m_MaxForwardSpeed*126;
		radar_device.DrawTexture(394,630-62-offset,0xFFFFFFFF,26,68+126-offset,52,68+126);
	}else{
		offset=m_Speed/m_MaxReverseSpeed*60;
		radar_device.DrawTexture(394,630-62,0xFFFFFFFF,26,68+126,52,68+126+offset);
	}

	//Draw Frame
	radar_device.pD3DDevice->SetTexture(0,0);
	radar_device.DrawFrame(394-1,630-188-3,420+1,630+3,0xFFFFFFFF);
	//Draw SpeedNumber
	char buf[16];
	wsprintf(buf,"%dKPH",(int)m_Speed);
// MSL 5.00 Speedbar
	if (m_Speed < 0)
		radar_device.pFont[1].DrawText(420,412,0xFFFFFF00,buf,TEXTALIGN_VCENTER|TEXTALIGN_RIGHT);
	else
		radar_device.pFont[1].DrawText(420,412,0xFFFFFFFF,buf,TEXTALIGN_VCENTER|TEXTALIGN_RIGHT);
}
}







//_______________________________________________________________________________________




HUDNav::HUDNav()
{

//	AddTexture ("hud\\hud",0,0,0,213,31);
//	AddTexture ("hud\\hud",1,1.001f,33,15,47);
	AddTexture ("hud\\hud5",2,5,35,22,48);				// left right arrow

	AddTexture ("hud\\hud5",10,27,249,228,256);		// bar
	AddTexture ("hud\\hud5",13,27,249,228,256);		// bar

	AddTexture ("hud\\hud5",11,251,244,256,248);	// arrow
	AddTexture ("hud\\hud5",12,4,134,13,144);			// bug

	Location (Point3D (298,39,0.9f));
	Size (m_Textures[10]->Size ());

	Color (0,255,0,250);

	m_BaseLeft = 27;
	m_BaseRight = 228;
	Point3D size;
	size = m_Textures[11]->Size ();
	m_Textures[11]->Origin (size.x/2.0f,size.y);
	size = m_Textures[12]->Size ();
	m_Textures[12]->Origin (size.x/2.0f,size.y/2.0f);

	MWApplication *app;
	app = MWApplication::GetInstance ();
	int i;
	for (i=0;i<41;i++)
	{
		navText[i] = new HUDText ();
		navText[i]->SetSize (HUDText::SMALL_SIZE);
		switch (i)
		{
		case 0:
		case 36:
			navText[i]->UpdateText (app->GetLocString (IDS_NORTH));
			break;
		case 37:
			navText[i]->UpdateText (app->GetLocString (IDS_NORTHEAST));
			break;
		case 9:
			navText[i]->UpdateText (app->GetLocString (IDS_EAST));
			break;
		case 38:
			navText[i]->UpdateText (app->GetLocString (IDS_SOUTHEAST));
			break;
		case 18:
			navText[i]->UpdateText (app->GetLocString (IDS_SOUTH));
			break;
		case 39:
			navText[i]->UpdateText (app->GetLocString (IDS_SOUTHWEST));
			break;
		case 27:
			navText[i]->UpdateText (app->GetLocString (IDS_WEST));
			break;
		case 40:
			navText[i]->UpdateText (app->GetLocString (IDS_NORTHWEST));
			break;
		default:
			{
				char text[10];
				itoa (i*10,text,10);
				navText[i]->UpdateText (text);
			}
			break;
		}
	}
	navPointName = new HUDText ();
	navPointRange = new HUDNumberText ();
	playerAngle = new HUDNumberText ();
	navPointRange->SetSize (HUDText::MEDIUM_SIZE); // was originally SMALL_SIZE
	playerAngle->SetSize (HUDText::MEDIUM_SIZE); // was originally SMALL_SIZE

	m_NavAlphaTime = 0;

}

HUDNav::~HUDNav()
{
	int i;
	delete navPointName;
	delete navPointRange;
	for (i=0;i<41;i++)
	{
		delete navText[i];
	}
	delete playerAngle;
}

void HUDNav::Update (Stuff::Time till)
{

	if (m_NavAlphaTime == 0)
		m_NavAlphaTime = till;

	while (m_NavAlphaTime <= till)
	{
		m_NavAlpha +=20;
		if (m_NavAlpha >= 255)
			m_NavAlpha = 15;
		m_NavAlphaTime += 1.0/30.0;
	}

	inherited::Update (till);
}

static char dirnames[][4]	={
	"N","", "10","", "20","", "30","", "40","NE", "50","", "60","", "70","", "80","",
	"E","","100","","110","","120","","130","SE","140","","150","","160","","170","",
	"S","","190","","200","","210","","220","SW","230","","240","","250","","260","",
	"W","","280","","290","","300","","310","NW","320","","330","","340","","350","",""
};

// MSL 5.00 JumpJet MFD
static char mfd_text_nav[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"",	"",	"",	"",	
};

static char mfd_text_navw[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"EJECT\nAMMO ROUND",	"",	"",	"",	
};

static char mfd_text_navwa[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"EJECT\nAMMO ROUND",	"",	"",	"EJECT\nAMMO MAGAZINE",	
};

static char mfd_text_nava[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"",	"",	"",	"EJECT\nAMMO MAGAZINE",	
};

static char mfd_text_navj[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"",	"JUMP\nJET",	"JUMP\nJET",	"",	
};

static char mfd_text_navjw[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"EJECT\nAMMO ROUND",	"JUMP\nJET",	"JUMP\nJET",	"",	
};

static char mfd_text_navja[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"",	"JUMP\nJET",	"JUMP\nJET",	"EJECT\nAMMO MAGAZINE",	
};

static char mfd_text_navjwa[8][32]={
	"",	"NEXT WAYPOINT",	"PREV WAYPOINT",	"OBJECTIVES",	
	"EJECT\nAMMO ROUND",	"JUMP\nJET",	"JUMP\nJET",	"EJECT\nAMMO MAGAZINE",	
};


void sh_get_rect_center(const RECT &rc,int &x,int&y)
{
	x=(rc.left+rc.right)/2;
	y=(rc.top+rc.bottom)/2;
}

extern int _stdcall VehGetShutdownState();

void HUDNav::DrawImplementation(void)
{
if(!hsh_initialized){
	Point3D loc,size;
	int i;

	loc = Location ();
	DWORD color = MakeColor (0,255,0,250);
	
	int offset = m_PlayerFacing%10;
	if (offset < 0)
		offset *= -1;
	offset *= 5;
	m_Textures[10]->TopLeft ((Scalar) (m_BaseLeft + offset),m_Textures[10]->Top ());
	size = m_Textures[10]->Size ();
	m_Textures[10]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
	//Main portion of aux2 ruler... (if not displayable here, use next one.)
#if 1	
	loc.x += size.x;
	loc.x-=1;
	m_Textures[13]->BottomRight ((Scalar) m_BaseLeft+offset,m_Textures[13]->Bottom ());
	size = m_Textures[13]->Size ();
	m_Textures[13]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
	//Short tick marks of aux2 ruler....
#endif	
	
	int heading = m_PlayerFacing;
	loc = Location ();
	Scalar cx=loc.x;
	for (i=heading-20;i<=heading+20;i++,cx+=5.0f)
	{
		int textid = 0;
		int dir = i;
		bool draw = false;
		if (dir < 0)
			dir += 360;
		else if (dir > 360)//sanghoon fix: original was --> "else if (dir > 360)"..
			dir -= 360;
		switch (dir)
		{
		case 45:
			textid = 37;
			draw = true;
			break;
		case 135:
			textid = 38;
			draw = true;
			break;
		case 225:
			textid = 39;
			draw = true;
			break;
		case 315:
			textid = 40;
			draw = true;
			break;
		default:
			if (!(dir % 10))
			{
				draw = true;
				textid = dir/10;
			}
			break;
		}
		if (draw)
		{
			DWORD dx,dy;
			Point3D textloc;
			textloc.x = cx;
			textloc.z = 0.9f;
			textloc.y = 26.0f;
			navText[textid]->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
			navText[textid]->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
			navText[textid]->Color (0xff00aa00);
			navText[textid]->Justification (HUDText::LEFT_ALIGN);
			navText[textid]->DrawSize (dx,dy);
			textloc.x -= dx/2;
			navText[textid]->Draw (textloc);
			//Aux2 bearing display.. 340 350 N 10 20...
		}
	}
	
	//Aux2 mech heading angle display...
	color = Color ();
	DrawFrame (400-13,10,400+13,22,color);
	DWORD dx,dy;
	Point3D textloc;
	textloc.x = 400.0f;
	textloc.y = 12.0f;
	textloc.z = 0.9f;
	playerAngle->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
	playerAngle->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
	playerAngle->Color (color);
	playerAngle->Justification (HUDText::LEFT_ALIGN);
	playerAngle->DrawSize (dx,dy);
	textloc.x -= ((dx/2)+1);
	playerAngle->Draw (textloc);

	size = m_Textures[11]->Size ();
	color = Color ();
	m_Textures[11]->Draw (Point3D (400.0f,44.0f,0.9f),size,color);
	//Aux2 center indicator.. inverted triangle.. (very small)

	if (m_NavPointRange != -1)
	{

		Point3D textloc;

		textloc.x = 0;
		textloc.y = 0;
		textloc.z = 0;
		// Draw navpoint bug or arrows
		//Aux2 navigation
		//navpoint: draw circle indicating objective (when displayable in ruler)
		//When unable to display in arrow ruler.. show direction with left/right arrow only.
		DWORD color = (m_NavAlpha << 24) + 0x00AF00;

		size = Size ();
		if ((m_NavPointFacing > -20) && (m_NavPointFacing < 20))
		{
			int bugoffset=0;
			bugoffset = (m_NavPointFacing*5) * -1;

			Point3D bugloc,bugsize;
			bugloc = loc;
			bugloc.y = 45;
			bugloc.x = loc.x + (size.x/2.0f) + bugoffset;
			bugsize = m_Textures[12]->Size ();
			m_Textures[12]->Draw (bugloc,bugsize,color);
			textloc.x = bugloc.x;
			textloc.y = bugloc.y + m_Textures[12]->Size ().y/2.0f;
			textloc.y += 2;
			textloc.z = 0.9f;
		}
		else
		{
			Point3D bugloc,bugsize;
			bugloc = loc;
			bugloc.y += (size.y/2) ;
			bugsize = m_Textures[2]->Size ();
			bugloc.y -= bugsize.y/2;

			if (m_NavPointFacing <= -10)
			{
				bugloc.x = loc.x + size.x + 5;
				m_Textures[2]->Draw (bugloc,bugsize,color,HUDTexture::XFLIP);
				textloc.x = bugloc.x + bugsize.x/2.0f;
			}
			else if (m_NavPointFacing >= 10)
			{
				bugloc.x = loc.x -5 ;
				bugloc.x -= bugsize.x;
				m_Textures[2]->Draw (bugloc,bugsize,color);
				textloc.x = bugloc.x + bugsize.x/2.0f;
			}
			textloc.y = bugloc.y + m_Textures[2]->Size ().y/2.0f;
			textloc.y += 5;
			textloc.z = 0.9f;
		}
		//Draw the name of the point target.
		DWORD dx,dy;
		navPointName->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
		navPointName->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
		navPointName->Color (0xff00aa00);
		navPointName->Justification (HUDText::LEFT_ALIGN);
		navPointName->DrawSize (dx,dy);
		textloc.x -= dx/2;
		navPointName->Draw (textloc);
		textloc.x += dx/2;
		
		//Draw distance to point target.
		textloc.y += 12.0f;
		navPointName->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
		navPointName->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
		navPointRange->Color (0xff00aa00);
		navPointRange->Justification (HUDText::LEFT_ALIGN);
		navPointRange->DrawSize (dx,dy);
		textloc.x -= dx/2;
		navPointRange->Draw (textloc);
	}
}else if(mfd_device.BeginChannel(1)){
// MSL 5.00 JumpJet MFD
	Vehicle *vehicle = m_Vehicle.GetCurrent();
	Mech *mech = Cast_Object(Mech *, vehicle);
	JumpJet *jump_jet = mech->GetJumpJet();
	MWApplication *m_App;
	m_App = MWApplication::GetInstance ();
	int m_AmmoMode = m_App->GetLocalNetParams()->m_ammobayfireOn;
	int m_WeaponJamMode = m_App->GetLocalNetParams()->m_weaponjamOn;
// MSL 5.03 Dump Ammo
	if (jump_jet)
	{
		if (m_AmmoMode)
		{
			if (m_WeaponJamMode)
			{
				mfd_device.DrawMFDBackText(mfd_text_navjwa);
			}
			else
			{
				mfd_device.DrawMFDBackText(mfd_text_navja);
			}
		}
		else
		{
			if (m_WeaponJamMode)
			{
				mfd_device.DrawMFDBackText(mfd_text_navjw);
			}
			else
			{
				mfd_device.DrawMFDBackText(mfd_text_navj);
			}
		}
	}
	else
	{
		if (m_AmmoMode)
		{
			if (m_WeaponJamMode)
			{
				mfd_device.DrawMFDBackText(mfd_text_navwa);
			}
			else
			{
				mfd_device.DrawMFDBackText(mfd_text_nava);
			}
		}
		else
		{
			if (m_WeaponJamMode)
			{
				mfd_device.DrawMFDBackText(mfd_text_navw);
			}
			else
			{
				mfd_device.DrawMFDBackText(mfd_text_nav);
			}
		}
	}

	mfd_device.pD3DDevice->SetTexture(0,0);
	
	mfd_device.DrawQuad(0,240-1,640,240+1,0xFFFFFFFF);

    bool bTeamGame = MWApplication::GetInstance()->IsTeamAllowed() ? true: false;
    int nTeam;
    if (bTeamGame) {
        nTeam = MWApplication::GetInstance()->servedConnectionData[Connection::Local->GetID()].pilotTeam;
        if (!((0 <= nTeam) && (nTeam < 8))) {
            bTeamGame = false;
        }
    }
	static RECT prc3[3]={
		{50,340,230,380},
		{280,340,360,380},
		{480,340,560,380},
	};
	static RECT prcTeam[3]={
		{140,300,320,340},
		{340,300,460,340},
		{480,300,600,340},
	};
// MSL 5.02 Score MFD
	static RECT prcTeam1[3]={
		{140,360,320,400},
		{340,360,460,400},
		{480,360,600,400},
	};
    RECT* pcRCs;
// MSL 5.02 Score MFD
    RECT* pcRC1s;
    if (bTeamGame) {
        pcRCs = &prcTeam[0];
// MSL 5.02 Score MFD
        pcRC1s = &prcTeam1[0];
    } else {
        pcRCs = &prc3[0];
    }
    int nCX1, nCX2, nCX3;

	nCX1 = (pcRCs[0].left + pcRCs[0].right) / 2;
    nCX2 = (pcRCs[1].left + pcRCs[1].right) / 2;
    nCX3 = (pcRCs[2].left + pcRCs[2].right) / 2;
    
// MSL 5.02 Score MFD
	if (bTeamGame)
	{
		mfd_device.DrawThickFrameList(3,pcRCs,2,0xFFFFFFFF);
		mfd_device.DrawThickFrameList(3,pcRC1s,2,0xFFFFFFFF);
		mfd_device.pFont[0].DrawText(nCX1,272,0xFFFFFFFF,"SCORE",TEXTALIGN_ORG);
		mfd_device.pFont[0].DrawText(nCX2,272,0xFFFFFFFF,"KILLS",TEXTALIGN_ORG);
		mfd_device.pFont[0].DrawText(nCX3,272,0xFFFFFFFF,"DEATHS",TEXTALIGN_ORG);
	}
	else
	{
		mfd_device.DrawThickFrameList(3,pcRCs,2,0xFFFFFFFF);
		mfd_device.pFont[0].DrawText(nCX1,292,0xFFFFFFFF,"SCORE",TEXTALIGN_ORG);
		mfd_device.pFont[0].DrawText(nCX2,292,0xFFFFFFFF,"KILLS",TEXTALIGN_ORG);
		mfd_device.pFont[0].DrawText(nCX3,292,0xFFFFFFFF,"DEATHS",TEXTALIGN_ORG);
	}

	int offset = m_PlayerFacing%10;
	if (offset < 0)offset *= -1;

	int testoffset=offset*10;

	mfd_device.pD3DDevice->SetTexture(0,mfd_device.pDDSTexture);
	//enable Alpha
	mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
	mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,	D3DBLEND_SRCALPHA );
	mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );

	if(VehGetShutdownState()!=1)
	{
		mfd_device.DrawTexture(120,140,0xFFFFFFFF,testoffset+1,256,testoffset+402+1,256+18);
		//Draw bearing above tick marks
		int heading = m_PlayerFacing;
		int ii=0;
		for (int i=heading-20;i<=heading+20;i++,ii++){
			int dir = i;

			if (dir < 0)dir += 360;
			else if (dir >= 360)dir -= 360;

			if(dir%5==0){
				if(dirnames[dir/5][0]!='\0'){
					//HSH_DrawText(2,120+ii*10,115,dirnames[dir/5],0,0,1);
					mfd_device.pFont[0].DrawText(120+ii*10,115,0xFFFFFFFF,dirnames[dir/5],TEXTALIGN_CENTER);
				}
			}
		}
		
		mfd_device.pD3DDevice->SetTexture(0,0);
		//Draw current bearing
		{
			char text[8];
			wsprintf(text,"%d",(int)m_PlayerFacing);
			mfd_device.DrawFrame(280,60,360,90,0xFFFFFFFF);
			mfd_device.pFont[0].DrawText(320,75,0xFFFFFFFF,text,TEXTALIGN_ORG);
		}
		mfd_device.pD3DDevice->SetTexture(0,mfd_device.pDDSTexture);

		//Draw center-indicator inverted triangle (very small)
		mfd_device.DrawTexture(320-5,140,0xFFFFFFFF,59,30+256,70,39+256);

		//Draw objective.
		if (m_NavPointRange != -1){//when a target waypoint exists.
			int hsh_textpos=0;
			//Draw objective indicator.
			if ((m_NavPointFacing > -20) && (m_NavPointFacing < 20)){
				//When inside bearing range.. draw indicator.
				mfd_device.DrawTexture((int)(320-9-m_NavPointFacing*10),140+4,0xFFFFFFFF,87,28+256,106,47+256);
				hsh_textpos=(int)(320-m_NavPointFacing*10);
			}else{
				//When outside bearing range.. draw arrow.
				if (m_NavPointFacing <= -10){
					mfd_device.DrawTexture(520+4,140,0xFFFFFFFF,3,54+256,39,81+256);
					hsh_textpos=520;
				}else if (m_NavPointFacing >= 10){
					mfd_device.DrawTexture(120-40,140,0xFFFFFFFF,3,22+256,39,49+256);
					hsh_textpos=120;
				}
			}

			//Draw objective name and distance (text).
			mfd_device.pFont[0].DrawText(hsh_textpos,140+26,0xFFFFFFFF,m_NavPointName,TEXTALIGN_CENTER);
			mfd_device.pFont[0].DrawText(hsh_textpos,140+46,0xFFFFFFFF,m_NavPointRangeText,TEXTALIGN_CENTER);
		}
	}
	//Must add routine to draw score info here..
	{
		char score[32]={0};
		char kills[32]={0};
		char deaths[32]={0};
// MSL 5.02 Score MFD
		char tscore[32]={0};
		char tkills[32]={0};
		char tdeaths[32]={0};

        extern int GetScore4Player(int& nKills, int& nDeaths);
        int nScore, nKills, nDeaths;
        nScore = GetScore4Player(nKills, nDeaths);
        itoa(nScore,score,10);
		itoa(nKills,kills,10);
		itoa(nDeaths,deaths,10);

        if (bTeamGame) {
            int nTScore, nTKills, nTDeaths;

	        MWGUIManager *gui_manager = MWGUIManager::GetInstance ();
	        if (gui_manager && gui_manager->Component(MWGUIManager::HUD_SCORE))
	        {
                HUDScore *hud = Cast_Object (HUDScore *, gui_manager->Component(MWGUIManager::HUD_SCORE));
                if (hud) {
                    nTScore = hud->GetTeamScore(nTeam, nTKills, nTDeaths);
// MSL 5.02 Score MFD
//                  sprintf(&score[strlen(score)], " / %d", nTScore);
//	                sprintf(&kills[strlen(kills)], " / %d", nTKills);
//                  printf(&deaths[strlen(deaths)], " / %d", nTDeaths);
					itoa(nTScore,tscore,10);
					itoa(nTKills,tkills,10);
					itoa(nTDeaths,tdeaths,10);
                }
            }
        }
        
// MSL 5.02 Score MFD
		if (bTeamGame)
		{
			mfd_device.pFont[0].DrawText(nCX1-160,320,0xFFFFFFFF,"PILOT",TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX1-160,380,0xFFFFFFFF,"TEAM",TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX1,320,0xFFFFFFFF,score,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX2,320,0xFFFFFFFF,kills,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX3,320,0xFFFFFFFF,deaths,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX1,380,0xFFFFFFFF,tscore,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX2,380,0xFFFFFFFF,tkills,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX3,380,0xFFFFFFFF,tdeaths,TEXTALIGN_ORG);
		}
		else
		{
			mfd_device.pFont[0].DrawText(nCX1,360,0xFFFFFFFF,score,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX2,360,0xFFFFFFFF,kills,TEXTALIGN_ORG);
			mfd_device.pFont[0].DrawText(nCX3,360,0xFFFFFFFF,deaths,TEXTALIGN_ORG);
		}
	}

	mfd_device.EndChannel();
}
}

