// Copyright 1994, 1995, 1996 by Jon Dart.  All Rights Reserved.

#include "stdafx.h"
#include "options.h"
#include <stdlib.h> // for atoi

static const char *keys[] = 
  { "Primary Time Control", "Secondary Time Control" };

static const char *src_names[] =
  { "Ply", "Time", "Target", "Game", "Tournament", "Incremental", "None", 0 };

#ifdef _WINDOWS
void Options::get_src_opts( CWinApp *app, const Control c,
   Search_Type &my_search_type, Search_Limit &my_search_limit)
{

   CString opt_str = app->GetProfileString(keys[c],"Search Type",
        (c == First) ? "Ply" : "None");

   const char **p = src_names;
   int type = 0;
   while (*p)
   {
      if (opt_str.Compare(*p)==0)
         break;
      ++type; ++p;
   }
   ASSERT(type < 7);
   my_search_type = (Search_Type)type;
   switch (type)
   {
   case 0:
      opt_str = app->GetProfileString(keys[c],"ply","2");
      my_search_limit.max_ply = atoi((LPCSTR)opt_str);            
      break;
   case 1:
   case 2:
      opt_str = app->GetProfileString(keys[c],"Seconds","60");
      my_search_limit.centiseconds = 100*atoi((LPCSTR)opt_str);
      break;
   case 3:
      opt_str = app->GetProfileString(keys[c],"Minutes","60");
      my_search_limit.limit.minutes = atoi((LPCSTR)opt_str);
      break;
   case 4:
      opt_str = app->GetProfileString(keys[c],"Moves","60");
      my_search_limit.limit.moves = atoi((LPCSTR)opt_str);
      opt_str = app->GetProfileString(keys[c],"Minutes","60");
      my_search_limit.limit.minutes = atoi((LPCSTR)opt_str);
      break;
   case 5:
      opt_str = app->GetProfileString(keys[c],"Minutes","2");
      my_search_limit.limit.minutes = atoi((LPCSTR)opt_str);
      opt_str = app->GetProfileString(keys[c],"Increment","12");
      my_search_limit.limit.increment = atoi((LPCSTR)opt_str);
   default:
      break;
   }
}

void Options::set_src_opts( CWinApp *app, const Control c,
       const Search_Type my_search_type,
       const Search_Limit &my_search_limit)
{
   char msg[40];
   myApp->WriteProfileString(keys[c],"Search Type",src_names[my_search_type]);
   switch (my_search_type)
   {
    case Fixed_Ply:
      wsprintf(msg,"%d",my_search_limit.max_ply);
      app->WriteProfileString(keys[c],"ply",msg);
      break;
   case Time_Limit:
      wsprintf(msg,"%ld",my_search_limit.centiseconds/100);
      app->WriteProfileString(keys[c],"Seconds",msg);
      break;
   case Game:
      wsprintf(msg,"%d",my_search_limit.limit.minutes);
      app->WriteProfileString(keys[c],"Minutes",msg);
      break;
   case Tournament:
      wsprintf(msg,"%d", my_search_limit.limit.moves);
      app->WriteProfileString(keys[c],"Moves",msg);
      wsprintf(msg,"%d", my_search_limit.limit.minutes);
      app->WriteProfileString(keys[c],"Minutes",msg);
      break;
   case Incremental:
      wsprintf(msg,"%d", my_search_limit.limit.minutes);
      app->WriteProfileString(keys[c],"Minutes",msg);
      wsprintf(msg,"%d", my_search_limit.limit.increment);
      app->WriteProfileString(keys[c],"Increment",msg);
      break;
   case None:
      app->WriteProfileString(keys[c],"Search Type","None");
   }
}
#endif

#ifdef _WINDOWS
Options::Options(CWinApp *app)
:myApp(app)
{
   Search_Limit my_search_limit;
   Search_Type my_search_type;
   CString opt_str;
   get_src_opts(app,First, my_search_type, my_search_limit);
   tc[0] = Time_Control(my_search_type, my_search_limit);
   get_src_opts(app,Second, my_search_type, my_search_limit );
   tc[1] = Time_Control(my_search_type, my_search_limit);
   opt_str = app->GetProfileString("Preferences","Beep After Move","True");
   gprefs.beep_after_move = opt_str == "True";
   opt_str = app->GetProfileString("Preferences","Beep On Error","True");
   gprefs.beep_on_error = opt_str == "True";
   opt_str = app->GetProfileString("Preferences","Can Resign","True");
   gprefs.can_resign = opt_str == "True";
   opt_str = app->GetProfileString("Preferences","Think When Idle","True");
   gprefs.think_when_idle = opt_str == "True";
   opt_str = app->GetProfileString("Preferences","Use Opening Book","True");
   oprefs.use_book = opt_str == "True";
   oprefs.style = (styles)app->GetProfileInt("Preferences","Opening Style",0);
   appX = app->GetProfileInt("Location","x",100);
   if (appX <= 0)
      appX = 100;
   appY = app->GetProfileInt("Location","y",50);
   if (appY <= 0)
      appY = 50;
   appW = app->GetProfileInt("Location","width",400);
   if (appW <= 0)
      appW = 400;
   appH = app->GetProfileInt("Location","height",400);
   if (appH <= 0)
      appH = 400;
   // get "advanced" search options:
   src_opts.null_depth =
     app->GetProfileInt("Advanced","NullDepth",2);
   opt_str =
     app->GetProfileString("Advanced","CheckExtensions","True");
   src_opts.killers =
     app->GetProfileInt("Advanced","Killers",2);
   opt_str =
     app->GetProfileString("Advanced","CheckExtensions","True");
   src_opts.check_extensions = opt_str == "True";
   opt_str =
     app->GetProfileString("Advanced","ForcedExtensions","True");
   src_opts.forced_extensions = opt_str == "True";
   opt_str =
     app->GetProfileString("Advanced","PawnPushExtensions","True");
   src_opts.pawn_push_extensions = opt_str == "True";
   opt_str =
     app->GetProfileString("Advanced","History","True");
   src_opts.history = opt_str == "True";
   opt_str =
     app->GetProfileString("Advanced","AutoSizeHashTable","True");
   src_opts.auto_size_hash_table = opt_str == "True";
   src_opts.hash_table_size =
     app->GetProfileInt("Advanced","HashTableSize",4000);

   opt_str = app->GetProfileString("Colors","light","80ffff");
#ifdef _WIN32
   sscanf((LPCSTR)opt_str,"%x",&lightColor);
#else
   sscanf((LPCSTR)opt_str,"%lx",&lightColor);
#endif   
   opt_str = app->GetProfileString("Colors","dark","408080");
#ifdef _WIN32
   sscanf((LPCSTR)opt_str,"%x",&darkColor);
#else
   sscanf((LPCSTR)opt_str,"%lx",&darkColor);
#endif   
}

#else // _WINDOWS

Options::Options()
{
   Search_Limit my_search_limit;
   Search_Type my_search_type;
   // set some default options
   my_search_type = Fixed_Ply;
   my_search_limit.max_ply = 2;
   gprefs.beep_after_move = TRUE;
   gprefs.beep_on_error = TRUE;
   gprefs.can_resign = TRUE;
   gprefs.think_when_idle = FALSE;
   oprefs.use_book = TRUE;
   oprefs.style = Balanced;
   tc[0] = Time_Control(Fixed_Ply,my_search_limit);
   tc[1] = Time_Control(None,my_search_limit);
   src_opts.null_depth = 2;
   src_opts.killers = 2;
   src_opts.history = TRUE;
   src_opts.check_extensions = TRUE;
   src_opts.pawn_push_extensions = TRUE;
   src_opts.forced_extensions = TRUE;
   src_opts.history = TRUE;
   src_opts.auto_size_hash_table = FALSE;
   src_opts.hash_table_size = 4000; // 4 Megabytes
}

#endif

Options::~Options()
{
#ifdef _WINDOWS
   save();
#endif   
}

void Options::get_general_preferences( GeneralPreferences &p )
{
    p = gprefs;
}

void Options::update_general_preferences( const GeneralPreferences &p)
{
    gprefs = p;
}

void Options::get_opening_preferences( OpeningPreferences &p )
{
    p = oprefs;
}

void Options::update_opening_preferences( const OpeningPreferences &p)
{
    oprefs = p;
}

void Options::update_search_ops( const SearchOps &s)
{
    src_opts = s;
}
   
void Options::get_search_ops( SearchOps &ops) const
{
    ops = src_opts;
}   

#ifdef _WINDOWS
void Options::set_app_geometry(int x, int y, int w, int h)
{
   appX = x; appY = y; appW = w; appH = h;
}
   
void Options::get_app_geometry(int *x, int *y, int *w, int *h)
{
   *x = appX; *y = appY; *w = appW; *h = appH;
};

void Options::get_colors(COLORREF *light, COLORREF *dark)
{
   *light = lightColor; *dark = darkColor;
}
   
void Options::set_colors(COLORREF light, COLORREF dark)
{
   lightColor = light; darkColor = dark;
}

#endif
        
#ifdef _WINDOWS
void Options::save()
{
   set_src_opts(myApp,First,tc[0].get_search_type(),
     tc[0].get_search_limit());
   set_src_opts(myApp,Second,tc[1].get_search_type(),
     tc[1].get_search_limit());
   static const char *boolImage[2] = { "False", "True" };
   myApp->WriteProfileString("Preferences","Beep After Move",
      boolImage[(int)beep_after_move()]);
   myApp->WriteProfileString("Preferences","Beep On Error",
      boolImage[(int)beep_on_error()]);
   myApp->WriteProfileString("Preferences","Can Resign",
      boolImage[(int)can_resign()]);
   myApp->WriteProfileString("Preferences","Think When Idle",
      boolImage[(int)think_when_idle()]);
   myApp->WriteProfileString("Preferences","Use Opening Book",
      boolImage[(int)use_book()]);
   myApp->WriteProfileInt("Preferences","Opening Style",book_style());

   myApp->WriteProfileInt("Advanced","NullDepth",
      src_opts.null_depth);
   myApp->WriteProfileInt("Advanced","Killers",
      src_opts.killers);
   myApp->WriteProfileString("Advanced","CheckExtensions",
      boolImage[(int)src_opts.check_extensions]);
   myApp->WriteProfileString("Advanced","PawnPushExtensions",
      boolImage[(int)src_opts.pawn_push_extensions]);
   myApp->WriteProfileString("Advanced","ForcedExtensions",
      boolImage[(int)src_opts.forced_extensions]);
   myApp->WriteProfileString("Advanced","History",
      boolImage[(int)src_opts.history]);
   myApp->WriteProfileString("Advanced","AutoSizeHashTable",
      boolImage[(int)src_opts.auto_size_hash_table]);
   myApp->WriteProfileInt("Advanced","HashTableSize",src_opts.hash_table_size);

   myApp->WriteProfileInt("Location","x",appX);
   myApp->WriteProfileInt("Location","y",appY);
   myApp->WriteProfileInt("Location","width",appW);
   myApp->WriteProfileInt("Location","height",appH);

   static char buf[20];
#ifdef _WIN32
   wsprintf(buf,"%x",lightColor);
#else
   wsprintf(buf,"%lx",lightColor);
#endif   
   myApp->WriteProfileString("Colors","light",buf);
#ifdef _WIN32   
   wsprintf(buf,"%x",darkColor);
#else
   wsprintf(buf,"%lx",darkColor);
#endif   
   myApp->WriteProfileString("Colors","dark",buf);
}
#endif
