#ifndef MOVE_H
#define MOVE_H


#include "hash.h"
#include "board.h"
#include "magic.h"

// macros

/* Move Descriptions (moves) are represented internally as integers.
 * The lowest 6 bits define the destination ("TO") square, and
 * the next lowest 6 bits define the source ("FROM") square,
 * using the values defined by "enum Square" (0=a1, 63=h8).
 * Upper bits are used to identify other move information such as
 * a promotion (and to what), a capture (and of what),
 * CASTLING moves, and ENPASSANT moves; see the "constants for
 * move description" below for more information on these upper bits.
 */
#define PROMOTEPIECE(a) ((a >> 12) & 0x0007)
#define CAPTUREPIECE(a) ((a >> 15) & 0x0007)
#define TOSQ(a)         ((a) & 0x003F)
#define FROMSQ(a)       ((a >> 6) & 0x003F)
#define MOVE(f,t)       (((f) << 6) | (t))

/* constants for move description */
#define NOMOVE        0x00000000
#define KNIGHTPRM     0x00002000
#define BISHOPPRM     0x00003000 
#define ROOKPRM       0x00004000
#define QUEENPRM      0x00005000
#define PROMOTION     0x00007000
#define PAWNCAP       0x00008000
#define KNIGHTCAP     0x00010000 
#define BISHOPCAP     0x00018000
#define ROOKCAP       0x00020000 
#define QUEENCAP      0x00028000 
#define CAPTURE       0x00038000 
#define NULLMOVE      0x00100000 
#define CASTLING      0x00200000 
#define ENPASSANT     0x00400000
#define MOVEMASK      (CASTLING | ENPASSANT | PROMOTION | 0x0FFF)

/* constants for move classifier */
#define CLASSCAPTURE             0x00000001
#define CLASSPROMOTION           0x00000002
#define CLASS7RANK               0x00000004
#define CLASS6RANK               0x00000008
#define CLASSPASSEDPAWN          0x00000010
#define CLASSNEGATIVESWAPOFF     0x00000020
#define CLASSPOSITIVESWAPOFF     0x00000040


// types

typedef struct {
    int move;
    short epsq;
    short bflag;
    short Game50;
    HashType hashkey;
    HashType phashkey;
    int mvboard;
    HashType stack;
    int phase;
    int in_check;
    int xin_check;
#ifdef DEBUG
    board_t board;
#endif
} undo_t;

// functions


void MoveMake(board_t *board, int move);
void MoveMakeS(board_t *board, int * move, undo_t *undo);
void MoveUnMakeS (board_t *board, undo_t *undo);
void MoveToSAN(board_t *board, int move, char *SAN);
void MoveListToSAN(board_t *board, int *moves, int gencnt, char *SAN);
void MoveToLAN(int move, char *LAN);
void MoveFromString (board_t *board, int *move, char *s);
int  MoveLookAlike(char *s);
int  MoveIsPseudoLegal(board_t *board, int move);
unsigned int MoveClassifier(board_t *board, int move);
int MoveConnected(int firstmove, int secondmove);
int MoveAvoidThreat(int threat, int defence);

char *AlgbrMove (int move);

#endif
