#ifndef SORT_H_INCLUDED
#define SORT_H_INCLUDED

#include <stdint.h>
#include "move.h"
#include "position.h"
#include "history.h"

// bubble the best move to the top
void sort_2_top(MOVE* mv, int best);

// sort the moves in decreasing order
void sort_array(MOVE* mv, int n);

// gather the forcing moves: smallest recapture first, MVV-LVA and delta pruning
int sort_forcing(const POSITION* pos, MOVE* mv, int n, int delta);

// move generation stages
typedef enum {GS_START, GS_HASH, GS_FORCING, GS_OTHER} GENSTAGE;

// the sort state data type
typedef uint32_t SORTSTATE;
#define SS_GET_GS(ss) ((ss) >> 16)
#define SS_GET_N1(ss) ((ss) & 0xFF)
#define SS_GET_N2(ss) (((ss) & 0xFF00) >> 8)
#define SS_NEW(gs, n1, n2) (((gs) << 16) | ((n2) << 8) | (n1))
#define SS_START SS_NEW(GS_START, 0, 0)

// sort by history heuristic
void sort_quiet(const POSITION* pos, MOVE* mv, HISTORYTABLE* hy, int n);

// generate and sort moves on the fly
int sort_more_mv(const POSITION* pos, MOVE* mv, HISTORYTABLE* hy, SORTSTATE* ss, int i);

// test the functions above
int sort_test();

#endif // SORT_H_INCLUDED
