#include <graph.h>

static videoconfig vconf; 


void vga_init(int mode)
{ 
  if (mode == 1) // graphics mode
  { if (_setvideomode(_XRES16COLOR) == _UNKNOWN && 
        _setvideomode(_SVRES16COLOR) == _UNKNOWN)
        _setvideomode(_VRES16COLOR);

    _getvideoconfig(&vconf);
    _setviewport(0,0,vconf.numxpixels-1,vconf.numypixels-1);
    for(int i=0; i<16; i++) vga_setpal(i,_R_[i],_G_[i],_B_[i]);
   }
  else
    _setvideomode(_DEFAULTMODE);
  
}

int  vga_width()  { return vconf.numxpixels; }
int  vga_height() { return vconf.numypixels; }
int  vga_depth()  { return vconf.bitsperpixel; } 

void vga_clear(int col) 
{ _setcolor(col); 
  _rectangle(_GFILLINTERIOR,0,0,vga_width()-1,vga_height()-1);
 }

void vga_setpal(int index, int red, int green, int blue)
{ _R_[index] = red;
  _G_[index] = green;
  _B_[index] = blue;
  red   /= 4;
  green /= 4;
  blue  /= 4;
  _remappalette(index, (blue<<16) | (green<<8) | red);
}

void vga_getpal(int index, int* red, int* green, int* blue)
{ *red   = _R_[index];
  *green = _G_[index];
  *blue  = _B_[index];
 }

void vga_set_color(int color) { _setcolor(color); }

void vga_set_mode(int mode)
{ switch(mode) {
   case 0: _setplotaction(_GPSET);
           break;
   case 1: _setplotaction(_GAND);
           break;
   case 2: _setplotaction(_GOR);
           break;
   case 3: _setplotaction(_GXOR);
           break;
  }
}


void vga_pixel(int x, int y) 
{ _setpixel(x,y); }

void vga_hline(int x1, int x2,int y)
{ _rectangle(_GFILLINTERIOR,x1,y,x2,y); }

void vga_vline(int x, int y1, int y2)
{ _rectangle(_GFILLINTERIOR,x,y1,x,y2); }

void vga_box(int x1, int y1, int x2, int y2)
{ _rectangle(_GFILLINTERIOR,x1,y1,x2,y2); }


static void vga_bytes(int x, int y, unsigned char* ptr, int len)
{ unsigned char* stop = ptr+len;
  while (ptr < stop)
  { int d = 0;
    for (d=0; ptr <stop && *ptr==0xFF; ptr++) d += 8;
    if (d > 0)
      { _rectangle(_GFILLINTERIOR,x,y,x+d,y);
        x += d;
       }
    else
      { unsigned char c = *ptr++;
        if (c & 128) _setpixel(x,  y);
        if (c &  64) _setpixel(x+1,y);
        if (c &  32) _setpixel(x+2,y);
        if (c &  16) _setpixel(x+3,y);
        if (c &   8) _setpixel(x+4,y);
        if (c &   4) _setpixel(x+5,y);
        if (c &   2) _setpixel(x+6,y);
        if (c &   1) _setpixel(x+7,y);
        x += 8;
       }
   }
}



void vga_bitmap(int x, int y, unsigned char* pm, int width, int height)
{ while (height--)
  { vga_bytes(x,y++,pm,width);
    pm += width;
   }
 }



char* vga_getimage(int left, int top, int right, int bottom)
{ char* bp = new char[_imagesize(left,top,right,bottom)];
  _getimage(left,top,right,bottom,bp);
  return bp;
 }

void vga_putimage(int x, int y, char* image)
{ if (x < 0) x = 0;
  if (y < 0) y = 0;
  _putimage(x,y,image,_GPSET);
 }

void vga_delimage(char* image)   { delete image; }

void vga_copyimage(int x1, int y1, int x2, int y2, int x, int y)
{ int sz = _imagesize(x1,y1,x2,y2);
  char* image = new char[sz];
  _getimage(x1,y1,x2,y2,image);
  _putimage(x,y,image,_GPSET);
  delete[] image;
 }
