/*
 * GOATTRACKER "console" output routines
 */

#define MAX_COLUMNS 80
#define MAX_ROWS 25

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bme.h"
#include "gsound.h"

int initscreen(void);
void closescreen(void);
void clearscreen(void);
void fliptoscreen(void);
void printtext(int x, int y, int color, const unsigned char *text);
void printtextc(int y, int color, const unsigned char *text);
void printblank(int x, int y, int length);
void printblankc(int x, int y, int color, int length);
void printbg(int x, int y, int color, int length);
void drawbox(int x, int y, int color, int sx, int sy);
void getkey(void);

Uint8 chardata[4096];

short *scrbuffer;
int key = 0;
int rawkey = 0;
int virtualkey = 0;
int shiftpressed = 0;
int lasttime = 0;
int currenttime = 0;
int framecounter = 0;
int cursorflashdelay = 0;

static int gfxinitted = 0;

int initscreen(void)
{
  int handle;

  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0)
  {
          return BME_ERROR;
  }
  atexit(SDL_Quit);
  win_windowinitted = 1;
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
  SDL_EnableUNICODE(1);
  SDL_WM_SetCaption("GoatTracker", NULL);
  win_fullscreen = 0;

  handle = io_open("chargen.bin");
  if (handle != -1)
  {
    io_read(handle, &chardata[0], 4096);
    io_close(handle);
  }
  else return 0;

  if (!gfx_init(640, 400, 60, 0)) return 0;
  gfx_loadpalette("palette.bin");
  gfx_calcpalette(64,0,0,0);
  gfx_setpalette();

  scrbuffer = malloc(MAX_COLUMNS * MAX_ROWS * 2 * sizeof(short));

  if (!scrbuffer) return 0;

  gfxinitted = 1;
  clearscreen();
  return 1;
}

void closescreen(void)
{
  if (scrbuffer)
  {
    free(scrbuffer);
    scrbuffer = NULL;
  }

  gfxinitted = 0;
}

void clearscreen(void)
{
  int c;
  short *dptr = scrbuffer;

  if (!gfxinitted) return;

  for (c = 0; c < MAX_ROWS * MAX_COLUMNS; c++)
  {
    *dptr++ = 0x20;
    *dptr++ = 0x7;
  }
}

void printtext(int x, int y, int color, const unsigned char *text)
{
  short *dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  while (*text)
  {
    *dptr++ = *text;
    *dptr++ = color;
    text++;
  }
}

void printblank(int x, int y, int length)
{
  short *dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  while (length--)
  {
    *dptr++ = 32;
    *dptr++ = 0;
  }
}

void printblankc(int x, int y, int color, int length)
{
  short *dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  while (length--)
  {
    *dptr++ = 32;
    *dptr++ = color;
  }
}

void drawbox(int x, int y, int color, int sx, int sy)
{
  short *dptr;
  short *dptr2;
  int counter;

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  if (y+sy > MAX_ROWS) return;

  dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);
  dptr2 = scrbuffer + (((x+sx-1) + y * MAX_COLUMNS) << 1);
  counter = sy;

  while (counter--)
  {
    dptr[0] = '|';
    dptr[1] = color;
    dptr2[0] = '|';
    dptr2[1] = color;
    dptr += (MAX_COLUMNS << 1);
    dptr2 += (MAX_COLUMNS << 1);
  }

  dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);
  dptr2 = scrbuffer + ((x + (y+sy-1) * MAX_COLUMNS) << 1);
  counter = sx;
  while (counter--)
  {
    *dptr++ = '-';
    *dptr++ = color;
    *dptr2++ = '-';
    *dptr2++ = color;
  }

  /* scrbuffer[(x + y * MAX_COLUMNS) << 1] = '+';
  scrbuffer[((x+sx-1) + y * MAX_COLUMNS) << 1] = '+';
  scrbuffer[(x + (y+sy-1) * MAX_COLUMNS) << 1] = '+';
  scrbuffer[((x+sx-1) + (y+sy-1) * MAX_COLUMNS) << 1] = '+'; */
}

void printbg(int x, int y, int color, int length)
{
  short *dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  while (length--)
  {
    dptr++;
    *dptr = 15 | (color << 4);
    dptr++;
  }
}

void printtextc(int y, int color, const unsigned char *text)
{
  int x = (80 - strlen(text)) / 2;
  short *dptr = scrbuffer + ((x + y * MAX_COLUMNS) << 1);

  if (!gfxinitted) return;
  if (y < 0) return;
  if (y >= MAX_ROWS) return;
  while (*text)
  {
    *dptr++ = *text;
    *dptr++ = color;
    text++;
  }
}

void fliptoscreen(void)
{
  short *sptr = scrbuffer;
  int x,y,c,d;
  if (!gfxinitted) return;

  for (y = 0; y < MAX_ROWS; y++)
  {
    for (x = 0; x < MAX_COLUMNS; x++)
    {
      int ch = *sptr++;
      int color = *sptr++;
      int fgcolor = color & 15;
      int bgcolor = color >> 4;
      for (c = 0; c < 16; c++)
      {
        Uint8 e = chardata[ch*16+c];
        Uint8 *dptr = &gfx_vscreen[(y*16+c)*640+x*8];
        for (d = 0; d < 8; d++)
        {
          if (e & 128) *dptr++ = fgcolor;
          else *dptr++ = bgcolor;
          e <<= 1;
        }
      }
    }
  }
  gfx_updatepage();
}

void getkey(void)
{
  int c;
  win_asciikey = 0;
  win_getspeed(50);
  key = win_asciikey;
  rawkey = 0;
  for (c = 0; c < MAX_KEYS; c++)
  {
    if (win_keytable[c])
    {
      if ((c != KEY_LEFTSHIFT) && (c != KEY_RIGHTSHIFT) &&
          (c != KEY_CTRL) && (c != KEY_RIGHTCTRL))
      {
        rawkey = c;
        win_keytable[c] = 0;
        break;
      }
    }
  }
  shiftpressed = 0;
  if ((win_keystate[KEY_LEFTSHIFT])||(win_keystate[KEY_RIGHTSHIFT])||
      (win_keystate[KEY_CTRL])||(win_keystate[KEY_RIGHTCTRL]))
    shiftpressed = 1;

  if (rawkey == SDLK_KP0) key = '0';
  if (rawkey == SDLK_KP1) key = '1';
  if (rawkey == SDLK_KP2) key = '2';
  if (rawkey == SDLK_KP3) key = '3';
  if (rawkey == SDLK_KP4) key = '4';
  if (rawkey == SDLK_KP5) key = '5';
  if (rawkey == SDLK_KP6) key = '6';
  if (rawkey == SDLK_KP7) key = '7';
  if (rawkey == SDLK_KP8) key = '8';
  if (rawkey == SDLK_KP9) key = '9';

  cursorflashdelay++;
}

