/*  DreamChess
**
**  DreamChess is the legal property of its developers, whose names are too
**  numerous to list here. Please refer to the AUTHORS.txt file distributed
**  with this source distribution.
**
**  This program is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  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 the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdlib.h>

#include "board.h"
#include "move.h"
#include "repetition.h"

typedef struct rep_list {
	/* FIXME */
	long long position[101 + 100];
	int head;
} rep_list_t;

static rep_list_t *hist;
static int hist_idx;
static rep_list_t *cur_list;

void repetition_init(board_t *board) {
	hist = malloc(sizeof(rep_list_t));
	hist_idx = 0;
	cur_list = &hist[0];
	cur_list->position[0] = board->hash_key;
	cur_list->head = 1;
}

void repetition_exit(void) {
	free(hist);
}

void repetition_add(board_t *board, move_t move) {
	if ((MOVE_GET(move, TYPE) != NORMAL_MOVE) || ((MOVE_GET(move, PIECE) & PIECE_MASK) == PAWN)) {
		hist_idx++;
		hist = realloc(hist, sizeof(rep_list_t) * (hist_idx + 1));
		cur_list = &hist[hist_idx];
		cur_list->position[0] = board->hash_key;
		cur_list->head = 1;
	} else
		cur_list->position[cur_list->head++] = board->hash_key;
}

void repetition_remove(void) {
	if (cur_list->head > 1)
		cur_list->head--;
	else if (hist_idx > 0) {
		hist_idx--;
		cur_list = &hist[hist_idx];
	}
}

int is_repetition(board_t *board, int ply) {
	int i;
	int cur_head = cur_list->head + ply;

	/* We won't go out of bounds here because of the 50-move rule. */
	cur_list->position[cur_head] = board->hash_key;

	if (cur_head < 4)
		return 0;

	/* We only check for two occurrences to prevent transposition table
	** hits that lead to a third repetition without us knowing about it.
	*/
	for (i = cur_head - 2; i >= 0; i -= 2)
		if (board->hash_key == cur_list->position[i])
			return 1;

	return 0;
}

int is_draw(board_t *board) {
	int i;
	int count = 0;

	/* 50 move rule. */
	if (board->fifty_moves == 100)
		return 2;

	if (cur_list->head < 9)
		return 0;

	for (i = cur_list->head - 3; i >= 0; i -= 2) {
		if (cur_list->position[cur_list->head - 1] == cur_list->position[i])
			count++;
		if (count == 2)
			return 1;
	}

	return 0;
}
