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

#include "chess.h"
#include "utils.h"
#include "image.h"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#define TARGET_SQUARES_COLOR 0.0, 0.5, 0.0, 0.5

void create_position_image(const struct t_position position, const struct t_position_info info, const struct t_move* moves, size_t array_size)
{
  int x, y, i;
  cairo_pattern_t* pat;
  int center_x, center_y;
  
  create_images();
  
  cairo_surface_t* chessboard_sfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 11 * 36, 9 * 36);
  cairo_t* chessboard_ctx = cairo_create(chessboard_sfc);
  
  cairo_surface_t* extra_sfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10 * 36, 8 * 36);
  cairo_t* extra_ctx = cairo_create(extra_sfc);
  
  cairo_select_font_face(chessboard_ctx, CHESSBOARD_FONT, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(chessboard_ctx, 12);
  
  cairo_set_source_rgb(chessboard_ctx, BORDER_COLOR);
  cairo_paint(chessboard_ctx);
  
  draw_empty_chessboard(chessboard_ctx);
  
/* ------------------------------------------------------------------ */
  
  if (info.check)
  {
    cairo_set_source_rgba(extra_ctx, 1.0, 0.0, 0.0, 0.4);
    sqr2xy(info.king_square, &x, &y);
    
    center_x = 36 * x + 18;
    center_y = 36 * (7 - y) + 18;
    pat = cairo_pattern_create_radial (center_x, center_y, 16, center_x, center_y, 20);
    cairo_pattern_add_color_stop_rgba (pat, 0, 1.0, 0.0, 0.0, 0.6);
    cairo_pattern_add_color_stop_rgba (pat, 1, 1.0, 0.0, 0.0, 0.0);
    cairo_set_source (extra_ctx, pat);
    
    //cairo_arc(extra_ctx, 36 * x + 18, 36 * (7 - y) + 18, 18, 0.0, 2 * M_PI);
    cairo_rectangle(extra_ctx, 36 * x, 36 * (7 - y), 36, 36);
    cairo_fill(extra_ctx);
  }
  
/* ------------------------------------------------------------------ */
  
  //cairo_set_source_rgba(extra_ctx, TARGET_SQUARES_COLOR);
  
  for (i = 0; i < array_size; i ++)
  {
    if (moves[i].capture)
    {
      cairo_set_source_rgba(extra_ctx, TARGET_SQUARES_COLOR);
    }
    else
    {
      cairo_set_source_rgba(extra_ctx, TARGET_SQUARES_COLOR);
    }
    sqr2xy(moves[i].from, &x, &y);
    cairo_arc(extra_ctx, 36 * x + 18, 36 * (7 - y) + 18, 15, 0.0, 2 * M_PI);
    cairo_fill(extra_ctx);
    sqr2xy(moves[i].to, &x, &y);
    cairo_arc(extra_ctx, 36 * x + 18, 36 * (7 - y) + 18, 18, 0.0, 2 * M_PI);
    cairo_fill(extra_ctx);
    
    sqr2xy(moves[i].from, &x, &y);
    cairo_move_to(extra_ctx, 36 * x + 18, 36 * (7 - y) + 18);
    sqr2xy(moves[i].to, &x, &y);
    cairo_line_to(extra_ctx, 36 * x + 18, 36 * (7 - y) + 18);
    cairo_stroke(extra_ctx);
    
  }
  
  cairo_set_source_surface(chessboard_ctx, extra_sfc, 18, 18);
  cairo_paint(chessboard_ctx);

/* ------------------------------------------------------------------ */

  for (y = 7; y >= 0; y --)
  {
    for (x = 0; x <= 9; x ++)
    {
      i = xy2sqr(x, y);
      if (position.board[i] != EMPTY_SQUARE && position.board[i] != BORDER)
      {
        draw_chesspiece(chessboard_ctx, position.board[i], 36 * x + 18, 36 * (7 - y) + 18);
      }
    }
  }
  
  cairo_destroy(chessboard_ctx);
  cairo_destroy(extra_ctx);
  
  cairo_surface_write_to_png(chessboard_sfc, "demo_image3.png");
  
  free_images();
  
  cairo_surface_destroy(chessboard_sfc);
  cairo_surface_destroy(extra_sfc);
}

#define STARTPOS_CLASSICAL "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
#define STARTPOS_CAPABLANCA "rnabqkbcnr/pppppppppp/10/10/10/10/PPPPPPPPPP/RNABQKBCNR w KQkq - 0 1"

int main(int argc, char *argv[])
{
  struct t_position position;
  char fen_i[256];
  const char sample[] = "5k4/10/10/9b/7N2/10/9P/5K4 w - - 0 1";
  struct t_move moves[256];
  int movecount, i;
  char move_str[6];
  struct t_position_info info;
  
  erase_position(&position);
  
  if (argc > 1) { strcpy(fen_i, argv[1]); } else { strcpy(fen_i, sample); }
  load_position_from_fen(&position, fen_i);
  
  prettyprint_position(position);
  printf("\n");
  
  info = get_position_info(&position, 0);
  
  print_info(info);
  printf("\n");
  
  movecount = generate_legal_moves(position, info, moves, sizeof(moves) / sizeof(struct t_move), 0);
  
  create_position_image(position, info, moves, movecount);
  
  for (i = 0; i < movecount; i ++)
  {
    move2str(moves[i], move_str, sizeof(move_str));
    printf("%-6s", move_str);
    if ((i + 1) % 12 == 0 || i == movecount - 1)
    {
      printf("\n");
    }
  }
  
  return 0;
}
