#pragma once

#include "ehs/Str.h"
#include "ehs/UTF.h"
#include "ehs/Array.h"

namespace ehs
{
    #if defined(EHS_OS_WINDOWS)
        typedef void* ConsoleHdl;
    #elif defined(EHS_OS_LINUX)
        typedef int ConsoleHdl;
    #endif

	class Console
	{
	private:
		static ConsoleHdl hdlOut;
		static ConsoleHdl hdlIn;

        #if defined(EHS_OS_WINDOWS)
            static bool isConsole;
        #endif

	public:
        static void Attach();

	    /// Creates a console using standard input and output.
	    /// @param [in] inputRequired Whether or not input is required from the console.
		static bool Create();

        /// Frees the current console being used.
		static void Free();

        static bool CanRead();

        static bool CanWrite();

		/// Writes to console using UTF32.
		/// @param [in] str The text to write to the console.
		/// @param [in] newLine To make a new line after the given text.
		/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
		static void Write_32(const Str_32& str, const bool newLine = true);

        /// Writes to console using UTF16.
        /// @param [in] str The text to write to the console.
        /// @param [in] newLine To make a new line after the given text.
		static void Write_16(const Str_16& str, const bool newLine = true);

        /// Writes to console using UTF8.
        /// @param [in] str The text to write to the console.
        /// @param [in] newLine To make a new line after the given text.
        /// @warning Has to convert from UTF8 to UTF16 for the Windows API.
		static void Write_8(const Str_8& str, const bool newLine = true);

		/// Reads from the console using UTF32.
		/// @returns The text the user wrote to the console.
		/// @warning Has to convert from UTF16 to UTF32 for the Windows API.
		static Str_32 Read_32(const UInt_64 bufferSize = 1024);

        /// Reads from the console using UTF16.
        /// @returns The text the user wrote to the console.
		static Str_16 Read_16(const UInt_64 bufferSize = 1024);

        /// Reads from the console using UTF8.
        /// @returns The text the user wrote to the console.
        /// @warning Has to convert from UTF8 to UTF16 for the Windows API.
		static Str_8 Read_8(const UInt_64 bufferSize = 1024);

        /// Clears the console.
        static void Clear();

		/// Changes the console's title.
		/// @param [in] title The text to change the title to.
		/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
		static void SetTitle_32(const Str_32& title);

        /// Changes the console's title.
        /// @param [in] title The text to change the title to.
        static void SetTitle_16(const Str_16& title);

        /// Changes the console's title.
        /// @param [in] title The text to change the title to.
        /// @warning Has to convert from UTF8 to UTF16 for the Windows API.
        static void SetTitle_8(const Str_8& title);

        /// Retrieves the console's title in UTF32.
        /// @returns The console's title.
        /// @warning Has to convert from UTF16 to UTF32 for the Windows API.
		static Str_32 GetTitle_32();

        /// Retrieves the console's title in UTF16.
        /// @returns The console's title.
        static Str_16 GetTitle_16();

        /// Retrieves the console's title in UTF8.
        /// @returns The console's title.
        /// @warning Has to convert from UTF16 to UTF8 for the Windows API.
        static Str_8 GetTitle_8();

        /// Retrieves the string used when executing the end application through a command line interface in UTF32.
        /// @returns The result.
        static Vector<Str_32> GetArgs_32(const UInt_64 bufferSize = 1024);

        /// Retrieves the string used when executing the end application through a command line interface in UTF16.
        /// @returns The result.
        static Vector<Str_16> GetArgs_16(const UInt_64 bufferSize = 1024);

        /// Retrieves the string used when executing the end application through a command line interface in UTF8.
        /// @returns The result.
        static Vector<Str_8> GetArgs_8(const UInt_64 bufferSize = 1024);

        //static void* GetHandle();
	};
}