#include <iostream.h>
#include <gnome.h>
#include "draw.h"

GdkGC *gc = NULL;
GdkColormap *colormap = NULL;
GdkPixmap *main_pxm, *brick_pxm, *wall_pxm, *space_pxm;

// Redraws the entire window.
void Draw(GtkWidget *area)
{
  gdk_draw_pixmap(area->window, gc, main_pxm, 0, 0, 0, 0, 
		  T_WIDTH*C_WIDTH, T_HEIGHT*C_HEIGHT);
}

// Initializes the data in the pixmaps
void Init_pixmaps(GtkWidget *widget)
{
  GdkColor wall_cl, brick_cl;
  main_pxm = gdk_pixmap_new(widget->window, 
			    T_WIDTH*C_WIDTH, T_HEIGHT*C_HEIGHT, -1);
  brick_pxm = gdk_pixmap_new(widget->window, C_WIDTH, C_HEIGHT, -1);
  wall_pxm = gdk_pixmap_new(widget->window, C_WIDTH, C_HEIGHT, -1);
  space_pxm = gdk_pixmap_new(widget->window, C_WIDTH, C_HEIGHT, -1);

  wall_cl.red = (gushort) 0x8FFF;
  wall_cl.green = (gushort) 0x0FFF;
  wall_cl.blue = (gushort) 0x0FFF;
  Draw_rect_border(wall_pxm, wall_cl, C_WIDTH, C_HEIGHT);

  brick_cl.red = (gushort) 0xFFFF;
  brick_cl.green = (gushort) brick_cl.red/2;
  brick_cl.blue = (gushort) 0;
  Draw_rect_border(brick_pxm, brick_cl, C_WIDTH, C_HEIGHT);

  Draw_space(space_pxm, C_WIDTH, C_HEIGHT);

}

// Initialize the graphical context based on the drawing area.
void Init_gc(GtkWidget *area)
{ 
  colormap = gdk_colormap_get_system();
  gc = gdk_gc_new(area->window);
}

// A test function for the various pixmaps.
void Test_pixmaps(GtkWidget *area)
{
  //cout << 1 << endl;
  gdk_draw_pixmap(area->window, gc, space_pxm, 
			0, 0, 10, 10,  C_WIDTH, C_HEIGHT);
  //cout << 2 << endl;
  gdk_draw_pixmap(area->window, gc, brick_pxm, 
			0, 0, 25, 10,  C_WIDTH, C_HEIGHT);
  //cout << 3 << endl;
  gdk_draw_pixmap(area->window, gc, wall_pxm, 
			0, 0, 45, 10,  C_WIDTH, C_HEIGHT);
  //cout << 4 << endl;
}

// Draws the table on the main pixmap.
void Draw_table(Table_type table, int width, int height)
{
  for (int x=0; x<width; x++)
    for (int y=0; y<height; y++)
      switch (table[x][y]) { //space_cell, brick_cell, wall_cell
      case space_cell:
	gdk_draw_pixmap(main_pxm, gc, space_pxm, 
			0, 0, x*C_WIDTH, y*C_HEIGHT,  C_WIDTH, C_HEIGHT);
	break;
      case brick_cell:
	gdk_draw_pixmap(main_pxm, gc, brick_pxm, 
			0, 0, x*C_WIDTH, y*C_HEIGHT,  C_WIDTH, C_HEIGHT);
	break;
      case wall_cell:
	gdk_draw_pixmap(main_pxm, gc, wall_pxm, 
			0, 0, x*C_WIDTH, y*C_HEIGHT,  C_WIDTH, C_HEIGHT);
	break;
      }
}

// Draws a rectangle of the given color, with a lighter border on top
// and a darker border at the bottom.
void Draw_rect_border(GdkPixmap *pixmap, GdkColor color, 
		      int width, int height)
{
  GdkColor lighter, darker;

  gdk_color_alloc(colormap, &color);
  gdk_gc_set_foreground(gc, &color);
  gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);

  darker.red = 0.75*color.red;
  darker.green = 0.75*color.green;
  darker.blue = 0.75*color.blue;
  gdk_color_alloc(colormap, &darker);
  gdk_gc_set_foreground(gc, &darker);

  gdk_draw_line(pixmap, gc, 0, 0, width-1, 0);
  gdk_draw_line(pixmap, gc, 0, 0, 0, height-1);

  lighter.red = (color.red + 0xFFFF)/2;
  lighter.green = (color.green + 0xFFFF)/2;
  lighter.blue = (color.blue + 0xFFFF)/2;
  gdk_color_alloc(colormap, &lighter);
  gdk_gc_set_foreground(gc, &lighter);

  gdk_draw_line(pixmap, gc, width-1, 0, width-1, height-1);
  gdk_draw_line(pixmap, gc, 0, height-1, width-1, height-1);
}

// Draws a white rectangle.
void Draw_space(GdkPixmap *pixmap, int width, int height)
{
  GdkColor white, gray;

  white.red = 0xFFFF;
  white.green = 0xFFFF;
  white.blue = 0xFFFF;

  gray.red = 0xDFFF;
  gray.green = 0xDFFF;
  gray.blue = 0xDFFF;

  gdk_color_alloc(colormap, &white);
  gdk_gc_set_foreground(gc, &white);
  gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);

  gdk_color_alloc(colormap, &gray);
  gdk_gc_set_foreground(gc, &gray);
  gdk_draw_line(pixmap, gc, width-1, 0, width-1, height-1);
  gdk_draw_line(pixmap, gc, 0, height-1, width-1, height-1);
}


// Draws spaces over a tetris brick on the main pixmap.
void Erase_brick(Tetris_brick &the_brick, int old_x, int old_y)
{
  int x, y;
  for (int i=0; i<BRICK_NR; i++) {
    x = old_x + the_brick.bricks[i][0];
    y = old_y + the_brick.bricks[i][1];
    gdk_draw_pixmap(main_pxm, gc, space_pxm, 
		    0, 0, x*C_WIDTH, y*C_HEIGHT,  C_WIDTH, C_HEIGHT);
  }
}

// Draws the brick at the position stored in the object itself.
void Draw_brick(Tetris_brick &the_brick)
{
  int x, y;
  for (int i=0; i<BRICK_NR; i++) {
    x = the_brick.pos_x + the_brick.bricks[i][0];
    y = the_brick.pos_y + the_brick.bricks[i][1];
    gdk_draw_pixmap(main_pxm, gc, brick_pxm, 
		    0, 0, x*C_WIDTH, y*C_HEIGHT,  C_WIDTH, C_HEIGHT);
  }
}
