#include <exec/io.h>
#include <exec/memory.h>
#include <exec/lists.h>
#include <libraries/dos.h>
#include <devices/console.h>
#include <ctype.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <intuition/intuition.h>

BYTE bConsoleOpened = FALSE;

static struct IOStdReq  *hWriteReq;
static struct MsgPort   *hWritePort;
static struct IOStdReq  *hReadReq;
static struct MsgPort   *hReadPort;

#ifdef XDC_EXTENDED_CONSOLE

#define RESETCON	"\033c"
#define CURSOFF		"\033[0 p"
#define CURSON		"\033[p"

#define COLOR02		"\033[32m"
#define COLOR03		"\033[33m"
#define ITALICS		"\033[3m"
#define BOLD		"\033[1m"
#define UNDERLINE	"\033[4m"
#define NORMAL		"\033[0m"

void ConPutChar(struct IOStdReq *hWriteReq, UBYTE character)
{
    if (!bConsoleOpened) return;

	hWriteReq -> io_Command = CMD_WRITE;
	hWriteReq -> io_Data = (APTR) &character;
	hWriteReq -> io_Length = 1;
	DoIO((struct IORequest *) hWriteReq);
}

void ConWrite(struct IOStdReq *hWriteReq, UBYTE string, LONG length)
{ 
    if (!bConsoleOpened) return;

	hWriteReq -> io_Command = CMD_WRITE;
	hWriteReq -> io_Data = (APTR) string;
	hWriteReq -> io_Length = length;
	DoIO((struct IORequest *) hWriteReq);
}
#endif

void ConPutS(char *str)
{
	if (!bConsoleOpened) return;

    hWriteReq -> io_Command = CMD_WRITE;
	hWriteReq -> io_Data = (APTR) str;
	hWriteReq -> io_Length = -1;
	DoIO((struct IORequest *) hWriteReq);
}

void CloseConsole(void)
{
    if (bConsoleOpened)
    {
        bConsoleOpened = FALSE;
        CloseDevice((struct IORequest *) hWriteReq);
    }

    if (hReadReq)
    {
        DeleteExtIO((struct IORequest *) hReadReq);
        hReadReq = NULL;
    }

    if (hReadPort)
    {
        DeletePort(hReadPort);
        hReadPort = NULL;
    }

    if (hWriteReq)
    {
        DeleteExtIO((struct IORequest *) hWriteReq);
        hWriteReq = NULL;
    }

    if (hWritePort)
    {
        DeletePort(hWritePort);
        hWritePort = NULL;
    }
}

BOOL InitConsole(Window *hWnd)
{ 
    // Create Reply Port and IOReq for writing
    if (!(hWritePort = CreatePort("__console.write",NULL))) goto _InitFailed;
    if (!(hWriteReq = (struct IOStdReq *) CreateExtIO(hWritePort, (LONG)sizeof(struct IOStdReq)))) goto _InitFailed;

    // Create Reply Port and IOReq for reading
    if (!(hReadPort = CreatePort("__console.read",NULL))) goto _InitFailed;
    if (!(hReadReq = (struct IOStdReq *) CreateExtIO(hReadPort, (LONG)sizeof(struct IOStdReq)))) goto _InitFailed;

    // Attach a console to the console window
	hWriteReq -> io_Data = (APTR) hWnd;
	hWriteReq -> io_Length = sizeof(struct Window);
	
    // Open console device
    if (!(bConsoleOpened = (OpenDevice("console.device", 0, (struct IORequest *) hWriteReq,0) ? FALSE : TRUE))) goto _InitFailed;
	hReadReq -> io_Device = hWriteReq -> io_Device;
	hReadReq -> io_Unit = hWriteReq -> io_Unit;
    return TRUE;

_InitFailed:
    CloseConsole();
    return FALSE;
}

