
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>

#define PION_B 1
#define PION_N 2
#define DAME_B 5
#define DAME_N 6
#define COL_B 248
#define COL_N 7

Display* XDisp;
Window win;
XSetWindowAttributes wa;
unsigned long fg, bg, wm;
unsigned long valuemask;
int sn, height, width;
GC XGC;
GC XGCBack;
XGCValues gcv;
XGCValues gcvback;
XColor MyColor;
unsigned int ColorTable[256];
Colormap MyCM;
int TabJeu[12][12];
Font font;

typedef struct
{
  int dep_x;
  int dep_y;
  int arr_x;
  int arr_y;
  int pr_x;
  int pr_y;
  int prise;
  int prec;
  int ev_pos;
} LISTE_MVT;

void rafraichit()
{
  valuemask = 3;
  XSync(XDisp, True);
  XCopyGC(XDisp, XGCBack, GXcopy, XGC);
  XFlush(XDisp);
};

int signe(int x)
{
  if (x < 0) return -1;
  if (x > 0) return 1;
  return 0;
};

int init_fenetre()
{
  int i, r, v, b;

  if ((XDisp = XOpenDisplay(NULL)) == NULL) return True;

  sn = DefaultScreen(XDisp);
  bg = BlackPixel(XDisp, sn);
  fg = WhitePixel(XDisp, sn);
  XSetWindowAttributes wa;
  height = 480;
  width = 640;
  wa.override_redirect = True;
  wa.border_pixel = BlackPixel(XDisp, sn);
  wa.background_pixel = WhitePixel(XDisp, sn);
  wm = CWBackPixel | CWBorderPixel;
  win = XCreateWindow(XDisp, RootWindow(XDisp, sn), 0, 200, width, height, 4, DefaultDepth(XDisp, sn), InputOutput, NULL, wm, &wa);
  XGC = XCreateGC(XDisp, win, 0, &gcv);
  XGCBack = XCreateGC(XDisp, win, 0, &gcvback);
  XMapWindow(XDisp, win);
  XFillRectangle(XDisp, win, XGC, 0, 0, width, height);
  rafraichit();
  MyCM = DefaultColormap(XDisp, sn);

// définit une palette de 256 couleurs
// 2 bits de poids fort pour le rouge
// 3 bits pour le vert
// 3 bits de poids faible pour le bleu
  for (i = 0; i < 256; i++)
  {
    r = (i & 192) / 64;
    v = (i & 56) / 8;
    b = (i & 7);
    MyColor.red = r * 65535 / 3;
    MyColor.green = v * 65535 / 7;
    MyColor.blue = b * 65535 / 7;
    XAllocColor(XDisp, MyCM, &MyColor);
    ColorTable[i] = MyColor.pixel;
  };

  font = XLoadFont(XDisp, "9x15");

  XSetFont(XDisp, XGC, font);
  XSetFont(XDisp, XGCBack, font);

  return 0;
};

void detruit_fenetre()
{
  XDestroyWindow(XDisp, win);
  XCloseDisplay(XDisp);
};

void efface_fenetre(int couleur)
{
  XSetForeground(XDisp, XGCBack, ColorTable[couleur]);
  XSetBackground(XDisp, XGCBack, ColorTable[couleur]);
  XFillRectangle(XDisp, win, XGCBack, 0, 0, 640, 480);
};

void affiche_damier()
{
  char S[10];
  int i, j;

  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if ((i + j) & 1)
      {
        XSetForeground(XDisp, XGCBack, ColorTable[255]);
        XSetBackground(XDisp, XGCBack, ColorTable[0]);
      }
      else
      {
        XSetForeground(XDisp, XGCBack, ColorTable[0]);
        XSetBackground(XDisp, XGCBack, ColorTable[0]);
      };

      XFillRectangle(XDisp, win, XGCBack, 40 * (i + 1), 400 - (j * 40), 40, 40);
    };

    XSetForeground(XDisp, XGCBack, ColorTable[63]);
    XSetBackground(XDisp, XGCBack, ColorTable[63]);
    XFillRectangle(XDisp, win, XGCBack, 20, 400 - (i * 40), 20, 40);
    XFillRectangle(XDisp, win, XGCBack, 440, 400 - (i * 40), 20, 40);
    XFillRectangle(XDisp, win, XGCBack, 40 * (i + 1), 20, 40, 20);
    XFillRectangle(XDisp, win, XGCBack, 40 * (i + 1), 440, 40, 20);
    XSetForeground(XDisp, XGCBack, ColorTable[0]);

    sprintf(S, "%d", i + 1);

    XDrawImageString(XDisp, win, XGCBack, i * 40 + 60 - 9 * strlen(S) / 2, 35, S, strlen(S));
    XDrawImageString(XDisp, win, XGCBack, i * 40 + 60 - 9 * strlen(S) / 2, 455, S, strlen(S));

    sprintf(S, "%c", i + 65);

    XDrawImageString(XDisp, win, XGCBack, 26, 424 - i * 40, S, 1);
    XDrawImageString(XDisp, win, XGCBack, 445, 424 - i * 40, S, 1);
    XSetBackground(XDisp, XGCBack, ColorTable[0]);
    XDrawRectangle(XDisp, win, XGCBack, 20, 400 - (i * 40), 20, 40);
    XDrawRectangle(XDisp, win, XGCBack, 440, 400 - (i * 40), 20, 40);
    XDrawRectangle(XDisp, win, XGCBack, 40 * (i + 1), 20, 40, 20);
    XDrawRectangle(XDisp, win, XGCBack, 40 * (i + 1), 440, 40, 20);
  };

  XSetForeground(XDisp, XGCBack, ColorTable[63]);
  XSetBackground(XDisp, XGCBack, ColorTable[63]);
  XFillRectangle(XDisp, win, XGCBack, 21, 21, 19, 19);
  XFillRectangle(XDisp, win, XGCBack, 21, 441, 19, 19);
  XFillRectangle(XDisp, win, XGCBack, 441, 21, 19, 19);
  XFillRectangle(XDisp, win, XGCBack, 441, 441, 19, 19);
  XSetForeground(XDisp, XGCBack, ColorTable[0]);
  XSetBackground(XDisp, XGCBack, ColorTable[0]);
  XDrawRectangle(XDisp, win, XGCBack, 20, 20, 440, 440);
};

void dessine_pion(int x, int y, int c)
{
  int rx = 18;
  int ry = 10;
  int k = 0;
  XSetForeground(XDisp, XGCBack, ColorTable[c]);
  XSetBackground(XDisp, XGCBack, ColorTable[c]);

  for (k = 2; k >= -2; k--)
    XFillArc(XDisp, win, XGCBack, x - rx, y - ry + k, rx * 2, ry * 2, 0, 64 * 360);

  XSetForeground(XDisp, XGCBack, ColorTable[0]);
  XSetBackground(XDisp, XGCBack, ColorTable[0]);
  XDrawArc(XDisp, win, XGCBack, x - rx, y - ry - 2, rx * 2, ry * 2, 180 * 64, 180 * 64);
};

void dessine_dame(int x, int y, int c)
{
  int rx = 18;
  int ry = 10;
  int k = 0;
  XSetForeground(XDisp, XGCBack, ColorTable[c]);
  XSetBackground(XDisp, XGCBack, ColorTable[c]);

  for (k = 4; k >= -4; k--)
    XFillArc(XDisp, win, XGCBack, x - rx, y - ry + k, rx * 2, ry * 2, 0, 64 * 360);

  XSetForeground(XDisp, XGCBack, ColorTable[0]);
  XSetBackground(XDisp, XGCBack, ColorTable[0]);
  XDrawArc(XDisp, win, XGCBack, x - rx, y - ry - 4, rx * 2, ry * 2, 180 * 64, 180 * 64);
  XDrawArc(XDisp, win, XGCBack, x - rx, y - ry, rx * 2, ry * 2, 180 * 64, 180 * 64);
};

void affiche_pions(int TabJeu[12][12])
{
  int i, j, x, y;

  for (i = 1; i <= 10; i++)
  {
    x = 20 + i * 40;

    for (j = 1; j <= 10; j++)
    {
      y = 460 - j * 40;

      if (TabJeu[i][j] == PION_B)
      {
        dessine_pion(x, y, COL_B);
      };

      if (TabJeu[i][j] == PION_N)
      {
        dessine_pion(x, y, COL_N);
      };

      if (TabJeu[i][j] == DAME_B)
      {
        dessine_dame(x, y, COL_B);
      };

      if (TabJeu[i][j] == DAME_N)
      {
        dessine_dame(x, y, COL_N);
      };
    };
  };

  rafraichit();
};

void affiche_tout(int TabJeu[12][12])
{
  efface_fenetre(17);
  affiche_damier();
  affiche_pions(TabJeu);
  rafraichit();
};

void anim_pion(int p, int i, int j, int k, int l, int TabJeu[12][12])
{
  int x1, y1, x2, y2, t, u;
  x1 = 20 + i * 40;
  y1 = 460 - j * 40;
  x2 = 20 + k * 40;
  y2 = 460 - l * 40;
  t = (int)sqrt(((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) / 2);

  for (u = 0; u <= t; u++)
  {
    affiche_tout(TabJeu);

    switch (p)
    {
    case PION_N:
      dessine_pion(x1 + ((x2 - x1)*u) / t, y1 + ((y2 - y1)*u) / t, COL_N);
      break;

    case DAME_N:
      dessine_dame(x1 + ((x2 - x1)*u) / t, y1 + ((y2 - y1)*u) / t, COL_N);
      break;
    };

    rafraichit();

    usleep(5000);
  };
};

void affiche_mvt_b(LISTE_MVT mvt_b[256], int ptr_mvt_b[1])
{
  int i, x1, y1, x2, y2;
  XSetForeground(XDisp, XGCBack, ColorTable[216]);
  XSetBackground(XDisp, XGCBack, ColorTable[216]);

  for (i = 1; i <= ptr_mvt_b[0]; i++)
  {
    if ((mvt_b[i].dep_x != 0) && (mvt_b[i].dep_y != 0))
    {
      x1 = mvt_b[i].dep_x * 40 + 20;
      y1 = 460 - mvt_b[i].dep_y * 40;
      x2 = mvt_b[i].arr_x * 40 + 20;
      y2 = 460 - mvt_b[i].arr_y * 40;

      if (x1 < x2)
      {
        x1 = x1 + 5;
        x2 = x2 - 5;
      }
      else
      {
        x2 = x2 + 5;
        x1 = x1 - 5;
      };

      if (y1 < y2)
      {
        y1 = y1 + 5;
        y2 = y2 - 5;
      }
      else
      {
        y2 = y2 + 5;
        y1 = y1 - 5;
      };

      XDrawLine(XDisp, win, XGCBack, x1, y1, x2, y2);
      XDrawLine(XDisp, win, XGCBack, x2, y2, x2, y2 + signe(y1 - y2) * 8);
      XDrawLine(XDisp, win, XGCBack, x2, y2, x2 + signe(x1 - x2) * 8, y2);
    };
  };

  rafraichit();
};
