/*

	File	: console.cpp
	Author  : Richard Flower (c) 1998 Core Design
	----------------------------------------------------------------------------------
	Functions
	----------------------------------------------------------------------------------

	CSLaunch	-	Launch Console
	CSShutDown	-	ShutDown Console
	CSDisplay	-	Display Console

	----------------------------------------------------------------------------------
*/


#include "standard.h"
#include "console.h"
#include "directx.h"
#include "confuncs.h"
#include "winmain.h"

CONSOLE Console;


/*
	Function : CSLaunch
	Useage	 : Launch Console
*/


bool CSLaunch(HWND hWnd,LPDIRECTDRAW2 lpDD,char* Filename,LPDIRECTDRAWSURFACE3 lpDestSurface)
{
	HDC hdc;
	DDSURFACEDESC ddsd;
    HBITMAP Bitmap;
    BITMAP  bm;
	

	DXInit(ddsd);
	lpDestSurface->GetSurfaceDesc(&ddsd);

	Console.lpBitmapSurface = NULL;

	Bitmap = NULL;
	memset(&Console,0,sizeof(CONSOLE));

	// Use Fixed System Font, Get Text Metrics
	hdc = GetDC(hWnd);
	SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
	GetTextMetrics(hdc,&Console.tm);
	ReleaseDC(hWnd,hdc);
	
	if(Filename!=NULL)
	{
		// Load Image File
		Bitmap = (HBITMAP) LoadImage(NULL,Filename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);
		GetObject(Bitmap,sizeof(bm),&bm);
	}
	
	Console.w    = ddsd.dwWidth;
	Console.h    = ddsd.dwHeight/2;

	if(Bitmap != NULL)
	{
		//if(Console.w > bm.bmWidth)
			//Console.h = bm.bmHeight*(Console.w/bm.bmWidth);
	}
	else
		Console.h = ddsd.dwHeight;

	Console.rows = Console.h/Console.tm.tmHeight;
	
	Console.lpBackBuffer = lpDestSurface;
	Console.lpDD		 = lpDD;
		
	// Increment References

	lpDestSurface->AddRef();
	lpDD->AddRef();

	// Create Console Surface
	DXInit(ddsd);
	ddsd.dwFlags        = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
	ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OWNDC;
	ddsd.dwWidth        = Console.w;
	ddsd.dwHeight       = Console.rows*Console.tm.tmHeight;

	DXCreateSurface(lpDD,&ddsd,&Console.lpConsoleSurface);
	
	// Open Console Background

    HDC BitmapDC;
    HDC	SurfaceDC;

	if(Bitmap != NULL)
	{
		DXCreateSurface(lpDD,&ddsd,&Console.lpBitmapSurface);
		
		BitmapDC = CreateCompatibleDC(NULL);
		SelectObject(BitmapDC,Bitmap);
		Console.lpBitmapSurface->GetDC(&SurfaceDC);
		StretchBlt(SurfaceDC,0,0,Console.w,Console.rows*Console.tm.tmHeight,BitmapDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
		Console.lpBitmapSurface->ReleaseDC(SurfaceDC);
		DeleteDC(BitmapDC);
		DeleteObject(Bitmap);
	}

	Console.bActivated = false;

	Console.lpConsoleSurface->GetDC(&Console.hdc);
    SelectObject(Console.hdc,GetStockObject(SYSTEM_FIXED_FONT));
	SetBkColor(Console.hdc,RGB(0,0,0));
	SetTextColor(Console.hdc,RGB(0,64,150)) ;
	SetBkMode(Console.hdc,TRANSPARENT);

	DDCOLORKEY ck;
	ck.dwColorSpaceLowValue  = 0;
    ck.dwColorSpaceHighValue = 0;
	Console.lpConsoleSurface->SetColorKey(DDCKEY_SRCBLT,&ck);
	return true;
}

// EOF : CSLaunch



/*
	Function : CSShutDown
	Useage	 : Shut Down Console
*/

void CSShutDown()
{
	Console.bRunning = false;		
	DXRelease(Console.lpBackBuffer);
	DXRelease(Console.lpConsoleSurface);
	DXRelease(Console.lpBitmapSurface);
	DXRelease(Console.lpDD);
}

// EOF : CSShutDown


/*
	Function : CSDisplay
	Useage	 : Display Console
*/

void CSDisplay()
{
	RECT r,s;
	static bool flag;
	static int Row = 0;//Console.rows*Console.tm.tmHeight;
		
	if(Console.bActivated) 
		flag = true;
	else 
		flag = false;
	
	// To
	r.left   = 0;
	r.top    = 0;
	r.bottom = 0+Row;
	r.right  = Console.w;

	// From
	s.left	 = 0;
	s.top	 = Console.rows*Console.tm.tmHeight-Row;
	s.bottom = Console.rows*Console.tm.tmHeight;
	s.right  = Console.w;

	if(flag)
	{
		Row+=16;
		if(Row>=Console.tm.tmHeight*Console.rows)
			Row = Console.rows*Console.tm.tmHeight;
		}
		else
		{
			Row-=16;
			if(Row<=0)
				Row = 0;
		
		}

		if(Row != 0)
		{
			if(Console.lpBitmapSurface!=NULL)
				Console.lpBackBuffer->Blt(&r,Console.lpBitmapSurface,&s,DDBLT_WAIT,NULL);
			
			Console.lpBackBuffer->Blt(&r,Console.lpConsoleSurface,&s,DDBLT_WAIT|DDBLT_KEYSRC,NULL);
			ConsoleCursor();
		}
}

// EOF : CSDisplay




void ConsoleOutput(int col,char* string)
{
	TextOut(Console.hdc,col*Console.tm.tmAveCharWidth,(Console.rows-1)*Console.tm.tmHeight,string,strlen(string)); 
}

void ConsoleCursor()
{
   if(!Console.bActivated) return;
	
   RECT s;
   s.left = (Console.CommandCol+1)*Console.tm.tmAveCharWidth;
   s.top  = (Console.rows-1)*(Console.tm.tmHeight);
   s.bottom = Console.rows*Console.tm.tmHeight;
   s.right  = s.left+Console.tm.tmAveCharWidth;

   static bFlag = 0;
   int c;
   DDBLTFX	fx;
   memset(&fx,0,sizeof(DDBLTFX));

   c = (GetTickCount()/100)&0x1;

   if(c != 0)
   {
	   fx.dwFillColor = DXRGB(App.DeviceInfoPtr,App.DXConfigPtr,0,0,0);
   }
   else
   {
  		fx.dwFillColor = DXRGB(App.DeviceInfoPtr,App.DXConfigPtr,0,128,200);
   }
   fx.dwSize = sizeof(DDBLTFX);
   Console.lpConsoleSurface->Blt(&s,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);
   ConsoleOutput(0,">");
}



void ClearConsoleCursor()
{
   RECT s;
   s.left = (Console.CommandCol+1)*Console.tm.tmAveCharWidth;
   s.top  = (Console.rows-1)*(Console.tm.tmHeight);
   s.bottom = Console.rows*Console.tm.tmHeight;
   s.right  = s.left+Console.tm.tmAveCharWidth;

   DDBLTFX	fx;
   memset(&fx,0,sizeof(DDBLTFX));
   fx.dwSize = sizeof(DDBLTFX);
   fx.dwFillColor = RGB(0,0,0);
   Console.lpConsoleSurface->Blt(&s,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);
}



void ClearConsole()
{
   // Clear Console Background
   DDBLTFX	fx;
   memset(&fx,0,sizeof(DDBLTFX));
   fx.dwSize = sizeof(DDBLTFX);
   fx.dwFillColor = RGB(0,0,0);
   Console.lpConsoleSurface->Blt(NULL,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);
}



void KeyToConsole(int nKey)
{

	if(!Console.bActivated) return;

	nKey = tolower(nKey);
	
	if(Console.CommandCol > DEF_COMMANDLEN-2)
		Console.CommandCol--;

	if(nKey == 13)
	{
		ClearCommandLine();
		ClearConsoleCursor();
		SubmitCommand();
		memset(&Console.CommandLine[0],0,DEF_COMMANDLEN);		
		Console.CommandCol = 0;
		ConsoleOutput(0,">");
		return;
	}

	if(nKey == 8)
	{
		Console.CommandCol--;
		Console.CommandLine[Console.CommandCol] = 0;
		if(Console.CommandCol<0) Console.CommandCol = 0;

		ClearCommandLine();
		ConsoleOutput(1,&Console.CommandLine[0]);
		ConsoleOutput(0,">");
		return;
	}
	if(nKey>=32 && nKey<=128)
		sprintf(&Console.CommandLine[Console.CommandCol],"%c",nKey);
	else
		return;

    SetBkMode(Console.hdc,OPAQUE);
	ConsoleOutput(1,&Console.CommandLine[0]);
    SetBkMode(Console.hdc,TRANSPARENT);

	Console.CommandCol++;
}



void ConsoleOutput1(int col,char* string)
{
	TextOut(Console.hdc,col*Console.tm.tmAveCharWidth,(Console.rows-2)*Console.tm.tmHeight,string,strlen(string)); 
}



void ConsolePrintf(char *fmt, ...)
{
	va_list		argptr;
	char		msg[4096];
	va_start (argptr,fmt);
	vsprintf (msg,fmt,argptr);
	va_end (argptr);
	ConsoleOutput1(0,msg);
	ScrollConsole1();
}



void ClearCommandLine()
{
	RECT s;
	s.left = 0;
	s.top  = (Console.rows-1)*(Console.tm.tmHeight);
	s.bottom = Console.rows*Console.tm.tmHeight;
	s.right  = Console.w;

	DDBLTFX	fx;
	memset(&fx,0,sizeof(DDBLTFX));
	fx.dwSize = sizeof(DDBLTFX);
	fx.dwFillColor = RGB(0,0,0);
	Console.lpConsoleSurface->Blt(&s,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);
}


void ClearLine(int row)
{
	RECT s;
	s.left = 0;
	s.top  = (row)*(Console.tm.tmHeight);
	s.bottom = (row+1)*Console.tm.tmHeight;
	s.right  = Console.w;

	DDBLTFX	fx;
	memset(&fx,0,sizeof(DDBLTFX));
	fx.dwSize = sizeof(DDBLTFX);
	fx.dwFillColor = RGB(0,0,0);
	Console.lpConsoleSurface->Blt(&s,NULL,NULL,DDBLT_COLORFILL|DDBLT_WAIT,&fx);
}



void ScrollConsole()
{
	RECT s,d;
	s.left = 0;
	s.top  = Console.tm.tmHeight;
	s.bottom = Console.rows*Console.tm.tmHeight;
	s.right  = Console.w;

	d.left = 0;
	d.top  = 0;
	d.bottom = (Console.rows-1)*(Console.tm.tmHeight);
	d.right  = Console.w;
	
	Console.lpConsoleSurface->Blt(&d,Console.lpConsoleSurface,&s,DDBLT_WAIT,NULL);
	ClearCommandLine();
}



void ScrollConsole1()
{
	RECT s,d;
	s.left = 0;
	s.top  = Console.tm.tmHeight;
	s.bottom = (Console.rows-1)*Console.tm.tmHeight;
	s.right  = Console.w;

	d.left = 0;
	d.top  = 0;
	d.bottom = (Console.rows-2)*(Console.tm.tmHeight);
	d.right  = Console.w;
	
	Console.lpConsoleSurface->Blt(&d,Console.lpConsoleSurface,&s,DDBLT_WAIT,NULL);
	ClearLine(Console.rows-2);
}


void SubmitCommand()
{
	int n;
	char string[80];
	int bValid;

		
	// Scroll Up Command
	ScrollConsole();

	if(strlen(Console.CommandLine) == 0) return;
	
	// Execute Console Command

	bValid = FALSE;
	for(n=0;n<sizeof(Console_Functions)/sizeof(CONSOLE_COMMAND);n++)
	{	
		strncpy(string,Console.CommandLine,strlen(Console_Functions[n].command_text));
		string[strlen(Console_Functions[n].command_text)] = 0;
		if(!strcmp(string,Console_Functions[n].command_text))		
		{
			ConsolePrintf("%s",Console.CommandLine);
			
			Console.CommandLen = strlen(Console_Functions[n].command_text);
			(*Console_Functions[n].command_ptr)(&Console.CommandLine[0]+strlen(Console_Functions[n].command_text)+1);
			bValid = TRUE;
			break;
		}
	}	

	if(bValid == FALSE)
	{
		sprintf(string,"Unknown Command - '%s'",Console.CommandLine);
		ConsolePrintf("%s",string);
	}
}



void ToggleConsole()
{
	if(Console.bActivated)
	{
		Console.bActivated = false;
		ClearConsoleCursor();
	}
	else
		Console.bActivated = true;
}





void console_help(char* CommandLine)
{
	char string [256];
	int n;
	int col;
	col = 0;
	
	ConsolePrintf("Command Summary");
	ConsolePrintf("---------------");

	for(n=0;n<sizeof(Console_Functions)/sizeof(CONSOLE_COMMAND);n++)
	{	
		sprintf(string,"%s",Console_Functions[n].command_text);
		ConsoleOutput1(col,string);
		col += strlen(string)+1;
		if(col > DEF_COMMANDLEN-15)
		{
			col = 0;
			ScrollConsole();
		}
	}	
	ScrollConsole();
}




