/* interface.c */

/* The primary purpose of this function is to provide CONSOLE_*
   reotines that immediately call the appropiate driver handler.
   This cleans up code in the individual modules considerably.
   This could be done using a macro, but additional functionality
   may be provided here in the future. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "config.h"
#include "windef.h"
#include "console.h"
#include "options.h"

CONSOLE_device driver;

static int pop_driver(char **, char **, int *);

static int console_initialized = FALSE;

int CONSOLE_Init(char *drivers)
{
      /* When this function is called drivers should be a string
         that consists of driver names followed by plus (+) signs
         to denote additions. 

         For example:
            drivers = tty                Load just the tty driver
            drivers = ncurses+xterm      Load ncurses then xterm

         The "default" value is just tty.
      */
      
      char *single;
      int length;
      char initial_rows[5];
      char initial_columns[5];

      /* Suitable defaults... */
      driver.console_out = stdout;
      driver.console_in = stdin;

      while (pop_driver(&drivers, &single, &length))
      {
         if (!strncmp(single, "tty", length))
            TTY_Start();
#ifdef WINE_NCURSES
         else if (!strncmp(single, "ncurses", length))
            NCURSES_Start();
#endif /* WINE_NCURSES */
         else if (!strncmp(single, "xterm", length))
            XTERM_Start();
      }

   /* Read in generic configuration */
   /* This is primarily to work around a limitation in nxterm where
      this information is not correctly passed to the ncurses layer
      through the terminal. At least, I'm not doing it correctly if there
      is a way. But this serves as a generic way to do the same anyway. */

   /* We are setting this to 80x25 here which is *not* the default for
      most xterm variants... It is however the standard VGA resolution */

   /* FIXME: We need to be able to be able to specify that the window's
      dimensions should be used. This is required for correct emulation
      of Win32's console and Win32's DOS emulation */

   PROFILE_GetWineIniString("console", "InitialRows",
      "24", initial_rows, 5);
   PROFILE_GetWineIniString("console", "InitialColumns",
      "80", initial_columns, 5);

   sscanf(initial_rows, "%d", &driver.y_res);
   sscanf(initial_columns, "%d", &driver.x_res);
   
   GENERIC_Start();

   if (driver.init)
      driver.init();

   /* Not all terminals let our programs know the proper resolution
      if the resolution is set on the command-line... */
   CONSOLE_NotifyResizeScreen(driver.x_res, driver.y_res);

   /* For now, always return TRUE */
   return TRUE;
}

void CONSOLE_Write(char out, int fg_color, int bg_color, int attribute)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.write)
   {
      driver.write(out, fg_color, bg_color, attribute);
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

void CONSOLE_Close()
{
   if (driver.close)
      driver.close();
}

void CONSOLE_MoveCursor(char row, char col)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.moveCursor)
   {
      driver.moveCursor(row, col);
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

void CONSOLE_ClearWindow(char row1, char col1, char row2, char col2, 
   int bg_color, int attribute)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.clearWindow)
   {
      driver.clearWindow(row1, col1, row2, col2, bg_color, attribute);
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

void CONSOLE_ScrollUpWindow(char row1, char col1, char row2, char col2, 
   char lines, int bg_color, int attribute)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.scrollUpWindow)
   {
      driver.scrollUpWindow(row1, col1, row2, col2, lines, bg_color, 
         attribute);
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

void CONSOLE_ScrollDownWindow(char row1, char col1, char row2, char col2, 
   char lines, int bg_color, int attribute)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.scrollDownWindow)
   {
      driver.scrollDownWindow(row1, col1, row2, col2, lines, bg_color, 
         attribute);
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

int CONSOLE_CheckForKeystroke(char *scan, char *ascii)
/* These functions need to go through a conversion layer. Scancodes
   should *not* be determined by the driver, rather they should have
   a conv_* function in int16.c. Yuck. */
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.checkForKeystroke)
      return driver.checkForKeystroke(scan, ascii);
   else
      return FALSE;
}

void CONSOLE_GetKeystroke(char *scan, char *ascii)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.getKeystroke)
      driver.getKeystroke(scan, ascii);
}

void CONSOLE_GetCursorPosition(char *row, char *col)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.getCursorPosition)
      driver.getCursorPosition(row, col);
}

void CONSOLE_GetCharacterAtCursor(char *ch, int *fg, int *bg, int *a)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.getCharacterAtCursor)
      driver.getCharacterAtCursor(ch, fg, bg, a);
}

void CONSOLE_Refresh()
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.refresh)
      driver.refresh();
}

int CONSOLE_AllocColor(int color)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.allocColor)
      return driver.allocColor(color);
   else 
      return 0;
}

void CONSOLE_ClearScreen()
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.clearScreen)
   {
      driver.clearScreen();
      if (!driver.norefresh)
         CONSOLE_Refresh();
   }
}

char CONSOLE_GetCharacter()
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   /* I'm not sure if we need this really. This is a function that can be
      accelerated that returns the next *non extended* keystroke */
   if (driver.getCharacter)
      return driver.getCharacter();
   else
      return (char) 0; /* Sure, this will probably break programs... */
}

void CONSOLE_ResizeScreen(int x, int y)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.resizeScreen)
      driver.resizeScreen(x, y);
}

void CONSOLE_NotifyResizeScreen(int x, int y)
{
   if (driver.notifyResizeScreen)
      driver.notifyResizeScreen(x, y);
}

void CONSOLE_SetBackgroundColor(int fg, int bg)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.setBackgroundColor)
      driver.setBackgroundColor(fg, bg);
}

void CONSOLE_GetBackgroundColor(int *fg, int *bg)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   if (driver.getBackgroundColor)
      driver.getBackgroundColor(fg, bg);
}

void CONSOLE_WriteRawString(char *str)
{
   if (!console_initialized)
      console_initialized = CONSOLE_Init(driver.driver_list);
      
   /* This is a special function that is only for internal use and 
      does not actually call any of the console drivers. It's 
      primary purpose is to provide a way for higher-level drivers
      to write directly to the underlying terminal without worry that
      there will be any retranslation done by the assorted drivers. Care
      should be taken to ensure that this only gets called when the thing
      written does not actually produce any output or a CONSOLE_Redraw()
      is called immediately afterwards.
      CONSOLE_Redraw() is not yet implemented.
   */
   fprintf(driver.console_out, "%s", str);
}

/* This function is only at the CONSOLE level. */
/* Admittably, calling the variable norefresh might be a bit dumb...*/
void CONSOLE_SetRefresh(int setting)
{
   if (setting)
      driver.norefresh = FALSE;
   else
      driver.norefresh = TRUE;
}

/* This function is only at the CONSOLE level. */
int CONSOLE_GetRefresh()
{
   if (driver.norefresh)
      return FALSE;
   else 
      return TRUE;
}


/* Utility functions... */

int pop_driver(char **drivers, char **single, int *length)
{
   /* Take the string in drivers and extract the first "driver" entry */
   /* Advance the pointer in drivers to the next entry, put the origional
      pointer in single, and put the length in length. */
   /* Return TRUE if we found one */

   if (!*drivers)
      return FALSE;

   *single = *drivers;
   *length = 0;

   while ((*drivers[0] != NULL) && (*drivers[0] != '+'))
   {
      (*drivers)++;
      (*length)++;
   }
   
   while (*drivers[0] == '+')
      (*drivers)++;

   if (*length)
      return TRUE;
   else
      return FALSE;
      
}
