/* ncurses.c */
/* Copyright 1999 - Joseph Pranevich */

#include <stdio.h>
#include "config.h"
#include "console.h"	/* Must define WINE_NCURSES */

#ifdef WINE_NCURSES

/* This is the console driver for systems that support the ncurses
   interface. 
*/

/* Actually, this should work for curses, as well. But there may be
   individual functions that are unsupported in plain curses or other
   variants. Those should be detected and special-cased by autoconf. 
*/

/* When creating new drivers, you need to assign all the functions that
   that driver supports into the driver struct. If it is a supplementary
   driver, it should make sure to perserve the old values. 
*/

#include "debug.h"
#include "options.h"

DEFAULT_DEBUG_CHANNEL(console)

#undef ERR /* Use ncurses's err() */
#ifdef HAVE_NCURSES_H
# include <ncurses.h>
#else
# ifdef HAVE_CURSES_H
#  include <curses.h>
# endif
#endif

SCREEN *ncurses_screen;

static int get_color_pair(int fg_color, int bg_color);

const char *color_names[] = {"null", "black", "blue", "green",
   "cyan", "magenta", "brown", "red", "light gray", "dark gray",
   "light blue", "light green", "light red", "light magenta",
   "light cyan", "yellow", "white"};

void NCURSES_Start()
{
   /* This should be the root driver so we can ignore anything
      already in the struct. */

   driver.norefresh = FALSE;

   driver.init = NCURSES_Init;
   driver.write = NCURSES_Write;
   driver.close = NCURSES_Close;
   driver.moveCursor = NCURSES_MoveCursor;
   driver.getCursorPosition = NCURSES_GetCursorPosition;
   driver.getCharacterAtCursor = NCURSES_GetCharacterAtCursor;
   driver.clearScreen = NCURSES_ClearScreen;
   driver.allocColor = NCURSES_AllocColor;
#ifdef HAVE_GETBKGD
   driver.setBackgroundColor = NCURSES_SetBackgroundColor;
#endif   
#ifdef HAVE_RESIZETERM
   driver.notifyResizeScreen = NCURSES_NotifyResizeScreen;
#endif /* HAVE_RESIZETERM */

   driver.checkForKeystroke = NCURSES_CheckForKeystroke;
   driver.getKeystroke = NCURSES_GetKeystroke;

   driver.refresh = NCURSES_Refresh; 
}

void NCURSES_Init()
{
   char terminal_type[80];

   PROFILE_GetWineIniString("console", "TerminalType",
      "xterm", terminal_type, 79);

   ncurses_screen = newterm(terminal_type, driver.console_out,
      driver.console_in);
   set_term(ncurses_screen);
   start_color();
   raw();
   noecho();
   nonl();
   intrflush(stdscr, FALSE);
   keypad(stdscr, TRUE);
   nodelay(stdscr, TRUE);
}

void NCURSES_Write(char output, int fg, int bg, int attribute)
{
   char row, col;
   int pair;
   
   if (!fg)
      fg = COLOR_WHITE; /* Default */

   if (!bg)
      bg = COLOR_BLACK; /* Default */

   pair = get_color_pair(fg, bg);

   if (waddch(stdscr, output | COLOR_PAIR(pair)) == ERR)
   {
      NCURSES_GetCursorPosition(&row, &col);
      FIXME(console, "NCURSES: waddch() failed at %d, %d.\n", row, col);
   }
}

void NCURSES_Close()
{
   endwin();
}

void NCURSES_GetKeystroke(char *scan, char *ascii)
{
   while (!NCURSES_CheckForKeystroke(scan, ascii))
   {} /* Wait until keystroke is detected */
   
   /* When it is detected, we will already have the right value 
      in scan and ascii, but we need to take this keystroke
      out of the buffer. */
   wgetch(stdscr);
}

int NCURSES_CheckForKeystroke(char *scan, char *ascii)
{
   /* We don't currently support scan codes here */
   /* FIXME */
   int temp;
   temp = wgetch(stdscr);
   if (temp == ERR)
   {
      return FALSE;
   }
   else
   {
      ungetch(temp);  /* Keystroke not removed from buffer */
      *ascii = (char) temp;
      return TRUE;
   }
}

void NCURSES_MoveCursor(char row, char col)
{
   if (wmove(stdscr, row, col) == ERR)
      FIXME(console, "NCURSES: wmove() failed to %d, %d.\n", row, col);
}

void NCURSES_GetCursorPosition(char *row, char *col)
{
   int trow, tcol;

   getyx(stdscr, trow, tcol); /* MACRO, no need to pass pointer */

   *row = (char) trow;
   *col = (char) tcol;
}

void NCURSES_GetCharacterAtCursor(char *ch, int *fg_color, int
   *bg_color, int *attribute)
{
   /* If any of the pointers are NULL, ignore them */
   /* We will eventually have to convert the color data */
   if (ch)
      *ch = (char) winch(stdscr);
   if (fg_color)
      *fg_color = WINE_WHITE;
   if (bg_color)
      *bg_color = WINE_BLACK;
   if (attribute)
      *attribute = 0;
};

void NCURSES_Refresh()
{
   wrefresh(stdscr);
}

void NCURSES_ClearScreen()
{
   werase(stdscr);
}

int NCURSES_AllocColor(int color)
{
   /* Currently support only internal colors */
   switch (color)
   {
      case WINE_BLACK:		return COLOR_BLACK;
      case WINE_WHITE:		return COLOR_WHITE;
      case WINE_RED:		return COLOR_RED;
      case WINE_GREEN:		return COLOR_GREEN;
      case WINE_YELLOW:		return COLOR_YELLOW;
      case WINE_BLUE:     	return COLOR_BLUE;
      case WINE_MAGENTA:	return COLOR_MAGENTA;
      case WINE_CYAN:		return COLOR_CYAN;
   }

   FIXME(console, "Unable to allocate color %d (%s)\n", color,
      color_names[color]);

   /* Don't allocate a color... yet */
   return 0;
}

void NCURSES_SetBackgroundColor(int fg, int bg)
{
   int pair;

   pair = get_color_pair(fg, bg);

   wbkgd(stdscr, COLOR_PAIR(pair));
}

#ifdef HAVE_GETBKGD
void NCURSES_GetBackgroundColor(int *fg, int *bg)
{
   chtype background;
   short pair, sfg, sbg;
     
   background = getbkgd(stdscr);

   pair = (!A_CHARTEXT & background);
   
   pair_content(pair, &sfg, &sbg);

   *fg = sfg;
   *bg = sbg;
}
#endif /* HAVE_GETBKGD */

#ifdef HAVE_RESIZETERM

void NCURSES_NotifyResizeScreen(int x, int y)
{
   /* Note: This function gets called *after* another driver in the chain
      calls ResizeScreen(). It is meant to resize the ncurses internal
      data structures to know about the new window dimensions. */
 
   TRACE(console, "Terminal resized to y: %d, x: %d\n", y, x);

   resizeterm(y, x);
}

#endif /* HAVE_RESIZETERM */

static int get_color_pair(int fg_color, int bg_color)
{
   /* ncurses internally uses "color pairs" in addition to the "pallet" */
   /* This isn't the best way to do this. Or even close */

   static int current = 0;
   static int fg[255];     /* 16 x 16 is enough */
   static int bg[255];
   int x;

   /* The first pair is hardwired into ncurses */
   fg[0] = COLOR_WHITE;
   bg[0] = COLOR_BLACK;

   for (x = 0; x <= current; x++)
   {
      if ((fg_color == fg[x]) && (bg_color == bg[x]))
      {
         TRACE(console, "Color pair: already allocated\n");
         return x;  
      }    
   }

   /* Need to allocate new color */
   current++;
   fg[current] = fg_color;
   bg[current] = bg_color;
   TRACE(console, "Color pair: allocated.\n");
   return init_pair(current, fg_color, bg_color);
}

#endif /* WINE_NCURSES */
