/*******************************************************************************
+
+  LEDA 3.5
+
+  _svgalib.c
+
+  This file is part of the LEDA research version (LEDA-R) that can be 
+  used free of charge in academic research and teaching. Any commercial
+  use of this software requires a license which is distributed by the
+  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
+  (fax +49 681 31104).
+
+  Copyright (c) 1991-1997  by  Max-Planck-Institut fuer Informatik
+  Im Stadtwald, 66123 Saarbruecken, Germany     
+  All rights reserved.
+ 
*******************************************************************************/
#include <LEDA/impl/x_window.h>
#include <stdio.h>
#include <vga.h>
#include <vgamouse.h>
#include <unistd.h>
#include <fcntl.h>
#include <curses.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/stat.h>


static int mouse_but;
static int mouse_x;
static int mouse_y;

static int mouse_fd;
static int keyboard_fd;

enum { NO_EVENT, KEYBOARD_EVENT, MOUSE_EVENT }; 



void init_graphics(int mode, int& width, int& height, int& depth)
{
  if (mode == 1) // graphics mode
  { if ( vga_setmode(G800x600x256) && 
         //vga_setmode(G640x480x256) && 
         vga_setmode(G640x480x16))
     { fprintf (stderr, "Cannot switch to graphics mode.\n");
       exit(1);
      }

     mouse_fd = mouse_init_return_fd("/dev/mouse",MOUSE_PS2,150);
     keyboard_fd = 0;
     cbreak();
     noecho();

/*
     //int mouse_type = vga_getmousetype();
     int mouse_type = MOUSE_PS2;
     if ( mouse_init("/dev/mouse",mouse_type,150) != 0 )
     { vga_setmode(TEXT);
       printf("\nCannot open mouse device (gpm running ?)\n\n");
       exit(1);
      }
*/

     width = vga_getxdim();
     height= vga_getydim();
     depth = vga_getcolors();

     mouse_setxrange(0,width-1);
     mouse_setyrange(0,height-1);
     mouse_setwrap(0);
    }
  else
  { mouse_close();
    vga_setmode(TEXT);
    nocbreak();
    echo();
   }
}



void  define_color(int i, int r, int g, int b) 
{  vga_setpalette(i,r,g,b); }


void  draw_scan_segment(unsigned char* p, int x, int y, int len)
{ vga_drawscansegment(p,x,y,len); }


void  draw_pixel(int x, int y, unsigned char c)
{ vga_setcolor(c);
  vga_drawpixel(x,y); 
 }


static int read_next_event(int *val, int *x, int *y, int timeout)
{ 
  int f = ((mouse_fd > keyboard_fd) ? mouse_fd : keyboard_fd) + 1;

  fd_set rfds;
  FD_ZERO(&rfds);
  FD_SET(mouse_fd,&rfds);
  FD_SET(keyboard_fd,&rfds);

  struct timeval tv;
  tv.tv_usec = timeout;
  tv.tv_sec = 0;

  if (timeout == 0)
     select(f,&rfds,NULL,NULL,NULL);
  else
    if (select(f,&rfds,NULL,NULL,&tv) <= 0) return NO_EVENT;

  if (FD_ISSET(keyboard_fd,&rfds)) { 
    char c;
    read(keyboard_fd,&c,1);
    *val = c;
    return KEYBOARD_EVENT;
   }

  if (FD_ISSET(mouse_fd,&rfds)) { 
    //mouse_update();
    mouse_waitforupdate();
    *x = mouse_getx();
    *y = mouse_gety();
    *val = mouse_getbutton();
    return MOUSE_EVENT;
   }

}




int check_next_event(int& val, int& x, int& y, int block)
{ 
  int timeout = (block) ? 0 : 1000;

  int k = read_next_event(&val, &x, &y, timeout);

  if (k == KEYBOARD_EVENT)
  { x = mouse_x;
    y = mouse_y;
    switch (val) {
    case   1: val = KEY_ESCAPE;
              break;
    case 127: val = KEY_BACKSPACE;
              break;
    case  13: val = KEY_RETURN;
              break;
    }
    return key_press_event;
   }

  if (k == MOUSE_EVENT)
  { 
    if (val != mouse_but)
    { // read_next_event(&val, &x, &y, 150000);
      int e;
      if (val == 0) 
         { if (mouse_but == MOUSE_LEFTBUTTON)  val = 1;
           else
           if (mouse_but == MOUSE_RIGHTBUTTON) val = 3;
           else
           if (mouse_but == MOUSE_RIGHTBUTTON+MOUSE_LEFTBUTTON) val = 2;
           e = button_release_event;
          }
      else
         { if (val == MOUSE_LEFTBUTTON)  val = 1;
           else
           if (val == MOUSE_RIGHTBUTTON) val = 3;
           else
           if (val == MOUSE_RIGHTBUTTON+MOUSE_LEFTBUTTON) val = 2;
           e = button_press_event;
          }
       mouse_x = x;
       mouse_y = y;
       mouse_but = val;
       return e;
     }

    if (mouse_x != x || mouse_y != y)
    { mouse_x = x;
      mouse_y = y;
      return motion_event;
     }
   }

  return no_event;
}

