///////////////////////////////////////////////////////////////////////////////
/// @file deConsole.cpp
///
/// @brief "stdout" console
///
/// @author Assassin
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date July 2001
/// @author Assassin
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <wincon.h>
#include "deConsole.hpp"
#include <cstdio>

HANDLE StdOut;
bool ConsoleActive;

void deConsole_MakeConsole()
{
	AllocConsole();
	StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
	ConsoleActive = true;
}

void deConsole_DestroyConsole()
{
	ConsoleActive = false;
	FreeConsole();
}

bool deConsoleColor(ConsoleColor_t fore, ConsoleColor_t back)
{
	WORD ForeFlags=0, BackFlags=0;

	if (!ConsoleActive)
		return false;

	switch (fore)
	{
	case Black:
		break;
	case DarkRed:
		ForeFlags = FOREGROUND_RED;
		break;
	case LightRed:
		ForeFlags = FOREGROUND_RED | FOREGROUND_INTENSITY;
		break;
	case DarkGreen:
		ForeFlags = FOREGROUND_GREEN;
		break;
	case LightGreen:
		ForeFlags = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case DarkBlue:
		ForeFlags = FOREGROUND_BLUE;
		break;
	case LightBlue:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
		break;
	case Brown:
		ForeFlags = FOREGROUND_RED | FOREGROUND_GREEN;
		break;
	case Yellow:
		ForeFlags = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case DarkCyan:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_GREEN;
		break;
	case LightCyan:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	case Purple:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_RED;
		break;
	case Pink:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
		break;
	case Gray:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN;
		break;
	case White:
		ForeFlags = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
		break;
	}
	switch (back)
	{
	case Black:
		break;
	case DarkRed:
		BackFlags = BACKGROUND_RED;
		break;
	case LightRed:
		BackFlags = BACKGROUND_RED | BACKGROUND_INTENSITY;
		break;
	case DarkGreen:
		BackFlags = BACKGROUND_GREEN;
		break;
	case LightGreen:
		BackFlags = BACKGROUND_GREEN | BACKGROUND_INTENSITY;
		break;
	case DarkBlue:
		BackFlags = BACKGROUND_BLUE;
		break;
	case LightBlue:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_INTENSITY;
		break;
	case Brown:
		BackFlags = BACKGROUND_RED | BACKGROUND_GREEN;
		break;
	case Yellow:
		BackFlags = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
		break;
	case DarkCyan:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_GREEN;
		break;
	case LightCyan:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
		break;
	case Purple:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_RED;
		break;
	case Pink:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
		break;
	case Gray:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN;
		break;
	case White:
		BackFlags = BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
		break;
	}
	SetConsoleTextAttribute(StdOut, (WORD)(ForeFlags | BackFlags));

	return true;
}

bool deConsoleOut(const char * text, ...)
{
	static char buffer[2048];
	va_list arglist;
	DWORD written;

	if (!ConsoleActive)
		return false;

	va_start(arglist,text);
//	vprintf(text, arglist);
	_vsnprintf(buffer, 2048, text, arglist);
	va_end(arglist);
	buffer[2047] = '\0';

	WriteConsole(StdOut, buffer, strlen(buffer), &written, NULL);

	return true;
}

void deConsoleXY(int X, int Y)
{
	static COORD position;

	if (!ConsoleActive)
		return;

	position.X = (short)X;
	position.Y = (short)Y;
	SetConsoleCursorPosition(StdOut, position);
}
