#include <sys/bios.h>
#include "display.h"

static char bg_font[8] = {
   0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa
};

static int font_blank[8] = {
   0, 0, 0, 0, 0, 0, 0, 0
};
void clear_rect(int screen, int x, int y, int w, int h) {
   static int chars[REAL_SCREEN_W*REAL_SCREEN_H];
   int i; 

   if (w <= 0 || h <= 0)
     return;
   screen_get_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
   for(i=0; i<w*h; i++) {
      font_set_monodata(chars[i]&0x1ff, 1, font_blank);
   }
}

void r_fill_char(int screen, int x, int y, int w, int h, unsigned int data) {
   int i, j;
   int chars[REAL_SCREEN_W * REAL_SCREEN_H];

   for (j=0; j<h; j++)
     for (i=0; i<w; i++)
       chars[i+j*w] = data;
   screen_set_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
}

void r_fill_char_incr(int screen, int x, int y, int w, int h, 
		      unsigned int base_char) {
   int i, j, c;
   int chars[REAL_SCREEN_W * REAL_SCREEN_H];

   c = base_char;
   for (j=0; j<h; j++)
     for (i=0; i<w; i++) {
	chars[i+j*w] = c;
	c++;
     }
   screen_set_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
}

int r_get_char1(int screen, int x, int y) {
   static int c;

   screen_get_char(screen, REAL_SCREEN_W-y-1, x, 1, 1, &c);
   return 0x1ff & c;
}

void r_set_attr1(int screen, int x, int y, int palette) {
   static int c;

   screen_get_char(screen, REAL_SCREEN_W-y-1, x, 1, 1, &c);
   c = (c&0x1ff) + (palette <<9);
   screen_set_char(screen, REAL_SCREEN_W-y-1, x, 1, 1, &c);
}

void draw_char_to_font(int dstcode, int code) {
   char font[8], font1[8];
   int i, j, k;

   text_get_fontdata(code, font);
   k=0x80;
   for (i=0; i<8; i++) {
     font1[i] = 0;
     for (j=7; j>=0; j--) {
	font1[i] = font1[i] << 1;
	if (font[j] & k)
	  font1[i]++;
     }
     k = k>>1;
   }
   font_set_monodata(dstcode, 1, font1);
}

void draw_char(int screen, int x, int y, int code) {
   draw_char_to_font(r_get_char1(screen, x, y), code);
}

void draw_string(int screen, int x, int y, const char* string) {
   int i;
   int c1, c2;

   i=0;
   while((c1 = string[i])) {
      i++;
      if (c1 & 0x80) {
	 c2 = string[i];
	 i++;
	 if (c2 == 0)
	   break;
	 draw_char(screen, x, y, (c1<<8) + c2);
	 x++;
      } else {
	 draw_char(screen, x, y, c1);
	 x++;
      }
   }
}


#define INDEX(i, j) ((i+1)*h-(j)-1)
void rotate_up_line(int screen, int x, int y, int w, int h) {
   static int chars[REAL_SCREEN_W*REAL_SCREEN_H];
   int char_save;
   int i, j;

   screen_get_char(screen, REAL_SCREEN_W-y-1, x, h, w, chars);
   for(i=0; i<w; i++) {
      char_save = chars[INDEX(i, 0)];
      for(j=0; j<h-1; j++) 
	chars[INDEX(i, j)] = chars[INDEX(i, j+1)];
      chars[INDEX(i, h-1)] = char_save;
   }
   screen_set_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
}

void rotate_down_line(int screen, int x, int y, int w, int h) {
   static int chars[REAL_SCREEN_W*REAL_SCREEN_H];
   int char_save;
   int i, j;

   screen_get_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
   for(i=0; i<w; i++) {
      char_save = chars[INDEX(i, h-1)];
      for(j=h-1; j>=0; j--) 
	chars[INDEX(i, j)] = chars[INDEX(i, j-1)];
      chars[INDEX(i, 0)] = char_save;
   }
   screen_set_char(screen, REAL_SCREEN_W-y-1, x, h, w, chars);
}

void rotate_up_char(int screen, int x, int y, int w, int h, 
		    int i0, int i1) {
   static int chars[REAL_SCREEN_W*REAL_SCREEN_H];
   int char_save;
   int i, j;

   screen_get_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
   char_save = chars[INDEX(i0, 0)];
   for(j=0; j<h; j++)
     for(i=0; i<w; i++) 
       if ((j==0 && i < i0) || (j==h-1 && i >= i1-1)) {
       } else {
	  if (i < w-1)
	    chars[INDEX(i, j)] = chars[INDEX(i+1, j)];
	  else
	    chars[INDEX(i, j)] = chars[INDEX(0, j+1)];
       }
   chars[INDEX(i1-1, h-1)] = char_save;
   screen_set_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
}

void rotate_down_char(int screen, int x, int y, int w, int h, 
		    int i0, int i1) {
   static int chars[REAL_SCREEN_W*REAL_SCREEN_H];
   int char_save;
   int i, j;

   screen_get_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
   char_save = chars[INDEX(i1-1, h-1)];
   for(j=h-1; j>=0; j--)
     for(i=w-1; i>=0; i--) 
       if ((j==0 && i <= i0) || (j==h-1 && i >= i1)) {
       } else {
	  if (i > 0)
	    chars[INDEX(i, j)] = chars[INDEX(i-1, j)];
	  else
	    chars[INDEX(i, j)] = chars[INDEX(w-1, j-1)];
       }
   chars[INDEX(i0, 0)] = char_save;
   screen_set_char(screen, REAL_SCREEN_W-y-h, x, h, w, chars);
}
#undef INDEX
