#include "MW4Headers.hpp"
//sanghoon begin
#include "MWMission.hpp"
#include "VehicleInterface.hpp"
#include "Vehicle.hpp"
#include "Narc.hpp"
#include "MWGUIManager.hpp"
#include "MWGame.hpp"
#include "gameinfo.hpp"
#include "AI_Statistics.hpp"
#include "AI_UserConstants.hpp"
#include "GameTypes.h"
#include "MWObject.hpp"
#include "MWPlayer.hpp"
#include <Adept\Mission.hpp>
#include <Adept\Map.hpp>
#include "navpoint.hpp"
#include "ai_groups.hpp"
#include "ai.hpp"
#include "lancemate.hpp"
#include "mech.hpp"
#include "mechlabheaders.h"
#include "bucket.hpp"
//sanghoon end
#include "hudcomp.hpp"
#include "HUDChat.hpp"
#include "hudcomm.hpp"
#include "HUDscore.hpp"
#include "mwguimanager.hpp"
#include "mwapplication.hpp"
#include "..\missionlang\resource.h"

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

#include <GameOS\render.hpp>

#include "ctcls.h"
#include "ctcl.h"

extern Scalar g_fLastStartTime;
extern Adept::ReplicatorID g_LastTarget;

//sanghoon end

extern "C" char* _stdcall CharPrevA(const char* lpszStart, const char* lpszCurrent);
#define CharPrev CharPrevA

using namespace MechWarrior4;

const int MAX_CHAT_LINES = 10;

HUDChat::HUDChat()
{
	Location (Point3D (0,0,0.9f));
	Color (0,125,0,250);
	m_CurrentChat = NULL;
	curChatDisplay = new HUDText (false);
	curChatDisplay->Color (255,255,255,255);
	curChatDisplay->Justification (HUDText::LEFT_ALIGN);
	curChatDisplay->Wrap (true);
	curChatDisplay->SetSize (HUDText::SMALL_SIZE);
	m_CursorTime = 0;
	m_CursorBlink = true;
	m_CursorPos = NULL;
	m_TeamChat = false;
	m_LargeSize = false;
	m_ChatLen = NULL;
}

HUDChat::~HUDChat()
{
	delete curChatDisplay;
	KillData ();
}

void HUDChat::KillData (void)
{
	stlport::list<ChatData>::iterator iter;
	
	for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++)
		delete iter->text;
	m_Messages.clear ();
	m_CurrentChat = NULL;

}

void HUDChat::AddChat (const char *mesg,BYTE from, BYTE type, BYTE player_sent_to)
{
	HUDText *text;
	char srctext[MAX_HUD_TEXT];
	MWApplication *app;
	app = MWApplication::GetInstance ();

	srctext[0] = 0;
	Connection *connection = Network::GetInstance()->GetConnection(from);
	if (connection)
	{
		if (type == MWApplication::DeadBroadcast)
			Str_Copy (srctext,app->GetLocString (IDS_DEADCHAT),MAX_HUD_TEXT);
		else if (type == MWApplication::TeamAliveBroadcast)
			Str_Copy (srctext,app->GetLocString (IDS_TEAMCHAT),MAX_HUD_TEXT);
		else if (type == MWApplication::TeamDeadBroadcast)
		{
			Str_Copy (srctext,app->GetLocString (IDS_DEADCHAT),MAX_HUD_TEXT);
			Str_Cat (srctext,app->GetLocString (IDS_TEAMCHAT),MAX_HUD_TEXT);
		}
		else if (type == MWApplication::ObserverBroadcast)
			Str_Copy (srctext,app->GetLocString (IDS_OBSERVERCHAT),MAX_HUD_TEXT);
		Str_Cat(srctext, connection->GetConnectionName(), MAX_HUD_TEXT);
	}

	text = new HUDText ();
	switch (type)
	{
		case MWApplication::SystemBroadcast:
			text->Color (230,230,50,250);
			srctext[0] = 0;
//			Str_Copy (srctext,app->GetLocString (IDS_SYSTEMMESSAGEHEADER),MAX_HUD_TEXT);
			break;
		case MWApplication::AliveBroadcast:
			text->Color (0,191,0,250);
			break;
		case MWApplication::ObserverBroadcast:
		case MWApplication::DeadBroadcast:
			text->Color (122,153,122,250);
			break;
		case MWApplication::TeamAliveBroadcast:
			text->Color (0,243,0,250);
			break;
		case MWApplication::TeamDeadBroadcast:
			text->Color (122,205,122,250);
			break;
		case MWApplication::PrivateBroadcast:
			text->Color (191,48,48,250);
			break;
#if defined(LAB_ONLY)
		case MWApplication::LobbyBroadcast:
		case MWApplication::LobbyTeamBroadcast:
			PAUSE (("Lobby chat got into the hud chat system"));
			break;
#endif
	}
	char buffer[MAX_HUD_TEXT];
	
	text->Justification (HUDText::LEFT_ALIGN);
	text->Wrap (true);
	text->SetSize (HUDText::SMALL_SIZE);
	if (srctext[0] != 0)
	{
		sprintf (buffer,"%s: %s",srctext,mesg);
		text->UpdateText (buffer,false);
	}
	else
		text->UpdateText (mesg,false);

	m_Messages.insert (m_Messages.begin (),ChatData (text,from,type,player_sent_to));
}

void HUDChat::Reset (void)
{
//	KillData ();
	comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));

	//Load map data for mr_device.
	if(hsh_mrdev_initialized){
		extern char AssetsDirectory1[MAX_PATH];
		const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
		char temp[256];
		sprintf(temp, "%s\\hsh\\%s-1.bmp", AssetsDirectory1,model->m_HudMap);
		DrawBitmapToSurface(mr_device.pDDSMapTexture,0,0,temp);
		mr_device.map_loaded=true;
	}

}

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

	if (m_CursorTime == 0)
		m_CursorTime = till;

	while (m_CursorTime <= till)
	{
		m_CursorBlink = !m_CursorBlink;
		m_CursorTime += 1.0/6.0;
	}

	inherited::Update (till);
}

extern "C" unsigned int __stdcall GetACP(void); // defined in winnls.h



static const DWORD SH_DamageColor[6]={0xFFFFFFFF,0xFFCCCCCC,0xFF999999,0xFF666666,0xFF333333,0xFF000000};
static const DWORD SH_DamageColor2[6]={0xFF64E164,0xFFE1E100,0xFFFF9600,0xFFFF3200,0xFF7f1900,0xFF000000};


static const float sm1_texture[][4]=
{
	{217+85, 74,(217+39)+85,( 74+97)},//left leg
	{171+85, 74,(171+39)+85,( 74+97)},//right leg
	{229+85,195,(229+25)+85,(195+61)},//left arm
	{171+85,  9,(171+25)+85,(  9+61)},//right arm
	{194+85,  2,(194+19)+85,(  2+51)},//right torso
	{209+85,187,(209+19)+85,(187+51)},//left torso
	{187+85,193,(187+21)+85,(193+61)},//center torso
	{0,0,0,0},						//blank rear?
	{187+85,171,(187+21)+85,(171+21)},//head
	{0,0,0,0},						//special1
	{0,0,0,0}						//special2
};

static const float sm1_offset[][2]={
	{29*2,35*2},		//leftleg
	{ 6*2,35*2},		//rightleg
	{43*2,11*2},		//leftarm
	{ 0*2,11*2},		//rightarm
	{12*2, 7*2},		//righttorso
	{33*2, 7*2},		//lefttorso
	{22*2,10*2},		//centertorso
	{ 0*2, 0*2},		//blank rear?
	{22*2, 0*2},		//head
	{ 0*2, 0*2},		//special1
	{ 0*2, 0*2},		//special2
};

//number: 0,1,2,3 lancemate order..
//part: mech part of the lancemate
//color: color for this part
void RenderAux1SmallMech(int num,int part,int color)
{
	//Draw according to each offset.
	if(sm1_texture[part][2]!=0){
		mfd_device.DrawTexture(
			sm1_offset[part][0]+190+num*160,
			sm1_offset[part][1]+50,
			color,
			sm1_texture[part][0],
			sm1_texture[part][1],
			sm1_texture[part][2],
			sm1_texture[part][3]
			);
	}
}
//80,240,400,560

static RECT aux1freeframes[]={
	{ 80-25, 75, 80+25, 75+25},
	{ 80-25,130, 80+25,130+25},

	{240-25, 75,240+25, 75+25},
	{240-25,130,240+25,130+25},

	{400-25, 75,400+25, 75+25},
	{400-25,130,400+25,130+25},

	{560-25, 75,560+25, 75+25},
	{560-25,130,560+25,130+25},

	{ 80-25,345, 80+25,345+25},
	{ 80-25,400, 80+25,400+25},

	{240-25,345,240+25,345+25},
	{240-25,400,240+25,400+25},

	{400-25,345,400+25,345+25},
	{400-25,400,400+25,400+25},

	{560-25,345,560+25,345+25},
	{560-25,400,560+25,400+25},
};

static POINT aux1free_textcoord[]={
	{ 80, 75},
	{ 80,130},

	{240, 75},
	{240,130},

	{400, 75},
	{400,130},

	{560, 75},
	{560,130},

	{ 80,345},
	{ 80,400},

	{240,345},
	{240,400},

	{400,345},
	{400,400},

	{560,345},
	{560,400},
};

// MSL 5.02 Comm MFD
static POINT aux1free_textcoord2[]={
	{ 80, 20},
	{240, 20},
	{400, 20},
	{560, 20},

	{ 80,460},
	{240,460},
	{400,460},
	{560,460},
};

static char mfd_text_comm1[8][32]={
	"TEAM ALL","","","",
	"ALL","ALL OTHERS","AFFIRMATIVE","NEGATIVE"
};

// MSL 5.02 Comm MFD
static char mfd_text_comm3[8][32]={
	"","","","",
	"","","","ALL",
};

enum {TEAMORDER_NONE, TEAM_MODE, FREEFORALL_MODE, TEAM_MESSAGE1, TEAM_MESSAGE2};

extern int g_nTeamOrderMode;
extern int g_TeamOrderCount;
extern int g_TeamOrderOthers;
extern SMechInfo g_aMechInfos[16];

static float coords[][4]={
	{ 29, 43, 49, 91},
	{  6, 43, 26, 92},
	{ 43, 11, 56, 42},
	{  0, 11, 12, 42},
	{ 12,  7, 22, 33},
	{ 33,  7, 43, 33},
	{ 22, 10, 33, 41},
	{  0,  0,  0,  0},
	{ 22,  0, 33, 10},
	{  0,  0,  0,  0},
	{  0,  0,  0,  0},
};


DWORD GetMechTeamColor(int nTeam)
{
    if ((nTeam < 0) || (8 <= nTeam)) {
        // no team or cameraship...
        return 0x00FFFFFF;
    } else {
        // 
        static DWORD g_dwaColors[8] = {
            0x000000FF, // blue
            0x00FF0000, // red
            0x00FFFF00, // yellow
            0x0000FF00, // green
            0x00FF00FF, // violet
            0x0000FFFF, // cyan
            0x00FFC000, // orange
            0x00C0C0C0, // gray
        };
        return g_dwaColors[nTeam];
    }
}
DWORD MakeBrightColor(DWORD c,DWORD v)
{
	DWORD r=((c>>16)&0xFF) +v;
	DWORD g=((c>>8)&0xFF) +v;
	DWORD b=((c)&0xFF)+v;
	if(r>0xFF)r=0xFF;
	if(g>0xFF)g=0xFF;
	if(b>0xFF)b=0xFF;
	return (r<<16) + (g<<8) + b;
}


Mech* GetTargetMech(Mech* pMech)
{
    if (pMech) {
        return pMech->m_Others[0].Get();
    }
	return NULL;
}

void HUDChat::DrawImplementation(void)
{
	if(!hsh_initialized){
#ifdef _DEBUG
		{
		int mech_count=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
		}
#endif

		if(!hsh_mrdev_initialized){
#ifdef _DEBUG
			Point3D loc,size;
			bool drawCurrent=false;
			MWApplication *app = MWApplication::GetInstance ();

			loc = Location ();
			Verify (comm);
			loc.y = comm->BottomY ();
			if (comm->LancemateSelected ())
				return;

			if (m_LargeSize)
				Size (Point3D (232,MAX_CHAT_LINES*15.0f*2,0.9f));
			else
				Size (Point3D (232,MAX_CHAT_LINES*15.0f,0.9f));
			size = Size ();

			DWORD bcolor = BrighterColor (Color ());
			DrawRect (loc,size,MakeColor (5,15,5,200));
			DrawFrame (loc,size,bcolor);

			loc.y += 2;
			loc.x += 2;
			size.x -= 4;
			Point3D r,s,rNext;
			r.z = 0.0f;
			DWORD chatx,chaty;
			stlport::list<ChatData>::iterator iter;

			r.x = loc.x;
			r.y = loc.y + size.y;
			if (m_CurrentChat)
			{
				char buf[MAX_HUD_TEXT*2];
				Verify (m_CursorPos);
				char temp;
				int posx,posy;
				if (m_TeamChat)
				{
					Str_Copy (buf,app->GetLocString (IDS_CHATHEADER2),MAX_HUD_TEXT*2);
				}
				else
				{
					Str_Copy (buf,app->GetLocString (IDS_CHATHEADER1),MAX_HUD_TEXT*2);
				}
				int nHeaderLen = strlen(buf);
				Str_Cat (buf,m_CurrentChat,MAX_HUD_TEXT*2);

				curChatDisplay->UpdateText (buf,false);
				drawCurrent = true;

				extern DWORD g_bDisableImeCompletely;
				if (g_bDisableImeCompletely) {
					curChatDisplay->TopLeft (loc.x,loc.y);
					curChatDisplay->BottomRight (r.x+size.x-2,r.y+size.y-2);
				}
				else {
					// Fix for #8264 (XPack #231). The cause was because of incorrect string width.
					// Clipping rectangle must be set before HUDText::DrawSize is called.
					// HUDText::DrawSize calculates string width with selected clipping rectangle
					// and caches it along with gos_DBCS object.
					curChatDisplay->TopLeft (0, 0);
					curChatDisplay->BottomRight (10000, 10000);
				}
				curChatDisplay->DrawSize (chatx,chaty);

				r.y = loc.y + size.y - chaty;

				if (g_bDisableImeCompletely)
				{
					curChatDisplay->Draw (r);
					if (m_CursorBlink)
					{
						int ts;
						ts = (int) curChatDisplay->Size ();
						DWORD linecolor = MakeColor (255,255,255,255);
						DWORD a,b;
						curChatDisplay->EndPos (a,b);
						posx = a+(int) r.x;
						posy = b+(int) r.y - 2;
						DrawLine (posx,posy,posx,posy-ts,linecolor);
					}
				}
				else
				{
					// Trim the string if it overflows the window - keep the chat string single line
					// this is to avoid problems in word wrapping
					static int IsKoreanCP = -1;
					if (IsKoreanCP == -1)
						IsKoreanCP = (GetACP() == 949 ? 1 : 0);
					bool bClipped = false;

					int iRightEnd = int(r.x + size.x - 2);
					while (true)
					{
						DWORD cx, cy;
						curChatDisplay->DrawSize( cx, cy );
						if (cx <= iRightEnd) {
							if (*m_CursorPos > *m_ChatLen)
								*m_CursorPos = *m_ChatLen;
							break;
						}
						bClipped = true;
						char* pszPrev = CharPrev(buf, buf + nHeaderLen + *m_ChatLen);
						*m_ChatLen = pszPrev - buf - nHeaderLen;
						*pszPrev = 0;
						m_CurrentChat[*m_ChatLen] = 0;
						curChatDisplay->UpdateText (buf,false,false);
					}
					if (IsKoreanCP && bClipped && *m_CursorPos == *m_ChatLen)
						gos_FinalizeStringIME();

					temp = buf[nHeaderLen + *m_CursorPos];
					buf[nHeaderLen + *m_CursorPos] = 0;

					curChatDisplay->UpdateText (buf,false,false);
					curChatDisplay->DrawSize (chatx,chaty);
					curChatDisplay->Draw (r);

					DWORD a,b;
					curChatDisplay->EndPos (a,b,false);
					int iFontX = (int)r.x, iFontY = (int)r.y;
					AdjustCoords(iFontX, iFontY);
					iFontX += (int)a;

					curChatDisplay->EndPos (a,b);
					posx = a+(int) r.x;
					posy = int(loc.y + size.y - chaty);	// assumption - single line chat
					if (m_CursorBlink && gos_GetMachineInformation(gos_Info_GetIMECaretStatus))
					{
						int ts;
						ts = (int) curChatDisplay->Size ();
						DWORD linecolor = MakeColor (255,255,255,255);
						DrawLine (posx,posy,posx,posy-ts,linecolor);
					}

					rNext.x = (float)posx;
					rNext.y = (float)posy;
					rNext.z = 0;
					buf[nHeaderLen + *m_CursorPos] = temp;
					curChatDisplay->UpdateText(buf + nHeaderLen + *m_CursorPos,false,false);
					curChatDisplay->DrawSize (chatx,chaty);
					gos_TextSetPosition(iFontX, iFontY);
					curChatDisplay->Draw (rNext, false);

		//			if (gos_GetMachineInformation(gos_Info_GetIMEStatus))
					{
						int left = int(loc.x);
						int top = int(loc.y);
						int right = int(loc.x+size.x-2);
						int bottom = int(loc.y+size.y-2);
						AdjustCoords(left, top, right, bottom);
						gos_TextSetRegion(left, top, right, bottom);
						extern float FontSize;
						float oldFontSize = FontSize;
						float fDummy = 0.0f;
						FontSize = (float)curChatDisplay->Size ();
						AdjustCoords(FontSize, fDummy);
						FontSize *= -1.333f;
						AdjustCoords(posx, posy);
						gos_PositionIME(posx, posy);
						FontSize = oldFontSize;
					}
				}
			}

			for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++)
			{
				iter->text->TopLeft (loc.x,loc.y);
				iter->text->BottomRight (loc.x+size.x-2,loc.y+size.y-2);
				iter->text->DrawSize (chatx,chaty);
				r.y -= chaty;
				iter->text->Draw (r);

				if (r.y < loc.y)
				{
					iter++;
					break;
				}
			}
			int i = 0;
			while ((iter != m_Messages.end ()) && (i != 15))				// save last ten chats
			{
				i++;
				iter++;
			}

			while (iter != m_Messages.end ())
			{
				delete iter->text;
				iter->text = NULL;
				iter = m_Messages.erase (iter);
			}
#endif
		}else {
			#ifdef _DEBUG
				bool draw_mr=true;
			#else
				bool draw_mr=CTCL_GetType()==_ECTCL_CameraShip;
			#endif

			if(draw_mr){
				//Draw mission review content.
			//_______________________________________________________________________________________________________
			//	
			//											Mech status and messages
			//_______________________________________________________________________________________________________
				if(!mr_device.map_loaded){
					comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));

					//Load map data for mr_device.
					extern char AssetsDirectory1[MAX_PATH];
					const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
					char temp[256];
					sprintf(temp, "%s\\hsh\\%s-1.bmp", AssetsDirectory1,model->m_HudMap);
					DrawBitmapToSurface(mr_device.pDDSMapTexture,0,0,temp);
					mr_device.map_loaded=true;
				}

				Mech* pFocusMech=g_aMechInfos[0].m_pMech;
				Entity* pET = VehicleInterface::GetInstance()-> observingEntity.GetCurrent();
				if (pET && pET->IsDerivedFrom(Mech::DefaultData))
					pFocusMech = Cast_Object(Mech*, pET);
				Mech* pTargetMech=GetTargetMech(pFocusMech);


				mr_device.pD3DDevice->SetTexture(0,0);
				//Draw Default Background;
				//mr_device.DrawMFDDefaultBackAux1(g_nTeamOrderMode);

				int mech_count=0;
				PMechInfo pMechInfos = &g_aMechInfos[0];
				{
					//Draw the name/Kill/Death stats of other mechs.
					mech_count=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
					g_TeamOrderCount=mech_count;
					if (mech_count > 8) // jcem
						mech_count = 8;

					int i,j;

					const char * callsign="";
					char score[16] ={0};
					char kill_death[16] ={0};

					HUDScore *hud = NULL;
					MWGUIManager *manager = MWGUIManager::GetInstance ();
					if (manager){
						if (manager->Component(MWGUIManager::HUD_SCORE)){
							hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
						}
					}

					for(i=0;i<mech_count;i++) {
						int row=i/4,col=i%4;
						int x=col*80+360;
						int y=row*140+20;
						Mech* pMech = pMechInfos->m_pMech;

						
						mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
						//Draw mech Damage status.
						for (j=0;j<11;j++){
							if (j==7 || j==9 || j==10)
								continue;
							int dv=pMech ->damageArray[j];//damage value
							if ( (0<=dv) && (dv<=5)){
								int off=(j<=1)?-8:0;
								mr_device.DrawTexture(coords[j][0]+x-30,coords[j][1]+y+off,SH_DamageColor2[dv],
									coords[j][0],coords[j][1],coords[j][2],coords[j][3]);
							}
						}

						//Draw mech Callsign/Score/Kills/Deaths.
						int nScore = 0, nKills = 0, nDeaths = 0;
						callsign=pMechInfos->m_pcszName;
						if (hud) {
							nScore = hud->GetScore4Player(*pMechInfos, nKills, nDeaths);
						}
						wsprintf(score,"Score:%d",nScore);
						wsprintf(kill_death,"%d/%d",nKills,nDeaths);

						//DrawCallSign..
						mr_device.pFont[1].DrawText((float)(x),(float)(y+90),0xFFFFFFFF,callsign,TEXTALIGN_ORG);
						mr_device.pFont[1].DrawText((float)(x),(float)(y+90+15),0xFFFFFFFF,score,TEXTALIGN_ORG);
						mr_device.pFont[1].DrawText((float)(x),(float)(y+90+30),0xFFFFFFFF,kill_death,TEXTALIGN_ORG);

						if(pFocusMech== pMech ){
							mr_device.pD3DDevice->SetTexture(0,0);
							///focused mech
							mr_device.DrawThickFrame(x-40,y-4,x+40,y+140-10,2,0xFFFFFF00); // in yellow
                        } else if(pFocusMech== pMech ){
							mr_device.pD3DDevice->SetTexture(0,0);
							///target of focused mech
							mr_device.DrawThickFrame(x-40,y-4,x+40,y+140-10,2,0xFFFF0000); // in red
						}
						pMechInfos++;
					}

					//Draw the contents of the chat window.
					stlport::list<ChatData>::iterator iter;
					int cy=300+30;//chat_y
					for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
						mr_device.pFont[3].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
						cy+=16;
						if (cy>(480-40-16)){
							iter++;
							break;
						}
					}

					i = 0;
					while ((iter != m_Messages.end ()) && (i != 15)){
						i++;
						iter++;
					}

					while (iter != m_Messages.end ()){
						delete iter->text;
						iter->text = NULL;
						iter = m_Messages.erase (iter);
					}
				}

				
				
				

			//_______________________________________________________________________________________________________
			//	
			//											Map
			//_______________________________________________________________________________________________________

				Check_Object(this);
				int i;

				// Secondary Maps
				//Draw map and boundary. (Drawn once since it does not change during game.)
					//DrawMapBoundary();//Implement alternate version...
				mr_device.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING ,TRUE);
				mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSMapTexture);
				mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
				mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,	D3DBLEND_SRCALPHA );
				mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
				mr_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER ,D3DTFG_LINEAR);
				mr_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER ,D3DTFG_LINEAR);

				//setup state bits
				//int state[12];
				//MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();


				//In mission review, current mech is shown at center so the map scrolls.
				float MR_MSF=4.0f;//Mission Review - Map Scale Factor	
				const float ViewSize=300.0f;//Mission Review - Map Size
				const float ViewLMargin=10;
				const float ViewTMargin=10;
				const float ViewHC=ViewSize/2+ViewLMargin;
				const float ViewVC=ViewSize/2+ViewTMargin;

				D3DVIEWPORT7 viewport={ViewLMargin,ViewTMargin,ViewSize,ViewSize,0.0f,1.0f};
				mr_device.pD3DDevice->SetViewport(&viewport);
				///////////////////// MAP BEGIN //////////////////////

				//Need to add routine to set Focus Mech.
				Scalar multx,multz;
				

				multx = MR_MSF*ViewSize/(MW4AI::MaxX - MW4AI::MinX);
				multz = MR_MSF*ViewSize/(MW4AI::MaxZ - MW4AI::MinZ);



				Stuff::Point3D pos_focus;
				pos_focus   = pFocusMech->GetLocalToWorld();
				pos_focus.y = pos_focus.z;

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

				Scalar l,r,t,b;
				l=pos_focus.x-MR_MSF*ViewSize/2+ViewHC;
				t=pos_focus.y-MR_MSF*ViewSize/2+ViewVC;
				r=pos_focus.x+MR_MSF*ViewSize/2+ViewHC;
				b=pos_focus.y+MR_MSF*ViewSize/2+ViewVC;
				mr_device.DrawTexture(l,t,r,b,0xFFFFFFFF,0,0,256,256);



				mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);

				//Draw mechs on map. Text first..
				for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
					Mech* pMech = pMechInfos->m_pMech;
					//TODO: get mech position..
					
					Stuff::Point3D pos;
					
					pos   = pMech->GetLocalToWorld();
					pos.y = pos.z;

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

					const char *callsign=pMechInfos->m_pcszName;

					int fontindex;
					DWORD color;
                    
                    if (pFocusMech==pMech) {
                        fontindex = 3;
                        color = 0xFFFFFF00;
                    } else if (pTargetMech==pMech) {
						//if this mech is target of focused mech then
                        fontindex = 1;
                        color = 0xFFFF0000;
                    } else {
                        fontindex = 1;
                        color = 0xFFFFFFFF;
                    }

					mr_device.pFont[fontindex].DrawText(
						(int)(pos_focus.x -pos.x+ViewHC),
						(int)(pos_focus.y -pos.y+ViewVC+8),
						0xFF000000,callsign,TEXTALIGN_HCENTER|TEXTALIGN_TOP);
					mr_device.pFont[fontindex].DrawText(
						(int)(pos_focus.x -pos.x+ViewHC-1),
						(int)(pos_focus.y -pos.y+ViewVC+8-1),
						color,callsign,TEXTALIGN_HCENTER|TEXTALIGN_TOP);

				}
				//Draw icon.
				for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
					Mech* pMech = pMechInfos->m_pMech;
					//TODO: get mech position..
					
					Stuff::Point3D pos;
					
					UnitVector3D vec;
					pMech->GetLocalToWorld ().GetLocalForwardInWorld (&vec);
					YawPitchRange ypr (vec);
					ypr.yaw -= Pi;

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

					pos.x = pos.x*multx;
					pos.y = pos.y*multz;
					DWORD mechcolor=GetMechTeamColor(pMechInfos->m_nTeam);
					mechcolor=MakeBrightColor(mechcolor,80);
					mechcolor|=0xFF000000;
					
                    /*
                    // jcem : MR Mech Image
                    // This block may draw focused mech but there is no actual image on mr_texture.bmp & mr_texturea.bmp
                    // & surrounding brackets too!!!

					if(pFocusMech==pMech){
						mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
							pos_focus.x -pos.x+ViewHC+1,
							pos_focus.y -pos.y+ViewVC+1,Pi - ypr.yaw,0xFFFFFFFF);
						mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
							pos_focus.x -pos.x+ViewHC-1,
							pos_focus.y -pos.y+ViewVC-1,Pi - ypr.yaw,0xFFFFFFFF);
						mr_device.DrawTextureRotate(82, 0, 98, 12, 90, 6,
							pos_focus.x -pos.x+ViewHC,
							pos_focus.y -pos.y+ViewVC,Pi - ypr.yaw,mechcolor);
					}else
                    */
                    {
						mr_device.DrawTextureRotate(65,0,79,10,72,5,
							pos_focus.x -pos.x+ViewHC,
							pos_focus.y -pos.y+ViewVC,Pi - ypr.yaw,mechcolor);
					}
                    /*
					if(pTargetMech==pMech){
						//if this mech is target of focused mech then
						mr_device.DrawTexture(
							(int)(pos_focus.x -pos.x+ViewHC-9),
							(int)(pos_focus.y -pos.y+ViewVC-9),
							0xFFFF8000,66,48,84,66);
					}
                    */
				}

				mr_device.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING ,FALSE);
				D3DVIEWPORT7 viewport2={0,0,640,480,0.0f,1.0f};
				mr_device.pD3DDevice->SetViewport(&viewport2);


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

				//_______________________________________________________________________________________________________
				//	
				//											Progress
				//_______________________________________________________________________________________________________


				//Draw mission timer... taken from DrawImplementation in hudtimer.cpp..
				MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
				Verify (mwmiss);
				Stuff::Scalar cur_time=mwmiss->GetMissionTime();//-mwmiss->GetMissionTime();
				Stuff::Scalar total_time=mwmiss->GetMissionDuration ();

				const int bar_width = 520;
				int progress=0;
				if(total_time>0){
					progress=(int)(bar_width *cur_time/total_time);
				}
				mr_device.pD3DDevice->SetTexture(0,0);
				mr_device.DrawQuad(100,454,100+progress+6,464,0xFFCCCCCC);
				mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
				mr_device.DrawTexture(progress+100,450,0xCCFFFFFF,66,17,79,40);
			}//draw_mr
		}//hsh_mrdev_initialized
	}else if(mfd_device.BeginChannel(0)){
		mfd_device.pD3DDevice->SetTexture(0,0);

		stlport::vector<MWObject *> lance;
		MW4AI::Groups::GetLancemates (lance);

		//Draw Default Background;
		mfd_device.DrawMFDDefaultBackAux1(g_nTeamOrderMode);

		if(g_nTeamOrderMode==TEAM_MODE){
			int i,j;
			int size=3;
			//Draw mech status.
			PMechInfo pMechInfos = &g_aMechInfos[1];
			size=MWApplication::GetInstance()->GetMechInfos(0, g_aMechInfos, g_TeamOrderOthers);
			size--;
			g_TeamOrderCount=size;
			if (size > 3) // jcem
				size = 3;

			for(i=1;i<4;i++)mfd_text_comm1[i][0]=0;


			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 );
			

			for (i=0;i<size;i++) {
				Mech* mech = pMechInfos->m_pMech;
				//Fill CallSign Texts
				strcpy(mfd_text_comm1[i+1],pMechInfos->m_pcszName);

				BOOL bShow = TRUE;
				if (g_pCurTOC && ((g_pCurTOC->m_nFrom == pMechInfos->connectionID) && mech->isPlayerVehicle)) {
					Scalar fT = (Scalar)gos_GetElapsedTime();
					fT -= g_fLastStartTime;
					fT /= (Scalar)1.0;
					fT -= floor(fT);
					if (fT >= 0.5) {
						bShow = FALSE;
					}
				}

				if (bShow) {
					for (j=0;j<11;j++){
						if (j==7 || j==9 || j==10)
							continue;
						int dv=mech->damageArray[j];//damage value
						if (( dv <= 5) && (dv>=0)){
							RenderAux1SmallMech(i,j, SH_DamageColor[dv]);
						}
					}
				}
				pMechInfos++;
			}
			mfd_device.DrawMFDBackText(mfd_text_comm1);
			//Draw the contents of the chat window.
			stlport::list<ChatData>::iterator iter;
			int cy=240;//chat_y
			for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
// MSL 5.02 Comm MFD Font Change
				mfd_device.pFont[0].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
				cy+=22;
				if (cy>(440-22)){
					iter++;
					break;
				}
			}

			i = 0;
			while ((iter != m_Messages.end ()) && (i != 15)){
				i++;
				iter++;
			}

			while (iter != m_Messages.end ()){
				delete iter->text;
				iter->text = NULL;
				iter = m_Messages.erase (iter);
			}

		}else if(g_nTeamOrderMode==FREEFORALL_MODE){
			//Draw the name/Kill/Death stats of other mechs.
			int size=0;
			PMechInfo pMechInfos = &g_aMechInfos[1];
			size=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
			size--;
			g_TeamOrderCount=size;
			if (size > 7) // jcem
				size = 7;

			int i;
			//Clear the numbers first.
// MSL 5.03 Comm MFD
			for(i=0;i<7;i++)mfd_text_comm3[i][0]=0;
			//Fill in the numbers.
// MSL 5.03 Comm MFD
			for(i=0;i<size;i++)itoa(i+1,mfd_text_comm3[i],10);

// MSL 5.03 Comm MFD
			mfd_device.DrawMFDBackText(mfd_text_comm3);
			mfd_device.DrawThickFrameList(size*2,aux1freeframes,2,0xFFFFFFFF);

			POINT* p=aux1free_textcoord;
			POINT* p2=aux1free_textcoord2;
			RECT * r=aux1freeframes;
			int x,y;

            MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
            Verify (mwmiss);
            const MechWarrior4::CBucketManager& bm = *mwmiss->m_BucketManager;
		
			const char * callsign="";
			char kills[16]={0};
			char deaths[16]={0};

			HUDScore *hud = NULL;
			MWGUIManager *manager = MWGUIManager::GetInstance ();
			if (manager)
			{
				if (manager->Component(MWGUIManager::HUD_SCORE))
				{
					hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
				}
			}

			for(i=0;i<size;i++) {
				//Mech* pMech = pMechInfos->m_pMech;

				int nScore = 0, nKills = 0, nDeaths = 0;
				callsign=pMechInfos->m_pcszName;
				nScore = bm.RelativeGetScore4Player(g_aMechInfos[0], *pMechInfos, nKills, nDeaths);
				//itoa(nScore,score,10);
				itoa(nKills,kills,10);
				itoa(nDeaths,deaths,10);

				//DrawCallSign..
				SIZE size;
				mfd_device.pFont[2].GetTextExtent(callsign,&size);
				if(size.cx<160){
					mfd_device.pFont[2].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
				}else{
					mfd_device.pFont[3].GetTextExtent(callsign,&size);
					if(size.cx<160){
						mfd_device.pFont[3].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
					}else{
						mfd_device.pFont[1].GetTextExtent(callsign,&size);
						if(size.cx<160){
							mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
						}else{
							//Even the minimum font size is exceeded...
							//Split into 2 lines.
							char callsign2[128];
							strcpy(callsign2,callsign);
							int len2=strlen(callsign)/2;
							char save=callsign2[len2];
							callsign2[len2]=0;
							mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0XFFFFFFFF,callsign2,TEXTALIGN_CENTER|TEXTALIGN_BOTTOM);
							callsign2[len2]=save;
							mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0XFFFFFFFF,callsign2+len2,TEXTALIGN_CENTER|TEXTALIGN_TOP);

						}
					}
				}
				p2++;
				//Draw "Kill"
// MSL 5.02 Comm MFD
				mfd_device.pFont[2].DrawText((float)p->x,(float)p->y,0xFFFFFFFF,"YOUR DEATHS",TEXTALIGN_BOTTOM|TEXTALIGN_CENTER);
				p++;
				//Draw "Death"
// MSL 5.02 Comm MFD
				mfd_device.pFont[2].DrawText((float)p->x,(float)p->y,0xFFFFFFFF,"YOUR KILLS",TEXTALIGN_BOTTOM|TEXTALIGN_CENTER);
				p++;
				//Draw Kill
				x=(r->left+r->right)/2;
				y=(r->top+r->bottom)/2;
// MSL 5.02 Comm MFD
				char minus[16]="";
//				if (nKills == 0)
//				{
					sprintf(minus, "%d", nKills);
//				}
//				else
//				{
//					sprintf(minus, "-%d", nKills);
//				}
				mfd_device.pFont[0].DrawText((float)x,(float)y,0xFFFFFFFF,minus,TEXTALIGN_ORG);
				r++;
				//Draw Death
				x=(r->left+r->right)/2;
				y=(r->top+r->bottom)/2;
// MSL 5.02 Comm MFD
				char plus[16]="";
//				if (nDeaths == 0)
//				{
					sprintf(plus, "%d", nDeaths);
//				}
//				else
//				{
//					sprintf(plus, "+%d", nDeaths);
//				}
				mfd_device.pFont[0].DrawText((float)x,(float)y,0xFFFFFFFF,plus,TEXTALIGN_ORG);
				r++;

				pMechInfos++;
			}
			//Draw the contents of the chat window.
			stlport::list<ChatData>::iterator iter;
			int cy=180;//chat_y
			for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
// MSL 5.02 Comm MFD Font Change
				mfd_device.pFont[0].DrawText(10,(float)cy,0xFFFFFFFF,iter->text->hsh_get_m_Text(),0);
				cy+=22;
				if (cy>(300-22)){
					iter++;
					break;
				}
			}

			i = 0;
			while ((iter != m_Messages.end ()) && (i != 15)){
				i++;
				iter++;
			}

			while (iter != m_Messages.end ()){
				delete iter->text;
				iter->text = NULL;
				iter = m_Messages.erase (iter);
			}
	/*
			//Taken from MWMission.cpp
			MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());

			int death=0,kill=0;//,score
			if(MWPlayer::GetInstance()){
				Check_Object(MWPlayer::GetInstance());

				if(MWPlayer::GetInstance()->vehicle){
					ScoreObject *score_object = mwmiss->GetScoreMember(MWPlayer::GetInstance()->vehicle->GetReplicatorID());
					if(score_object){
						 death=score_object->GetDeaths();
						 kill=score_object->GetKills();
						 //score=score_object->
					}
				}
			}
	*/
		}else if(g_nTeamOrderMode==TEAM_MESSAGE1){
			;//do nothing
		}else if(g_nTeamOrderMode==TEAM_MESSAGE2){
			;//do nothing
		}
		//sanghoon end
		mfd_device.EndChannel();
	} else {
	}//hsh_initialized
}


