#pragma once

#include "core/core.h"
#include "bitboard.h"

enum btt_states
{
    bttEmpty	=	0,
    bttFull		=	1,
    bttAlpha	=	2,
    bttBeta		=	3,
};

// now fits in 16 bytes
class BitTransEntry
{
public:
    u64 hash;				// hash value
    BitMove move;			// best move
    i16 value;				// value (score)
    u8 type;				// (see bttNnnn)
    // new: bit 0-1: type, bits 2-7: search_id
    i8 depth;				// depth

    // convert from relative to absolute value (if_mate)
    inline i16 getValue( i32 ply ) const
    {
        if ( value >= bmate-1000 || value <= -bmate+1000 )
        {
            return value < 0 ? value + ply : value - ply;
        }
        return value;
    }
};

// bitsearch transposition table
class BitTrans
{
protected:
    BitTransEntry *entries;
    BitTransEntry *uaEntries;	// unaligned (=allocated)
    i32 size;
    i32 full;				// full_entries
public:
    i32 searchid;			// search id. incremented every call to search()

    // default: 4MB trans table
    BitTrans( i32 sizeMegs = 4 );

    void clear();

    // returns true on success
    bool resize( i32 sizeMegs );

    // returns entry for hash value
    BitTransEntry *entry( const u64 &hval ) const;

    // returns first entry for hash value
    BitTransEntry *firstEntry( const u64 &hval ) const;

    // store trans entry
    bool store( const u64 &hash, i32 ply, i32 depth, i32 type, i32 value, const BitMove &move );

    // get hash table fullness in permill, 0=0%, 1000=100%
    i32 getFullnessPermill() const;

    // called when new search is about to begin
    void newSearch();

    inline bool isCurrent( const BitTransEntry *e ) const
    {
        return (e->type & 0xfc) == ((searchid << 2) & 0xfc);
    }

    ~BitTrans();
};
