#include "vogle.h"
#include <graph.h>

extern unsigned int _cur_color;

static void iswap( int*, int* );

#define TRUE 0
#define FALSE 1

static int pageswap_OK = FALSE;

void vega_clear()
{
  _setbkcolor( _cur_color );
  _clearscreen( _GCLEARSCREEN );
#ifdef DEBUG
  printf("vega_clear() current color: %d\n",(int)_cur_color);
#endif
}

int zsetup()
{
  struct videoconfig VC;

  _getvideoconfig( &VC );
  if ( VC.adapter != _EGA && VC.adapter != _VGA && VC.adapter != _SVGA ) {
    printf("Unknown video adapter: %d",VC.adapter);
    return(0);
  }
  if ( VC.numvideopages >= 2 ) 
    pageswap_OK= TRUE;
  return(1);
}

void egaline( int xf, int yf, int xt, int yt, int color )
{
  short tmpcolor;

#ifdef CHECK_LINE
  /* 
    check if points are outside physical boundaries of screen
    and if they are adjust their positions accordingly
  */
  if ( (xf < 0 && xt < 0) || (xf > vdevice.sizeSx && xt > vdevice.sizeSx) )
    return;
  if ( (yf < 0 && yt < 0) || (yf > vdevice.sizeSy && yt > vdevice.sizeSy) )
    return;

  if ( xf > xt ) {
    iswap( &xt, &xf );
    iswap( &yt, &yf );
  }

  if ( xf < 0 && yf >= 0 && yf <= vdevice.sizeSy ) {
    yf= yf + (-xf+1)*(yt-yf)/(xt-xf);
    xf= 0;
  } else if ( yf < 0 ) {
    xf= xf + (-yf+1)*(xt-xf)/(yt-yf);
    yf= 0;
  } else if ( yf > vdevice.sizeSy ) {
    xf= xf + (vdevice.sizeSy-yf+1)*(xt-xf)/(yt-yf);
    yf= vdevice.sizeSy;
  }

  if ( xt > vdevice.sizeSx && yf >= 0 && yf <= vdevice.sizeSy ) {
    yt= yf + (vdevice.sizeSx-xf)*(yt-yf)/(xt-xf);
    xt= vdevice.sizeSx;
  } else if ( yt < 0 ) {
    xt= xf + (-yf+1)*(xt-xf)/(yt-yf);
    yt= 0;
  } else if ( yt > vdevice.sizeSy ) {
    xt= xf + (vdevice.sizeSy-yf+1)*(xt-xf)/(yt-yf);
    yt= vdevice.sizeSy;
  }
#endif
  /*
    OK- now draw the resulting line...
  */
  tmpcolor= _getcolor();
  _setcolor( (short) color );
  _moveto( (short) xf, (short) yf );
  _lineto( (short) xt, (short) yt );
  _setcolor( tmpcolor );
#ifdef DEBUG
  printf("egaline- xf:%3d yf:%3d xt:%3d yt:%3d c:%3d cc:%3d\n",xf,yf,xt,yt,color,(int)_cur_color);
#endif
}

void egalchar( int x, int y, int c, int color ) /* 8x14 */
{
  char tc[2];

  /* trap out of bounds character calls */

  if ( x < 0 || x > vdevice.sizeSx || y < 0 || y > vdevice.sizeSy )
    return;

#ifdef DEBUG
  printf("egalchar- x:%3d y:%3d ch:%c clr:%3d cc:%3d\n",x,y,(char)c,color,(int)_cur_color);
#endif
  _setcharsize( 8, 14 );
  _setcolor( (short) color );
  tc[0]= c;
  tc[1]= '\0';
  _grtext( (short) x, (short) y, tc );
}

void egaschar( int x, int y, int c, int color ) /* 8x8 */
{
  char tc[2];

  /* trap out of bounds character calls */

  if ( x < 0 || x > vdevice.sizeSx || y < 0 || y > vdevice.sizeSy )
    return;

#ifdef DEBUG
  printf("egaschar- x:%3d y:%3d ch:%c clr:%3d cc:%3d\n",x,y,(char)c,color,(int)_cur_color);
#endif
  _setcharsize( 8, 8 );
  _setcolor( (short) color );
  tc[0]= c;
  tc[1]= '\0';
  _grtext( (short) x, (short) y, tc );
}

/*
  mouse code copied from WATCOM documentation
*/

#include <i86.h>
union REGS inregs,outregs;
struct SREGS sregs;

int right_mouse_button= 0;
int left_mouse_button= 0;
int mouse_event= 0;
int mouse_code= 0;
int mouse_cx= 0;
int mouse_dx= 0;

#pragma off (check_stack)
void _loadds far click_handler (int max, int mcx, int mdx)
{
#pragma aux click_handler parm [EAX] [ECX] [EDX]
  mouse_event= 1;
  mouse_code= max;
  mouse_cx= mcx;
  mouse_dx= mdx;
  right_mouse_button= left_mouse_button= 0;
  if ( mouse_code == 8 ) right_mouse_button= 1;
  if ( mouse_code == 2 ) left_mouse_button= 1;
  if ( mouse_code == 10 ) left_mouse_button= right_mouse_button= 1;
}
#pragma on (check_stack)


int ismouse( int x, int y )
{
  int (far *function_ptr)();

  /* check for mouse and return -1 if it is not present */

  inregs.w.ax= 0;
  int386(0x33, &inregs, &outregs);
  if ( outregs.w.ax != -1 ) 
    return(0);


  /* mouse is here, so install click handler to watch mouse */

  inregs.w.ax= 0xC;
  inregs.w.cx= 0x0002 + 0x0008;
  function_ptr= click_handler;
  inregs.x.edx= FP_OFF( function_ptr );
  sregs.es=     FP_SEG( function_ptr );
  int386x( 0x33, &inregs, &outregs, &sregs );
  
  return(1);
}

void showmouse()
{

  inregs.w.ax= 0x1;
  int386( 0x33, &inregs, &outregs );

}

int readmouse( int *x, int *y )
{
  *x= mouse_cx;
  *y= mouse_dx;

  if ( right_mouse_button == 1 && left_mouse_button == 1 )
    return(3);
  else if ( right_mouse_button == 1 )
    return(1);
  else if ( left_mouse_button == 1 )
    return(2);
  else
    return(0);
}

int current_page= 0;

void vega_backbuf()
{
  if ( pageswap_OK == FALSE )
    verror("page swapping not possible");
  _setactivepage( 1 );
}

void vega_frontbuf()
{
  if ( pageswap_OK == FALSE )
    verror("page swapping not possible");
  _setactivepage( 0 );
}

void vega_swapbuf()
{
  if ( pageswap_OK == FALSE )
    verror("page swapping not possible");
  if ( current_page == 0 ) {
    _setvisualpage( 1 );
    current_page= 1;
  } else {
    _setvisualpage( 0 );
    current_page= 0;
  }
}


static void iswap( int *a, int *b )
{
  int	t;
  
  t = *a;
  *a = *b;
  *b = t;
}
