// Copyright 1994 by Jon Dart

#include "stdafx.h"
#include "eco.h"
#include "ecodata.h"
#include "ecoinfo.h"

#define HASHSIZE 61

ECO::ECO()
{
   ht = new Hash(HASHSIZE,1000);
// fill up hash table
   for (const eco_data *d = eco_codes; d->eco; d++)
   {
        ECO_Info *ei = new ECO_Info(d->eco, d->opening_name, d->hash_code);
        ht->insert(ei,TRUE);
   }
}

ECO::~ECO()
{
   ECO_Info::freeAll(TRUE);
   delete ht;
}

void ECO::classify( const Move_Array &moves, CString &result, CString &name)
{
    // We take kind of a simple-minded approach to ECO classification.
    // Each ECO code is associated with a chess position.  We follow the
    // game moves until we have found the last one that leads to a
    // hash code matching an ECO position, then report that ECO code.
    // This doesn't allow for openings that eventually transpose into
    // an ECO subline (e.g. A04/01) but don't ever hit the position
    // for the main ECO code (e.g. A04) - this is possible.     
    result = "";
    name = "";
    for ( unsigned i = 0; i < moves.num_moves(); i++)
    {
        ECO_Info ei(NULL, NULL, moves[i].hashcode());
        ECO_Info *hit = (ECO_Info*)(ht->search(ei));
        if (hit)
        {
           char *p = result.GetBuffer(4);
           strncpy(p,hit->get_eco(),3);
	   p[3] = '\0';
	   result.ReleaseBuffer();
           // Not all ECO lines have opening names.
           if (*hit->get_opening_name())
	      name = hit->get_opening_name();
        }
    }
}
