#include <string.h>

#include "util.h"
#include "eval.h"
#include "material.h"
#include "piece.h"

int MaterialDelta[2][8];
material_slot_t  Material[MATERIAL_SIZE];

static void MaterialDeltaInit(void){
    MaterialDelta[white][queen]=                     1;
    MaterialDelta[white][rook]=                      2;
    MaterialDelta[white][knight]=                  3*2;
    MaterialDelta[white][bishop]=                3*3*2;
    MaterialDelta[white][pawn]=                3*3*3*2;

    MaterialDelta[black][queen]=             9*3*3*3*2;
    MaterialDelta[black][rook]=            2*9*3*3*3*2;
    MaterialDelta[black][knight]=        3*2*9*3*3*3*2;
    MaterialDelta[black][bishop]=      3*3*2*9*3*3*3*2;
    MaterialDelta[black][pawn]=      3*3*3*2*9*3*3*3*2;
}



void MaterialFromIndex(int material[2][8],int index){
    int saveindex;
    saveindex=index;

    material[white][queen]=   index%2;
    index/=2;
    material[white][rook] =   index%3;
    index/=3;
    material[white][knight] = index%3;
    index/=3;
    material[white][bishop] = index%3;
    index/=3;
    material[white][pawn] =   index%9;
    index/=9;

    material[black][queen]=   index%2;
    index/=2;
    material[black][rook] =   index%3;
    index/=3;
    material[black][knight] = index%3;
    index/=3;
    material[black][bishop] = index%3;
    index/=3;
    material[black][pawn] =   index%9;

    ASSERT((index/9)==0);;
    ASSERT(saveindex==MaterialToIndex(material));
}

int MaterialToIndex(int material[2][8]){
    int color;
    enum Piece piece;
    int sum=0;
    for(color=white;color<=black;color++){
	for(piece=pawn;piece<=queen;piece++){
	    sum+=material[color][piece]*MaterialDelta[color][piece];
	}
    }
    return sum;
}


void MaterialInit(void){
    int index;
    int color, xcolor;
    int material[2][8];
    int m[2];
    int piece;
    int piece_weight;

    MaterialDeltaInit();

    memset(Material,0,sizeof(Material));
    
    for(index=0;index<MATERIAL_SIZE;index++){
	MaterialFromIndex(material,index);
	for(color=white;color<=black;color++){
	    m[color]=
		material[color][pawn]   *ValueP+
		material[color][knight] *ValueN+
		material[color][bishop] *ValueB+
		material[color][rook]   *ValueR+
		material[color][queen]  *ValueQ;
	}
	// temporary
	Material[index].phase= (MAX(0,(8 - (m[white]+m[black]) / 1150)));

	// feeble attempt to encourage trading down pieces and not pawns when we're ahead

	piece_weight=0;
	for(piece=knight;piece<=queen;piece++){
	    piece_weight-=(material[white][piece]+material[black][piece])*TRADEPIECE;
	}
	piece_weight+=(material[white][pawn]+material[black][pawn])*TRADEPAWNS;

	if(m[white]-m[black]>=200){
	    Material[index].score+=piece_weight;
	}else if(m[white]-m[black]<=-200){
	    Material[index].score-=piece_weight;
	}

	for(color=white;color<=black;color++){
	    xcolor=1^color;

	    // should be else if's but this is more readable

	    if(m[color]==ValueP && m[xcolor]==0){
		Material[index].recog=MATERIAL_KPK;
	    }
	    if(m[color]==ValueB+material[color][pawn]*ValueP && material[color][bishop]==1 && m[xcolor]==material[xcolor][pawn]*ValueP){
		Material[index].recog=MATERIAL_KBPK;
	    }
	    if(m[color]==ValueQ && material[color][queen]==1 && m[xcolor]==ValueP){
		Material[index].recog=MATERIAL_KQKP;
	    }
	    if(m[color]==ValueN && material[color][knight]==1 && m[xcolor]==0){
		Material[index].recog=MATERIAL_KNK;
	    }
	    if(m[color]==ValueB && material[color][bishop]==1 && m[xcolor]==0){
		Material[index].recog=MATERIAL_KBK;
	    }
	    if(m[color]==ValueB+ValueN && material[color][bishop]==1 && material[color][knight]==1 && m[xcolor]==0){
		Material[index].recog=MATERIAL_KBNK;
	    }
	    if(m[color]==ValueN+ValueN && material[color][knight]==1 && m[xcolor]==0){
		Material[index].recog=MATERIAL_KNNK;
	    }
	    if(m[color]==ValueB && material[color][bishop]==1 && m[xcolor]==ValueB && material[xcolor][bishop]==1){
		Material[index].recog=MATERIAL_KBKB;
	    }
	    if(m[color]==ValueB && material[color][bishop]==1 && m[xcolor]==ValueN && material[xcolor][knight]==1){
		Material[index].recog=MATERIAL_KBKN;
	    }
	    if(m[color]==ValueN && material[color][knight]==1 && m[xcolor]==ValueN && material[xcolor][knight]==1){
		Material[index].recog=MATERIAL_KNKN;
	    }
	    if(Material[index].recog!=0 && color==black){
		Material[index].flags|=MATERIAL_WINNER_BLACK;
	    }
	}	
	
    }
}
