/* Zortech Flash Graphics specific version of display routines.  All
   drawing is in white - need a RGB to 16 color conversion routine... */
#include <conio.h>
#include <fg.h>
#include "def.h"
#include "disp.h"

#define TEST_ABORT if (kbhit() && getch() == 27) { display_close(0); exit(1); }

static float X_Display_Scale = 1.0;
static float Y_Display_Scale = 1.0;
int maxx = 320;
int maxy = 200;

static fg_box_t clipbox;

/* Scale from image size to actual screen pixel size */
static void
rescale_coord(x, y)
   int *x, *y;
{
   float xt, yt;

   yt = maxy / 2 + Y_Display_Scale * *y;
   xt = maxx / 2 + X_Display_Scale * *x;

   *x = (xt < 0.0 ? 0 : (xt > maxx ? maxx - 1 : (int)xt));
   *y = (yt < 0.0 ? 0 : (yt > maxy ? maxy - 1 : (int)yt));
}

void
display_clear(void)
{
   /* Clear the screen using a box the size of the screen. */
   fg_fillbox(FG_BLACK, FG_MODE_SET, ~0, fg.displaybox);
}

void
display_init(xres, yres)
   int xres, yres;
{
   int x, y;
   COORD4 white;

   /* Ignore the resolution and make the display 640x480 in 16 colors. */
   fg_init_vga12();

   maxx = 640;
   maxy = 480;

   /* Scale the display to fit onto the screen */
   X_Display_Scale = (xres > maxx ? (float)maxx / (float)xres : 1.0);
   Y_Display_Scale = (yres > maxy ? (float)maxy / (float)yres : 1.0);
   if (X_Display_Scale < Y_Display_Scale)
      Y_Display_Scale = X_Display_Scale;
   else if (Y_Display_Scale < X_Display_Scale)
      X_Display_Scale = Y_Display_Scale;

   /* Make the clipping box for the display */
   x = -xres/2; y = -yres/2;
   rescale_coord(&x, &y);
   clipbox[FG_X1] = x;
   clipbox[FG_Y1] = y;
   x = xres/2; y = yres/2-1;
   rescale_coord(&x, &y);
   clipbox[FG_X2] = x;
   clipbox[FG_Y2] = y;

   /* Outline the actual "visible" display area in the window */
   SET_COORD(white, 1, 1, 1);
   display_line(-xres/2, -yres/2, -xres/2, yres/2-1, &white);
   display_line( xres/2-1, -yres/2,  xres/2-1, yres/2-1, &white);
   display_line(-xres/2,  yres/2-1,  xres/2-1,  yres/2-1, &white);
   display_line(-xres/2, -yres/2,  xres/2-1, -yres/2, &white);
}

void
display_close(int wait_flag)
{
   if (wait_flag) {
#if !defined( _WINDOWS )
      while (!kbhit()) ;
#endif
      if (!getch()) getch();
      }

   /* Turn off graphics mode */
   fg_term();
}

void
display_plot(x, y, color)
   int x, y;
   COORD4 *color;
{
   int xp, yp;

   xp = x; yp = y;
   rescale_coord(&xp, &yp);

   /* Insert code to plot a single pixel here */
   fg_drawdot(FG_WHITE, FG_MODE_SET, ~0, xp, yp);
}

void
display_line(x0, y0, x1, y1, color)
   int x0, y0, x1, y1;
   COORD4 *color;
{
   float xt, yt;
   int xs, ys, xe, ye;
   fg_line_t line1;

   TEST_ABORT

   xs = x0; ys = y0; xe = x1; ye = y1;
   rescale_coord(&xs, &ys);
   rescale_coord(&xe, &ye);

   /* Make a line out of the end points */
   fg_make_line(line1, xs, ys, xe, ye);

   /* Clip against the view */
   fg_drawlineclip(FG_WHITE, FG_MODE_SET, ~0, FG_LINE_SOLID,
		   line1, clipbox);
}
