#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "display.h"
#include "vncviewer.h"
#include "mcode.h"


static int bbox[4];
static int validbbox = 0;


void display_copy(int rx, int ry, int rw, int rh, int sx, int sy) {

  unsigned short *from, *to;
  int y;

  from = display.data + display.shortsperline*sy + sx;
  to = display.data + display.shortsperline*ry + rx;

  if (from > to) {
    for (y = 0; y < rh; y++) {
      memcpy(to, from, 2*rw);
      to += display.shortsperline;
      from += display.shortsperline;
    }
  } else {
    to += display.shortsperline*(rh-1);
    from += display.shortsperline*(rh-1);
    for (y = 0; y < rh; y++) {
      memcpy(to, from, 2*rw);
      to -= display.shortsperline;
      from -= display.shortsperline;
    }
  }
}


void display_raw(int rx, int ry, int rw, int rh, void *buf, int dithered8) {

  unsigned short *out;
  int y, x;

  out = display.data + display.shortsperline*ry + rx;

  if ((dithered8) || (bpp == 8)) {
    char *in;

    in = buf;
    for (y = 0; y < rh; y++) {
      for (x = 0; x < rw; x++)     out[x] = rgb332_rgb555_table[in[x]];
      out += display.shortsperline;
      in += rw;
    }

  } else {
    unsigned short *in;

    in = buf;
    for (y = 0; y < rh; y++) {
      memcpy(out, in, 2*rw);
      out += display.shortsperline;
      in += rw;
    }
  }
}


void display_fillrectangle(int rx, int ry, int rw, int rh, unsigned short pix) {

  unsigned short *out;

  out = display.data + display.shortsperline*ry + rx;
  if (bpp == 8) {
    mc_fill_rectangle(out, rw, rh, display.shortsperline, pix);
  } else {
    mc_fill_rectangle(out, rw, rh, display.shortsperline, pix);
  }
}



void display_flush() {

  if (!validbbox)   return;
  UpdateWindow(bbox[0], bbox[1], bbox[2]-bbox[0], bbox[3]-bbox[1]);
  validbbox = 0;
}


void display_add_rectangle(int x, int y, int w, int h) {

  if (validbbox) {
    unsigned int s;
    int x0, y0, x1, y1;

    s = (unsigned int) (bbox[2]-bbox[0]) * (bbox[3]-bbox[1]) + w * h;
    x0 = x   < bbox[0] ? x   : bbox[0];
    y0 = y   < bbox[1] ? y   : bbox[1];
    x1 = x+w > bbox[2] ? x+w : bbox[2];
    y1 = y+h > bbox[3] ? y+h : bbox[3];
    if (((x1 - x0) * (y1 - y0)) >> addrectshift <= s) {
      bbox[0] = x0;
      bbox[1] = y0;
      bbox[2] = x1;
      bbox[3] = y1;
      return;
    }
    display_flush();
  }
  bbox[0] = x;
  bbox[1] = y;
  bbox[2] = x+w;
  bbox[3] = y+h;
  validbbox = 1;
}
