/*****************************************************************************

        GRAOUMF TRACKER 2
        Author: Laurent de Soras, 1996-2016

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

*****************************************************************************/



#define WIN32_LEAN_AND_MEAN
#define NOGDI
#define NOMINMAX

#include	"pc.h"

#include	<Windows.h>



int	OS_key_pressed (void)
{
	::HANDLE	console;
	::INPUT_RECORD	buffer;
	::DWORD		nbr;

	console = ::GetStdHandle (STD_INPUT_HANDLE);
	for ( ; ; )
	{
		::PeekConsoleInputA (console, &buffer, 1, &nbr);
		if (nbr <= 0)
		{
			break;
		}

		/* On ne s'interesse qu'aux entrees clavier, touches enfoncees */
		if (buffer.EventType == KEY_EVENT)
		{
			if (buffer.Event.KeyEvent.bKeyDown)
			{
				break;
			}
		}

		/* Efface l'evenement courant du buffer d'entree */
		::ReadConsoleInputA (console, &buffer, 1, &nbr);
	}

	return (nbr > 0);
}



int	OS_get_key (void)
{
	int		key;
	::HANDLE	console;
	::INPUT_RECORD	buffer;
	::DWORD		nbr;

	console = ::GetStdHandle (STD_INPUT_HANDLE);
	for ( ; ; )
	{
		::ReadConsoleInputA (console, &buffer, 1, &nbr);
		if (buffer.EventType == KEY_EVENT)
		{
			if (buffer.Event.KeyEvent.bKeyDown)
			{
				break;
			}
		}
	}
	key = buffer.Event.KeyEvent.uChar.AsciiChar;

	switch (buffer.Event.KeyEvent.wVirtualScanCode)
	{
	case	0x01:	key = 0x01;	break;	/* Esc */
	case	0x1C:	key = 0x02;	break;	/* Enter */
	case	0x48:	key = 0x03;	break;	/* Up */
	case	0x50:	key = 0x04;	break;	/* Down */
	case	0x4B:	key = 0x05;	break;	/* Left */
	case	0x4D:	key = 0x06;	break;	/* Right */
	case	0x52:	key = 0x07;	break;	/* Insert */
	case	0x53:	key = 0x08;	break;	/* Delete */
	default:
		if (key >= 59 && key <= 68)
		{
			key = key - 59 + 20;
		}
	}

	return (key);
}



void	OS_clear_screen (void)
{
	::HANDLE	console;
	const ::COORD	coord =
	{
		OS_NBR_COLUMNS, OS_NBR_LINES
	};
	const ::COORD	topleft = { 0, 0 };
	const ::SMALL_RECT	rect =
	{
		0, 0,
		OS_NBR_COLUMNS - 1, OS_NBR_LINES - 1
	};
	::DWORD	bidon;

	console = ::GetStdHandle (STD_OUTPUT_HANDLE);
	::SetConsoleScreenBufferSize (console, coord);
	::SetConsoleWindowInfo (console, true, &rect);
	::FillConsoleOutputCharacterA (console, ' ', OS_NBR_COLUMNS * OS_NBR_LINES, topleft, &bidon);
}



void	OS_locate (int x, int y)
{
	::HANDLE	console;
	::COORD		coord;

	coord.X = x - 1;
	coord.Y = y - 1;
	console = ::GetStdHandle (STD_OUTPUT_HANDLE);
	::SetConsoleCursorPosition (console, coord);
}



void	OS_print (char	*text_0)
{
	HANDLE	console;
	DWORD		nbr;

	console = ::GetStdHandle (STD_OUTPUT_HANDLE);
	::WriteConsoleA (console, text_0, ::DWORD (strlen (text_0)), &nbr, 0);
}



void	OS_print_at (int x, int y, char *text_0)
{
	OS_locate (x, y);
	OS_print (text_0);
}