/* 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 "debugtools.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("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("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("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("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("Color pair: already allocated\n");
         return x;  
      }    
   }

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

#endif /* WINE_NCURSES */
