//-----------------------------------------------------------------------------------------------
// Console.hpp
//
#pragma once
#ifndef INCLUDED_CONSOLE
#define INCLUDED_CONSOLE
#include "Engine/Core/PlatformDefines.hpp"
#if defined( GYPSY_ENABLE_CONSOLE )

//-----------------------------------------------------------------------------------------------
#include "Engine/Core/EngineSubsystem.hpp"


//-----------------------------------------------------------------------------------------------
class BitmapFont;


/////////////////////////////////////////////////////////////////////////////////////////////////
enum ConsoleDisplayMode
{
	CONSOLE_DISPLAY_MODE_HIDDEN,
	CONSOLE_DISPLAY_MODE_MINIMAL,
	CONSOLE_DISPLAY_MODE_FULL,
	NUM_CONSOLE_LOG_DISPLAY_MODES
};


/////////////////////////////////////////////////////////////////////////////////////////////////
class ConsoleTextLine
{
public:
	ConsoleTextLine()
		: m_color( Rgba::WHITE )
		, m_absoluteTimePrinted( 0.0 )
	{}

private:
	Rgba			m_color;
	std::string		m_text;
	double			m_absoluteTimePrinted;

	friend class Console;
};


/////////////////////////////////////////////////////////////////////////////////////////////////
class Console : public EngineSubsystem
{
public:
	virtual void SetDefaultFont( BitmapFont* defaultFont );
	virtual void SetConsoleCapacity( int maxTextLines );
	virtual void PrintChars( const Rgba& textColor, const char* text );
	virtual void Printf( const Rgba& textColor, const char* messageFormat, ... );
	virtual void Printf( const char* messageFormat, ... );
	virtual void SetConsoleDisplayMode( ConsoleDisplayMode consoleDisplayMode );
	virtual void ToggleFullConsole();
	virtual void ToggleMinimalConsole();
	virtual void ClearCommandLine();
	virtual void ExecuteCommandString( const std::string& commandStringToExecute );

protected:
	Console();
	virtual ~Console();
	static void Create();
	virtual void StartUp();
	virtual void EndFrame();
	virtual bool ProcessSystemEventPreGame( const SystemEvent& systemEvent );

	virtual void RestartCursorTiming();
	virtual void ScrollConsoleLogForwardToCurrentPosition();
	virtual void ScrollConsoleLogBackToBeginningOfContent();
	virtual void ScrollConsoleLog( int numLinesToScrollBack );
	virtual void MoveCursorToLeft();
	virtual void MoveCursorToRight();
	virtual void MoveCursorToBeginningOfLine();
	virtual void MoveCursorToEndOfLine();
	virtual void DeleteCharacterToLeftOfCursor();
	virtual void DeleteCharacterToRightOfCursor();
	virtual void OnHomeInConsole();
	virtual void OnEndInConsole();
	virtual void OnEnterInConsole();
	virtual void OnEscapeInConsole();
	virtual void OnTildeInConsole();
	virtual bool IsTypeableUnicodeCharacter( unsigned int unicodeCharacterUTF32 );
	virtual bool IsTypeableLatinCharacter( unsigned char latinChar );
	virtual void TypeUnicodeCharacter( unsigned int unicodeCharacterUTF32 );
	virtual void TypeLatinCharacter( unsigned char latinChar );
	virtual void ExecuteAndEmptyCommandLine();

	virtual void BeginRendering();
	virtual void EndRendering();
	virtual void RenderFull();
	virtual void RenderMinimal();
	virtual void RenderCommandPrompt();
	virtual void PrintfV( const Rgba& textColor, const char* messageFormat, va_list args );
	virtual void PrintLine( const Rgba& textLineColor, const char* textLine );

protected:
	ConsoleDisplayMode				m_displayMode;
	BitmapFont*						m_defaultFont;
	std::vector< ConsoleTextLine >	m_logTextLines;
	int								m_mostRecentTextLineIndex;
	int								m_numLinesScrolledBack;
	int								m_consoleLogCapacity;
	float							m_linesOnScreenVertically;
	std::string						m_commandInputContents;
	int								m_commandInputCursorPos;
	double							m_timeBlinkStarted;
	float							m_secondsToHoldMinimalTextLine;
	float							m_secondsToFadeMinimalTextLine;

	friend void ConsolePrintf( const char* messageFormat, ... );
	friend void ConsolePrintf( const Rgba& color, const char* messageFormat, ... );
	friend class Application;
};


//-----------------------------------------------------------------------------------------------
extern Console* theConsole;



#endif // GYPSY_ENABLE_CONSOLE
#endif // INCLUDED_CONSOLE
