/*  drawing.c

    Copyright (C) 1994	Lambert Klasen & Detlef Steuer
			klasen@asterix.uni-muenster.de
			steuer@amadeus.statistik.uni-dortmund.de

    This file is free source code; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
    COPYING for more details.
 */


#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xatom.h>
#include <X11/Shell.h>
#include <stdio.h>
#include <stdlib.h>

#include "xgammon.h"
#include "gammon.h"

extern XFontStruct *doubler_font, *little_font;

Pixmap boardPixmap;
Pixmap underStone;
Pixmap pixmap[32];
Pixmap bar_pixmap[9];

XPoint pin_to_position(int pin);
void draw_empty_board();
void draw_board();
void DrawDice();
void DeleteDice();
void DrawEmptyDice();
void DrawDiceValues();
void draw_doubler();
static void draw_one();
static void draw_two();
static void draw_three();
static void draw_four();
static void draw_five();
static void draw_six();
void put_stone(unsigned int color, unsigned int pin);
void draw_stone();
void remove_stone();
void redraw_all_stones();
void free_pixmaps(void);
void prepare_pixmaps(void);

int  rect_width, rect_height;
static int dice_x = 0, dice_y = 0;

void draw_board(void)
{
	XCopyArea(dpy, boardPixmap,  boardWindow, boardGC, 0, 0, width, height, 0, 0);
}

void draw_empty_board(void)
{
XPoint c[3];
int i;
int s = 0;

rect_width  = stone_width;
rect_height = stone_width * 5;

XSetForeground(dpy, boardGC, gammon_resource.board_Pixel);
XFillRectangle(dpy, boardPixmap, boardGC, 0, 0, width, height);

XSetForeground(dpy, boardGC, gammon_resource.bar_Pixel);
XFillRectangle(dpy, boardPixmap, boardGC, 0,		      0, rect_width, height);
XFillRectangle(dpy, boardPixmap, boardGC, rect_width * 7,     0, rect_width, height);
XFillRectangle(dpy, boardPixmap, boardGC, width - rect_width, 0, rect_width, height);

for(i=1; i<13; i++) {

	/* first draw a filled triangle */
	c[0].x = i * rect_width;	if (i>6) c[0].x += rect_width;
	c[0].y = 0;
	c[1].x = c[0].x + rect_width;
	c[1].y = 0;
	c[2].x = c[0].x + rect_width/2;
	c[2].y = rect_height;

	if (s) XSetForeground(dpy, boardGC, gammon_resource.light_Pixel);
	else   XSetForeground(dpy, boardGC, gammon_resource.dark_Pixel);
	XFillPolygon(dpy, boardPixmap, boardGC, c, 3, Convex, CoordModeOrigin);

	/* then a little black border around it */
	/* base */
	XDrawLine(dpy, boardPixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);

	/* left side */
	c[1].y =  rect_height;
	c[1].x -= rect_width/2;
	XDrawLine(dpy, boardPixmap, gc, c[0].x,	             c[0].y, c[1].x, c[1].y);

	/* right side */
	XDrawLine(dpy, boardPixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

	if (s==0) s=1; else s=0;
	}

for(i=1; i<13; i++) {
	/* draw a triangle */
	c[0].x = i * rect_width; if (i > 6) c[0].x += rect_width;
	c[0].y = height - 1;
	c[1].x = c[0].x + rect_width;
	c[1].y = height - 1;
	c[2].x = c[0].x + rect_width/2;
	c[2].y = height - rect_height;

	/* make the opposing colors different, so !s */
	if (!s) XSetForeground(dpy, boardGC, gammon_resource.light_Pixel);
	else    XSetForeground(dpy, boardGC, gammon_resource.dark_Pixel);
	XFillPolygon(dpy, boardPixmap, boardGC, c, 3, Convex, CoordModeOrigin);

	/* and around it a little black border */
	c[0].x = i  * rect_width; if (i > 6) c[0].x += rect_width;
	c[1].x = c[0].x + rect_width;
	c[0].y = c[1].y = height - 1;
	XDrawLine(dpy, boardPixmap, gc, c[0].x, c[0].y, c[0].x, c[1].y);
	c[1].y =  height - rect_height;
	c[1].x -= rect_width/2;
	XDrawLine(dpy, boardPixmap, gc, c[0].x, c[0].y, c[1].x, c[1].y);
	XDrawLine(dpy, boardPixmap, gc, c[0].x + rect_width, c[0].y, c[1].x, c[1].y);

	if (s==0) s=1; else s=0;
	}
	draw_board();
}

void DrawDice(int color)
{
	DeleteDice();
	DrawEmptyDice(color);
	DrawDiceValues();
}

void DeleteDice(void)
{
	int x;

	if (!dice_y) return;

	if (turn == BLACK) x = 3 * stone_width + stone_width/2 - 3; /* remove white dice */
	else 		   x = 9 * stone_width + stone_width/2 - 3;

	XSetForeground(dpy, boardGC, gammon_resource.board_Pixel);
	XFillRectangle(dpy, boardWindow, boardGC, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle(dpy, boardWindow, boardGC, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle(dpy, boardPixmap, boardGC, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
	XFillRectangle(dpy, boardPixmap, boardGC, x, dice_y - 3, stone_width * 2 + stone_width/2 + 6, dice_width + 6);
}

void DrawEmptyDice(int color)
{
	unsigned long b, w; /* black and white pixel */

	dice_y = 6 * stone_width - dice_width/2;

	if (color == BLACK) {
		b = gammon_resource.white_Pixel;
		w = gammon_resource.black_Pixel;
		dice_x = 9 * stone_width + stone_width/2;
	}
	else {
	        w = gammon_resource.white_Pixel;
	        b = gammon_resource.black_Pixel;
		dice_x = 3 * stone_width + stone_width/2;
        }

	XSetForeground(dpy, diceGC, w);
	XFillRectangle(dpy, boardWindow, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle(dpy, boardWindow, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XFillRectangle(dpy, boardPixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XFillRectangle(dpy, boardPixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XSetForeground(dpy, diceGC, b);
	XDrawRectangle(dpy, boardWindow, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle(dpy, boardWindow, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
	XDrawRectangle(dpy, boardPixmap, diceGC, dice_x, dice_y, dice_width, dice_width);
	XDrawRectangle(dpy, boardPixmap, diceGC, dice_x + dice_width + dice_width/2, dice_y, dice_width, dice_width);
}

void DrawDiceValues(void)
{
switch (abs(roll[0])) {
	case 1: draw_one  (dice_x, dice_y, dice_width); break;
	case 2: draw_two  (dice_x, dice_y, dice_width); break;
	case 3: draw_three(dice_x, dice_y, dice_width); break;
	case 4: draw_four (dice_x, dice_y, dice_width); break;
	case 5: draw_five (dice_x, dice_y, dice_width); break;
	case 6: draw_six  (dice_x, dice_y, dice_width); break;
	}

switch (abs(roll[1])) {
	case 1: draw_one  (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	case 2: draw_two  (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	case 3: draw_three(dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	case 4: draw_four (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	case 5: draw_five (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	case 6: draw_six  (dice_x + dice_width + dice_width/2, dice_y, dice_width); break;
	}
}

void draw_doubler(int how_double, int who_doubled) /* doubler is as wide as a stone */
{
	int x = 0;
	static int y = 0; /* yes */
	int font_height, font_width, l;

	char t[3];

	/* all the x+1, y-3, x-1 ... or some like that are more or lesss
	   neccessary cause of XDrawLine () Function */

	/* remove old doubler */
	XSetForeground(dpy, boardGC, gammon_resource.bar_Pixel);
	XFillRectangle(dpy, boardWindow, boardGC, x, y - 3, stone_width, 2*stone_width);

	/* set new position */
	if      (who_doubled == BLACK) y = 2*stone_width; 
	else if (who_doubled == WHITE) y = 9*stone_width;
	else if (who_doubled == 0)     y = 5*stone_width  + stone_width/2;

	/* draw new one */
	XSetForeground(dpy, diceGC, gammon_resource.white_Pixel);
	XFillRectangle(dpy, boardWindow, diceGC, x+1, y, stone_width-3, stone_width);
	XFillRectangle(dpy, boardPixmap, diceGC, x+1, y, stone_width-3, stone_width);
	XSetForeground(dpy, diceGC, gammon_resource.black_Pixel);
	XDrawRectangle(dpy, boardWindow, diceGC, x+1, y, stone_width-3, stone_width);
	XDrawRectangle(dpy, boardPixmap, diceGC, x+1, y, stone_width-3, stone_width);

	/* prepare the numbr inside */
	if (how_double < 10) {
		t[0] = how_double + '0';
		l = 1;
	}
	else {
		t[0] = how_double/10 + 48;
		t[1] = how_double%10 + 48;
		l = 2;
	}

	/* decide witch font to use */
	if ((doubler_font->ascent + doubler_font->descent + 6) > stone_width) {
		XSetFont(dpy, diceGC, little_font->fid);
		font_height = little_font->ascent + little_font->descent;
		font_width = little_font->per_char[t[0] - little_font->min_char_or_byte2].width;
	}
	else {
		XSetFont(dpy, diceGC, doubler_font->fid);
		font_height = doubler_font->ascent + doubler_font->descent;
		font_width = doubler_font->per_char[t[0] - doubler_font->min_char_or_byte2].width;
	}

	if (how_double > 10) font_width *= 2;

	/* draw the text */
	x += (stone_width - font_width)/2;
	y += stone_width - (stone_width - font_height)/2 - 3;
	XDrawImageString(dpy, boardWindow, diceGC, x , y, t, l);
	XDrawImageString(dpy, boardPixmap, diceGC, x , y, t, l);

	/* reset y for remove */
	y -= stone_width - (stone_width - font_height)/2 - 3;
}

void draw_one(int dice_x, int dice_y, int dice_width)
{
	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/2 - r/2;
	y = dice_y + dice_width/2 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);
}

void draw_two(int dice_x, int dice_y, int dice_width)
{
	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width/4 - r/4;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - (dice_width - 6)/4 - r;
	y = dice_y + dice_width - (dice_width - 6)/4 - r;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);
}

void draw_three(int dice_x, int dice_y, int dice_width)
{
	int x, y, r;

	/* center */
	r = dice_width/4;
	x = dice_x + dice_width/2 - r/2;
	y = dice_y + dice_width/2 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	/* upper left */
	x = dice_x + dice_width/4 - r/2;
	y = dice_y + dice_width/4 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	/* lower right */
	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);
}

void draw_four(int dice_x, int dice_y, int dice_width)
{
	int x, y, r;

	r = dice_width/4;
	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width/4 - r/4;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width/4 - r/4;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width/4 - r/4;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	x = dice_x + dice_width - dice_width/4 - r/2;
	y = dice_y + dice_width - dice_width/4 - r/2;

	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);
}

void draw_five(int dice_x, int dice_y, int dice_width)
{
	draw_one(dice_x+2, dice_y+2, dice_width);
	draw_four(dice_x, dice_y, dice_width);
}

void draw_six(int dice_x, int dice_y, int dice_width)
{
	int r, x, y;

	r = dice_width/4;

	/* left three */
	x = dice_x + dice_width/3 - r/2 - 2;
	y = dice_y + dice_width/4 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	y = dice_y + dice_width/2 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	y = dice_y  + dice_width - dice_width/4 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	/* right three */
	x = dice_x  + dice_width - dice_width/3 - r/2 + 2;
	y = dice_y + dice_width/4 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	y = dice_y + dice_width/2 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);

	y = dice_y  + dice_width - dice_width/4 - r/2;
	XFillArc(dpy, boardWindow, diceGC, x, y, r, r, 0*64, 360*64);
	XFillArc(dpy, boardPixmap, diceGC, x, y, r, r, 0*64, 360*64);
}

void put_stone(unsigned int color, unsigned int pin)
{
	XPoint p;

	p = pin_to_position(pin);	/* before adding the stone to the Pin */

	if (pin == FINISHED) {
		Pin[FINISHED].count++;
		Pin[FINISHED].color = color;
	}
	else {
		Pin[pin].count++;
		Pin[pin].color = color;
	}

	draw_stone (p.x, p.y, color);
	if (color == BLACK) {
	        XFillArc(dpy,boardPixmap,stoneGC[0], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc(dpy,boardPixmap,stoneGC[1], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
	        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
        }
	else {
	        XFillArc(dpy,boardPixmap,stoneGC[1], p.x, p.y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc(dpy,boardPixmap,stoneGC[0], p.x, p.y, stone_width-1, stone_width-1, 0, 360*64);
        }
}

void draw_stone(int x, int y, int color)
{
	if (color == BLACK) {
	        XFillArc(dpy,boardWindow,stoneGC[0], x, y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc(dpy,boardWindow,stoneGC[1], x, y, stone_width-1, stone_width-1, 0, 360*64);
	        /* DrawArc is somtimes a pixel wider than FillArc, donno why */
        }
	else {
	        XFillArc(dpy,boardWindow,stoneGC[1], x, y, stone_width,   stone_width,   0, 360*64);
	        XDrawArc(dpy,boardWindow,stoneGC[0], x, y, stone_width-1, stone_width-1, 0, 360*64);
        }
}

void remove_stone(int pin)
{
	Pixmap pixmap, pixmap_to_redraw(int pin);
	XPoint p;
	int copy_start, copy_start_in_pixmap(int pin);

	Pin[pin].count--;
	if (Pin[pin].count == 0) Pin[pin].color = 0;

	p = pin_to_position(pin);

	pixmap = pixmap_to_redraw(pin);
	copy_start = copy_start_in_pixmap(pin);

	XCopyArea(dpy, pixmap, boardWindow, boardGC,
		0, copy_start, stone_width, stone_width, p.x, p.y);
	XCopyArea(dpy, pixmap, boardPixmap, boardGC,
		0, copy_start, stone_width, stone_width, p.x, p.y);
}

Pixmap pixmap_to_redraw(int pin)
{
	int layer, turn_color, direct, pin_color;

	if (pin == BAR || pin == OTHER_BAR) {

		if (Pin[pin].count<5) return bar_pixmap[0];

		else if (Pin[pin].count<9)  layer = 1;
		else if (Pin[pin].count<13) layer = 3;
		else			    layer = 5;

		if (turn == BLACK) turn_color = 0;
		else		   turn_color = 1;

		if (Pin[pin].count>8) direct = (turn == BLACK) ? 0 : 1;
		else		      direct = 0;

		return bar_pixmap[layer + turn_color + direct];
	}

	if	(Pin[pin].count<5)  layer = 0;
	else if (Pin[pin].count<9)  layer = 1;
	else if (Pin[pin].count<13) layer = 2;
	else			    layer = 3;

	if (turn == BLACK) turn_color = 0;
	else		   turn_color = 2;

	pin_color = pin%2;

	if (pin <13) direct = 0;
	else	     direct = 16;

	return pixmap[direct + pin_color + turn_color + (4 * layer)];
}

int copy_start_in_pixmap(int pin)
{
	if (pin<13) {
		if     (Pin[pin].count < 5)  return ( Pin[pin].count       * stone_width);
		else if(Pin[pin].count < 9)  return ((Pin[pin].count - 5)  * stone_width + stone_width/2);
		else if(Pin[pin].count < 13) return ((Pin[pin].count - 9)  * stone_width + stone_width/4);
		else 			     return ((Pin[pin].count - 13) * stone_width + stone_width*3/4);
	}
	else {			/* GRRRHHUUUMMPPFFFNNAAARRGGHHH */
		if     (Pin[pin].count < 5)  return ((4  - Pin[pin].count) * stone_width);
		else if(Pin[pin].count < 9)  return ((8  - Pin[pin].count) * stone_width + stone_width/2);
		else if(Pin[pin].count < 13) return ((13 - Pin[pin].count) * stone_width - stone_width/4);
		else 			     return ((16 - Pin[pin].count) * stone_width - stone_width*3/4);
	}
}

void redraw_all_stones(void)
{
	int i, c;

	if (Pin[0].count) {
		c = Pin[0].count; Pin[0].count = 0;
		while (c) {
			if (turn == BLACK) put_stone(BLACK, BAR);
			else put_stone(BLACK, OTHER_BAR);
			c--;
		}
	}

	if (Pin[25].count) {
		c = Pin[25].count; Pin[25].count = 0;
		while (c) {
			if (turn == WHITE) put_stone(WHITE, BAR);
			else put_stone(WHITE, OTHER_BAR);
			c--;
		}
	}

	for (i=1; i<25; i++) {
		if (Pin[i].count) {
			c = Pin[i].count; Pin[i].count = 0;
			while (c) {
				put_stone(Pin[i].color, i);
				c--;
			}
		}
	}
	
{	int backup_turn = turn;	/* for loading from a file */

	turn = BLACK;
	if (Pin[25+turn].count) {
		c = Pin[25+BLACK].count; Pin[25+BLACK].count = 0;
		while (c) {
			put_stone(BLACK, 25+BLACK);
			c--;
		}
	}

	turn = WHITE;
	if (Pin[25+turn].count) {
		c = Pin[25+WHITE].count; Pin[25+WHITE].count = 0;
		while (c) {
			put_stone(WHITE, 25+WHITE);
			c--;
		}
	}

	turn = backup_turn;
}
}

void free_pixmaps(void)
{
	int i;

	XFreePixmap(dpy, boardPixmap);
	XFreePixmap(dpy, underStone);
	for (i=0; i<32; i++) XFreePixmap(dpy, pixmap[i]);
	for (i=0; i<9; 	i++) XFreePixmap(dpy, bar_pixmap[i]);
}

/* there is a comment in the sources of `xmgt' program:
   "... pixmap hell ..."
   so, here we go 
 */

void prepare_pixmaps(void)
{
	XPoint down_p[3], up_p[3];
	int i, j, y;
	unsigned int rect_width, rect_height;

	boardPixmap  = XCreatePixmap(dpy, boardWindow, width, height, screen_depth);
	draw_empty_board();	/* draw the pixmap */

	underStone   = XCreatePixmap(dpy, boardWindow, stone_width, stone_width, screen_depth);

	rect_width = stone_width;
	rect_height = stone_width * 5;

	down_p[0].x = 1;		/* looks a little more slim */
	down_p[1].x = rect_width - 1;
	down_p[2].x = rect_width/2;
	down_p[0].y = 0;
	down_p[1].y = 0;
	down_p[2].y = rect_height;

	up_p[0].x = rect_width/2;
	up_p[1].x = 1;
	up_p[2].x = rect_width - 1;
	up_p[0].y = 0;
	up_p[1].y = rect_height;
	up_p[2].y = rect_height;

/* first the bar stuff */

/* there are [layer 0-3] with
	empty = bar_pixmap[0]
	first and second layer are epual for up and down so:
		p[1],p[2] black,white first layer
		p[3],p[4] black,white second layer
	for the third layer up and down are different so:
		p[5],p[6] black,white up layer
		p[7],p[8] black,white down layer
 */

	for (i=0; i<9; i++) bar_pixmap[i] = XCreatePixmap(dpy, boardWindow, rect_width, rect_height, screen_depth);

/* now the pins */

/* threr are UP|DOWN DARK|LIGHT BLACK|WHITE EMPTY|ONE|TWO|THREE layers 
	   =   2    *    2     *     2     *       4     = 32 pixmaps
   of them two empty pixmaps are equal and so unused */

/* there are 15 stones: 5 in the first layer, 4 in the second and third
   and two in the fourth and last layer, (witch needs no redraw and so
    no pixmap)
   I fell this lotta pixmaps are a little a one way street,
   and I should possibly think a little more (but don't) */

	for (i=0; i<32; i++) pixmap[i] = XCreatePixmap(dpy, boardWindow, rect_width, rect_height, screen_depth);

	/* now draw the boardcolor inside */
	XSetForeground(dpy, boardGC, gammon_resource.board_Pixel);
	for (i=0; i<32; i++) XFillRectangle(dpy, pixmap[i], boardGC, 0, 0, rect_width, rect_height);

	/* the first 16 are the pins showing dowdwards the other 16 upwards */

	/* the dark ones */
	XSetForeground(dpy, boardGC, gammon_resource.dark_Pixel);
	for (i=0; i<16; i+=2) {
		XFillPolygon(dpy, pixmap[i], boardGC, down_p, 3, Convex, CoordModeOrigin);
		XDrawLine(dpy, pixmap[i], gc, down_p[0].x, down_p[0].y, down_p[2].x, down_p[2].y);
		XDrawLine(dpy, pixmap[i], gc, down_p[1].x, down_p[1].y, down_p[2].x, down_p[2].y);
	}

	for (i=16; i<32; i+=2) {
		XFillPolygon(dpy, pixmap[i],  boardGC, up_p, 3, Convex, CoordModeOrigin);
		XDrawLine(dpy, pixmap[i], gc, up_p[0].x, up_p[0].y, up_p[1].x, up_p[1].y);
		XDrawLine(dpy, pixmap[i], gc, up_p[0].x, up_p[0].y, up_p[2].x, up_p[2].y);
	}

	/* the light ones */
	XSetForeground(dpy, boardGC, gammon_resource.light_Pixel);
	for (i=1; i<16; i+=2) {
		XFillPolygon(dpy, pixmap[i], boardGC, down_p, 3, Convex, CoordModeOrigin);
		XDrawLine(dpy, pixmap[i], gc, down_p[0].x, down_p[0].y, down_p[2].x, down_p[2].y);
		XDrawLine(dpy, pixmap[i], gc, down_p[1].x, down_p[1].y, down_p[2].x, down_p[2].y);
	}

	for (i=17; i<32; i+=2) {
		XFillPolygon(dpy, pixmap[i],  boardGC, up_p, 3, Convex, CoordModeOrigin);
		XDrawLine(dpy, pixmap[i], gc, up_p[0].x, up_p[0].y, up_p[1].x, up_p[1].y);
		XDrawLine(dpy, pixmap[i], gc, up_p[0].x, up_p[0].y, up_p[2].x, up_p[2].y);
	}

/* now draw the first layer of stones into the pixmaps where necessary */
for (i=4; i<32; i+=4) {
	if (i == 16) i = 20;	/* skip empty ones */
for (j=0; j<5; j++) {
	y = stone_width * j;
	/* black stone on dark pin */
	XFillArc(dpy, pixmap[i], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[i], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* black stone on light pin */
	XFillArc(dpy, pixmap[i+1], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[i+1], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* white stone on dark pin */
	XFillArc(dpy, pixmap[i+2], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[i+2], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	/* white stone on light pin */
	XFillArc(dpy, pixmap[i+3], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[i+3], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
	}

/* second layer */
for (i=8; i<32; i+=4) {
	if (i == 16) i = 24;	/* skip empty ones */
	for (j=0; j<4; j++) {
		y = stone_width * j + stone_width/2;
		XFillArc(dpy, pixmap[i], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, pixmap[i], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc(dpy, pixmap[i+1], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, pixmap[i+1], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc(dpy, pixmap[i+2], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, pixmap[i+2], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc(dpy, pixmap[i+3], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, pixmap[i+3], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		}
	}

/* third and last layer */
for (j=0; j<4; j++) {
	y = stone_width * j + stone_width/4;	/* upper half of board */
	XFillArc(dpy, pixmap[12], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[12], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[13], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[13], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[14], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[14], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[15], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[15], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

	y = stone_width * j + stone_width*3/4;	/* lower half of board */
	XFillArc(dpy, pixmap[28], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[28], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[29], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[29], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[30], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[30], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	XFillArc(dpy, pixmap[31], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
	XDrawArc(dpy, pixmap[31], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}


	/* now the drawing in the bar pixmaps */

	/* the bar background */
	XSetForeground(dpy, boardGC, gammon_resource.bar_Pixel);
	for (i=0; i<9; i++) XFillRectangle(dpy, bar_pixmap[i], boardGC, 0, 0, rect_width, rect_height);

	for (i=1; i<9; i+=2) {         /* first layer */
	for (j=0; j<5; j++) {
		y = stone_width * j;
		XFillArc(dpy, bar_pixmap[i], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[i], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc(dpy, bar_pixmap[i+1], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[i+1], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
	}

	for (i=3; i<9; i+=2) {         /* second layer */
	for (j=0; j<4; j++) {
		y = stone_width * j + stone_width/2;
		XFillArc(dpy, bar_pixmap[i], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[i], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		XFillArc(dpy, bar_pixmap[i+1], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[i+1], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
	}

	for (j=0; j<4; j++) {         /* third layer */
		y = stone_width * j + stone_width/4;
		XFillArc(dpy, bar_pixmap[5], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[5], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		XFillArc(dpy, bar_pixmap[6], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[7], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);

		y = stone_width * j + stone_width*3/4;
		XFillArc(dpy, bar_pixmap[7], stoneGC[0], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[8], stoneGC[1], 0, y, stone_width-1, stone_width-1, 0, 360*64);
		XFillArc(dpy, bar_pixmap[8], stoneGC[1], 0, y, stone_width,   stone_width,   0, 360*64);
		XDrawArc(dpy, bar_pixmap[8], stoneGC[0], 0, y, stone_width-1, stone_width-1, 0, 360*64);
	}
}
