cross compilier working
[xboard.git] / backend.c
index e9ae20f..84937ae 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -107,6 +107,16 @@ extern int gettimeofday(struct timeval *, struct timezone *);
 # include "zippy.h"
 #endif
 #include "backendz.h"
+#include "gettext.h"
+
+#ifdef ENABLE_NLS
+# define  _(s) gettext (s)
+# define N_(s) gettext_noop (s)
+#else
+# define  _(s) (s)
+# define N_(s)  s
+#endif
+
 
 /* A point in time */
 typedef struct {
@@ -121,7 +131,7 @@ typedef struct {
   int nr_moves;           /* Total nr of root moves */
   int moves_left;         /* Moves remaining to be searched */
   char move_name[MOVE_LEN];  /* Current move being searched, if provided */
-  unsigned long nodes;    /* # of nodes searched */
+  u64 nodes;                     /* # of nodes searched */
   int time;               /* Search time (centiseconds) */
   int score;              /* Score (centipawns) */
   int got_only_move;      /* If last msg was "(only move)" */
@@ -202,6 +212,11 @@ void ParseFeatures P((char* args, ChessProgramState *cps));
 void InitBackEnd3 P((void));
 void FeatureDone P((ChessProgramState* cps, int val));
 void InitChessProgram P((ChessProgramState *cps));
+double u64ToDouble P((u64 value));
+
+#ifdef WIN32
+       extern void ConsoleCreate();
+#endif
 
 extern int tinyLayout, smallLayout;
 static ChessProgramStats programStats;
@@ -245,6 +260,26 @@ static ChessProgramStats programStats;
 #define TN_SGA  0003
 #define TN_PORT 23
 
+/* Some compiler can't cast u64 to double
+ * This function do the job for us:
+
+ * We use the highest bit for cast, this only
+ * works if the highest bit is not
+ * in use (This should not happen)
+ *
+ * We used this for all compiler
+ */
+double
+u64ToDouble(u64 value)
+{
+  double r;
+  u64 tmp = value & u64Const(0x7fffffffffffffff);
+  r = (double)(s64)tmp;
+  if (value & u64Const(0x8000000000000000))
+       r +=  9.2233720368547758080e18; /* 2^63 */
+ return r;
+}
+
 /* Fake up flags for now, as we aren't keeping track of castling
    availability yet */
 int
@@ -291,12 +326,8 @@ int gotPremove = 0;
 Boolean alarmSounded;
 /* end premove variables */
 
-#define ICS_GENERIC 0
-#define ICS_ICC 1
-#define ICS_FICS 2
-#define ICS_CHESSNET 3 /* not really supported */
-int ics_type = ICS_GENERIC;
 char *ics_prefix = "$";
+int ics_type = ICS_GENERIC;
 
 int currentMove = 0, forwardMostMove = 0, backwardMostMove = 0;
 int pauseExamForwardMostMove = 0;
@@ -431,7 +462,7 @@ InitBackEnd1()
     if (appData.icsActive) {
        appData.matchMode = FALSE;
        appData.matchGames = 0;
-#if ZIPPY      
+#if ZIPPY
        appData.noChessProgram = !appData.zippyPlay;
 #else
        appData.zippyPlay = FALSE;
@@ -452,7 +483,7 @@ InitBackEnd1()
     if (!ParseTimeControl(appData.timeControl, appData.timeIncrement,
                          appData.movesPerSession)) {
        char buf[MSG_SIZ];
-       sprintf(buf, "bad timeControl option %s", appData.timeControl);
+       sprintf(buf, _("bad timeControl option %s"), appData.timeControl);
        DisplayFatalError(buf, 0, 2);
     }
 
@@ -467,11 +498,11 @@ InitBackEnd1()
            searchTime = min * 60 + sec;
        } else {
            char buf[MSG_SIZ];
-           sprintf(buf, "bad searchTime option %s", appData.searchTime);
+           sprintf(buf, _("bad searchTime option %s"), appData.searchTime);
            DisplayFatalError(buf, 0, 2);
        }
     }
-    
+
     first.which = "first";
     second.which = "second";
     first.maybeThinking = second.maybeThinking = FALSE;
@@ -526,7 +557,7 @@ InitBackEnd1()
     if (appData.firstProtocolVersion > PROTOVER ||
        appData.firstProtocolVersion < 1) {
       char buf[MSG_SIZ];
-      sprintf(buf, "protocol version %d not supported",
+      sprintf(buf, _("protocol version %d not supported"),
              appData.firstProtocolVersion);
       DisplayFatalError(buf, 0, 2);
     } else {
@@ -536,7 +567,7 @@ InitBackEnd1()
     if (appData.secondProtocolVersion > PROTOVER ||
        appData.secondProtocolVersion < 1) {
       char buf[MSG_SIZ];
-      sprintf(buf, "protocol version %d not supported",
+      sprintf(buf, _("protocol version %d not supported"),
              appData.secondProtocolVersion);
       DisplayFatalError(buf, 0, 2);
     } else {
@@ -549,7 +580,7 @@ InitBackEnd1()
        appData.clockMode = FALSE;
        first.sendTime = second.sendTime = 0;
     }
-    
+
 #if ZIPPY
     /* Override some settings from environment variables, for backward
        compatibility.  Unfortunately it's not feasible to have the env
@@ -559,7 +590,7 @@ InitBackEnd1()
       ZippyInit();
     }
 #endif
-    
+
     if (appData.noChessProgram) {
        programVersion = (char*) malloc(5 + strlen(PRODUCT) + strlen(VERSION)
                                        + strlen(PATCHLEVEL));
@@ -587,7 +618,7 @@ InitBackEnd1()
       case VariantBughouse:     /* need four players and two boards */
       case VariantKriegspiel:   /* need to hide pieces and move details */
       case VariantFischeRandom: /* castling doesn't work, shuffle not done */
-       sprintf(buf, "Variant %s supported only in ICS mode", appData.variant);
+       sprintf(buf, _("Variant %s supported only in ICS mode"), appData.variant);
        DisplayFatalError(buf, 0, 2);
        return;
 
@@ -602,7 +633,7 @@ InitBackEnd1()
       case Variant35:
       case Variant36:
       default:
-       sprintf(buf, "Unknown variant name %s", appData.variant);
+       sprintf(buf, _("Unknown variant name %s"), appData.variant);
        DisplayFatalError(buf, 0, 2);
        return;
 
@@ -685,14 +716,19 @@ InitBackEnd3 P((void))
 
     InitChessProgram(&first);
 
+    #ifdef WIN32
+               /* Make a console window if needed */
+               if (appData.icsActive) ConsoleCreate();
+       #endif
+
     if (appData.icsActive) {
        err = establish();
        if (err != 0) {
            if (*appData.icsCommPort != NULLCHAR) {
-               sprintf(buf, "Could not open comm port %s",  
+               sprintf(buf, _("Could not open comm port %s"),
                        appData.icsCommPort);
            } else {
-               sprintf(buf, "Could not connect to host %s, port %s",  
+               sprintf(buf, _("Could not connect to host %s, port %s"),
                        appData.icsHost, appData.icsPort);
            }
            DisplayFatalError(buf, err, 1);
@@ -715,7 +751,7 @@ InitBackEnd3 P((void))
        cmailISR =
          AddInputSource(cmailPR, FALSE, CmailSigHandlerCallBack, &cmailISR);
     }
-    
+
     ThawUI();
     DisplayMessage("", "");
     if (StrCaseCmp(appData.initialMode, "") == 0) {
@@ -723,7 +759,7 @@ InitBackEnd3 P((void))
     } else if (StrCaseCmp(appData.initialMode, "TwoMachines") == 0) {
       initialMode = TwoMachinesPlay;
     } else if (StrCaseCmp(appData.initialMode, "AnalyzeFile") == 0) {
-      initialMode = AnalyzeFile; 
+      initialMode = AnalyzeFile;
     } else if (StrCaseCmp(appData.initialMode, "Analysis") == 0) {
       initialMode = AnalyzeMode;
     } else if (StrCaseCmp(appData.initialMode, "MachineWhite") == 0) {
@@ -737,7 +773,7 @@ InitBackEnd3 P((void))
     } else if (StrCaseCmp(appData.initialMode, "Training") == 0) {
       initialMode = Training;
     } else {
-      sprintf(buf, "Unknown initialMode %s", appData.initialMode);
+      sprintf(buf, _("Unknown initialMode %s"), appData.initialMode);
       DisplayFatalError(buf, 0, 2);
       return;
     }
@@ -745,7 +781,7 @@ InitBackEnd3 P((void))
     if (appData.matchMode) {
        /* Set up machine vs. machine match */
        if (appData.noChessProgram) {
-           DisplayFatalError("Can't have a match with no chess programs",
+           DisplayFatalError(_("Can't have a match with no chess programs"),
                              0, 2);
            return;
        }
@@ -755,14 +791,14 @@ InitBackEnd3 P((void))
            if (!LoadGameFromFile(appData.loadGameFile,
                                  appData.loadGameIndex,
                                  appData.loadGameFile, FALSE)) {
-               DisplayFatalError("Bad game file", 0, 1);
+               DisplayFatalError(_("Bad game file"), 0, 1);
                return;
            }
        } else if (*appData.loadPositionFile != NULLCHAR) {
            if (!LoadPositionFromFile(appData.loadPositionFile,
                                      appData.loadPositionIndex,
                                      appData.loadPositionFile)) {
-               DisplayFatalError("Bad position file", 0, 1);
+               DisplayFatalError(_("Bad position file"), 0, 1);
                return;
            }
        }
@@ -774,7 +810,7 @@ InitBackEnd3 P((void))
        /* Set up other modes */
        if (initialMode == AnalyzeFile) {
          if (*appData.loadGameFile == NULLCHAR) {
-           DisplayFatalError("AnalyzeFile mode requires a game file", 0, 1);
+           DisplayFatalError(_("AnalyzeFile mode requires a game file"), 0, 1);
            return;
          }
        }
@@ -789,11 +825,11 @@ InitBackEnd3 P((void))
        }
        if (initialMode == AnalyzeMode) {
          if (appData.noChessProgram) {
-           DisplayFatalError("Analysis mode requires a chess engine", 0, 2);
+           DisplayFatalError(_("Analysis mode requires a chess engine"), 0, 2);
            return;
          }
          if (appData.icsActive) {
-           DisplayFatalError("Analysis mode does not work with ICS mode",0,2);
+           DisplayFatalError(_("Analysis mode does not work with ICS mode"),0,2);
            return;
          }
          AnalyzeModeEvent();
@@ -803,36 +839,36 @@ InitBackEnd3 P((void))
          AnalysisPeriodicEvent(1);
        } else if (initialMode == MachinePlaysWhite) {
          if (appData.noChessProgram) {
-           DisplayFatalError("MachineWhite mode requires a chess engine",
+           DisplayFatalError(_("MachineWhite mode requires a chess engine"),
                              0, 2);
            return;
          }
          if (appData.icsActive) {
-           DisplayFatalError("MachineWhite mode does not work with ICS mode",
+           DisplayFatalError(_("MachineWhite mode does not work with ICS mode"),
                              0, 2);
            return;
          }
          MachineWhiteEvent();
        } else if (initialMode == MachinePlaysBlack) {
          if (appData.noChessProgram) {
-           DisplayFatalError("MachineBlack mode requires a chess engine",
+           DisplayFatalError(_("MachineBlack mode requires a chess engine"),
                              0, 2);
            return;
          }
          if (appData.icsActive) {
-           DisplayFatalError("MachineBlack mode does not work with ICS mode",
+           DisplayFatalError(_("MachineBlack mode does not work with ICS mode"),
                              0, 2);
            return;
          }
          MachineBlackEvent();
        } else if (initialMode == TwoMachinesPlay) {
          if (appData.noChessProgram) {
-           DisplayFatalError("TwoMachines mode requires a chess engine",
+           DisplayFatalError(_("TwoMachines mode requires a chess engine"),
                              0, 2);
            return;
          }
          if (appData.icsActive) {
-           DisplayFatalError("TwoMachines mode does not work with ICS mode",
+           DisplayFatalError(_("TwoMachines mode does not work with ICS mode"),
                              0, 2);
            return;
          }
@@ -843,7 +879,7 @@ InitBackEnd3 P((void))
          EditPositionEvent();
        } else if (initialMode == Training) {
          if (*appData.loadGameFile == NULLCHAR) {
-           DisplayFatalError("Training mode requires a game file", 0, 2);
+           DisplayFatalError(_("Training mode requires a game file"), 0, 2);
            return;
          }
          TrainingEvent();
@@ -881,7 +917,7 @@ establish()
                        appData.icsHost, appData.icsPort);
            } else {
                sprintf(buf, "%s %s -l %s %s %s %s",
-                       appData.remoteShell, appData.gateway, 
+                       appData.remoteShell, appData.gateway,
                        appData.remoteUser, appData.telnetProgram,
                        appData.icsHost, appData.icsPort);
            }
@@ -991,14 +1027,14 @@ read_from_player(isr, closure, message, count, error)
        gotEof = 0;
        outCount = OutputMaybeTelnet(icsPR, message, count, &outError);
        if (outCount < count) {
-           DisplayFatalError("Error writing to ICS", outError, 1);
+           DisplayFatalError(_("Error writing to ICS"), outError, 1);
        }
     } else if (count < 0) {
        RemoveInputSource(isr);
-       DisplayFatalError("Error reading from keyboard", error, 1);
+       DisplayFatalError(_("Error reading from keyboard"), error, 1);
     } else if (gotEof++ > 0) {
        RemoveInputSource(isr);
-       DisplayFatalError("Got end of file from keyboard", 0, 0);
+       DisplayFatalError(_("Got end of file from keyboard"), 0, 0);
     }
 }
 
@@ -1013,7 +1049,7 @@ SendToICS(s)
     count = strlen(s);
     outCount = OutputMaybeTelnet(icsPR, s, count, &outError);
     if (outCount < count) {
-       DisplayFatalError("Error writing to ICS", outError, 1);
+       DisplayFatalError(_("Error writing to ICS"), outError, 1);
     }
 }
 
@@ -1038,13 +1074,13 @@ SendToICSDelayed(s,msdelay)
     outCount = OutputToProcessDelayed(icsPR, s, count, &outError,
                                      msdelay);
     if (outCount < count) {
-       DisplayFatalError("Error writing to ICS", outError, 1);
+       DisplayFatalError(_("Error writing to ICS"), outError, 1);
     }
 }
 
 
 /* Remove all highlighting escape sequences in s
-   Also deletes any suffix starting with '(' 
+   Also deletes any suffix starting with '('
    */
 char *
 StripHighlightAndTitle(s)
@@ -1113,7 +1149,7 @@ StringToVariant(e)
     char buf[MSG_SIZ];
 
     if (!e) return v;
-    
+
     for (i=0; i<sizeof(variantNames)/sizeof(char*); i++) {
       if (StrCaseStr(e, variantNames[i])) {
        v = (VariantClass) i;
@@ -1201,7 +1237,7 @@ StringToVariant(e)
          v = VariantShatranj;
          break;
 
-       /* Temporary names for future ICC types.  The name *will* change in 
+       /* Temporary names for future ICC types.  The name *will* change in
           the next xboard/WinBoard release after ICC defines it. */
        case 29:
          v = Variant29;
@@ -1242,7 +1278,7 @@ StringToVariant(e)
       }
     }
     if (appData.debugMode) {
-      fprintf(debugFP, "recognized '%s' (%d) as variant %s\n",
+      fprintf(debugFP, _("recognized '%s' (%d) as variant %s\n"),
              e, wnum, VariantName(v));
     }
     return v;
@@ -1267,7 +1303,7 @@ looking_at(buf, index, pattern)
     char *bufp = &buf[*index], *patternp = pattern;
     int star_count = 0;
     char *matchp = star_match[0];
-    
+
     for (;;) {
        if (*patternp == NULLCHAR) {
            *index = leftover_start = bufp - buf;
@@ -1307,7 +1343,7 @@ SendToPlayer(data, length)
     int error, outCount;
     outCount = OutputToProcess(NoProc, data, length, &error);
     if (outCount < length) {
-       DisplayFatalError("Error writing to display", error, 1);
+       DisplayFatalError(_("Error writing to display"), error, 1);
     }
 }
 
@@ -1393,7 +1429,7 @@ TelnetRequest(ddww, option)
     msg[2] = option;
     outCount = OutputToProcess(icsPR, (char *)msg, 3, &outError);
     if (outCount < 3) {
-       DisplayFatalError("Error writing to ICS", outError, 1);
+       DisplayFatalError(_("Error writing to ICS"), outError, 1);
     }
 }
 
@@ -1439,7 +1475,7 @@ read_from_ics(isr, closure, data, count, error)
 #define STARTED_CHATTER 5
 #define STARTED_COMMENT 6
 #define STARTED_MOVES_NOHIDE 7
-    
+
     static int started = STARTED_NONE;
     static char parse[20000];
     static int parse_pos = 0;
@@ -1453,8 +1489,17 @@ read_from_ics(isr, closure, data, count, error)
     int buf_len;
     int next_out;
     int tkind;
+    int backup;
     char *p;
 
+    if (appData.debugMode) {
+      if (!error) {
+       fprintf(debugFP, "<ICS: ");
+       show_bytes(debugFP, data, count);
+       fprintf(debugFP, "\n");
+      }
+    }
+
     if (count > 0) {
        /* If last read ended with a partial line that we couldn't parse,
           prepend it to the new read and try again. */
@@ -1473,7 +1518,7 @@ read_from_ics(isr, closure, data, count, error)
        buf[buf_len] = NULLCHAR;
        next_out = leftover_len;
        leftover_start = 0;
-       
+
        i = 0;
        while (i < buf_len) {
            /* Deal with part of the TELNET option negotiation
@@ -1585,12 +1630,12 @@ read_from_ics(isr, closure, data, count, error)
                  next_out = i;
                continue;
            }
-               
+
            /* OK, this at least will *usually* work */
            if (!loggedOn && looking_at(buf, &i, "ics%")) {
                loggedOn = TRUE;
            }
-           
+
            if (loggedOn && !intfSet) {
                if (ics_type == ICS_ICC) {
                  sprintf(str,
@@ -1699,15 +1744,23 @@ read_from_ics(isr, closure, data, count, error)
 
            oldi = i;
            if (appData.zippyTalk || appData.zippyPlay) {
+                /* Backup address for color zippy lines */
+                backup = i;
 #if ZIPPY
+       #ifdef WIN32
+               if (loggedOn == TRUE)
+                       if (ZippyControl(buf, &backup) || ZippyConverse(buf, &backup) ||
+                       (appData.zippyPlay && ZippyMatch(buf, &backup)));
+               #else
                if (ZippyControl(buf, &i) ||
                    ZippyConverse(buf, &i) ||
                    (appData.zippyPlay && ZippyMatch(buf, &i))) {
                    loggedOn = TRUE;
-                   continue;
+                   if (!appData.colorize) continue;
                }
+       #endif
 #endif
-           } else {
+           }
                if (/* Don't color "message" or "messages" output */
                    (tkind = 5, looking_at(buf, &i, "*. * (*:*): ")) ||
                    looking_at(buf, &i, "*. * at *:*: ") ||
@@ -1863,7 +1916,6 @@ read_from_ics(isr, closure, data, count, error)
                        curColor = ColorSeek;
                    }
                    continue;
-               }
            }
 
            if (looking_at(buf, &i, "\\   ")) {
@@ -1898,14 +1950,14 @@ read_from_ics(isr, closure, data, count, error)
                SendToICS("refresh\n");
                continue;
            }
-           
+
            if (!have_sent_ICS_logon && looking_at(buf, &i, "login:")) {
                ICSInitScript();
                have_sent_ICS_logon = 1;
                continue;
            }
-             
-           if (ics_getting_history != H_GETTING_MOVES /*smpos kludge*/ && 
+
+           if (ics_getting_history != H_GETTING_MOVES /*smpos kludge*/ &&
                (looking_at(buf, &i, "\n<12> ") ||
                 looking_at(buf, &i, "<12> "))) {
                loggedOn = TRUE;
@@ -1974,7 +2026,7 @@ read_from_ics(isr, closure, data, count, error)
                  case H_GOT_UNWANTED_HEADER:
                  case H_GETTING_MOVES:
                    /* Should not happen */
-                   DisplayError("Error gathering move list: two headers", 0);
+                   DisplayError(_("Error gathering move list: two headers"), 0);
                    ics_getting_history = H_FALSE;
                    break;
                }
@@ -1988,7 +2040,7 @@ read_from_ics(isr, closure, data, count, error)
                    gameInfo.whiteRating = string_to_rating(star_match[1]);
                    gameInfo.blackRating = string_to_rating(star_match[3]);
                    if (appData.debugMode)
-                     fprintf(debugFP, "Ratings from header: W %d, B %d\n", 
+                     fprintf(debugFP, _("Ratings from header: W %d, B %d\n"),
                              gameInfo.whiteRating, gameInfo.blackRating);
                }
                continue;
@@ -2021,7 +2073,7 @@ read_from_ics(isr, closure, data, count, error)
                    break;
                  case H_GETTING_MOVES:
                    /* Should not happen */
-                   DisplayError("Error gathering move list: nested", 0);
+                   DisplayError(_("Error gathering move list: nested"), 0);
                    ics_getting_history = H_FALSE;
                    break;
                  case H_GOT_REQ_HEADER:
@@ -2042,8 +2094,8 @@ read_from_ics(isr, closure, data, count, error)
                    break;
                }
                continue;
-           }                           
-           
+           }
+
            if (looking_at(buf, &i, "% ") ||
                ((started == STARTED_MOVES || started == STARTED_MOVES_NOHIDE)
                 && looking_at(buf, &i, "}*"))) {
@@ -2061,7 +2113,7 @@ read_from_ics(isr, closure, data, count, error)
                            if (WhiteOnMove(forwardMostMove)) {
                                if (first.sendTime) {
                                  if (first.useColors) {
-                                   SendToProgram("black\n", &first); 
+                                   SendToProgram("black\n", &first);
                                  }
                                  SendTimeRemaining(&first, TRUE);
                                }
@@ -2107,7 +2159,7 @@ read_from_ics(isr, closure, data, count, error)
                                  firstMove = TRUE;
                                }
                            }
-                       }                       
+                       }
                    }
 #endif
                    if (gameMode == IcsObserving && ics_gamenum == -1) {
@@ -2149,14 +2201,14 @@ read_from_ics(isr, closure, data, count, error)
                }
                continue;
            }
-           
+
            if ((started == STARTED_MOVES || started == STARTED_BOARD ||
                 started == STARTED_HOLDINGS ||
                 started == STARTED_MOVES_NOHIDE) && i >= leftover_len) {
                /* Accumulate characters in move list or board */
                parse[parse_pos++] = buf[i];
            }
-           
+
            /* Start of game messages.  Mostly we detect start of game
               when the first board image arrives.  On some versions
               of the ICS, though, we need to do a "refresh" after starting
@@ -2189,7 +2241,7 @@ read_from_ics(isr, closure, data, count, error)
                player2Rating = string_to_rating(star_match[3]);
 
                if (appData.debugMode)
-                 fprintf(debugFP, 
+                 fprintf(debugFP,
                          "Ratings from 'Game notification:' %s %d, %s %d\n",
                          player1Name, player1Rating,
                          player2Name, player2Rating);
@@ -2219,8 +2271,8 @@ read_from_ics(isr, closure, data, count, error)
                    SendToICS("refresh\n");
                }
                continue;
-           }    
-           
+           }
+
            /* Error messages */
            if (ics_user_moved) {
                if (looking_at(buf, &i, "Illegal move") ||
@@ -2282,7 +2334,7 @@ read_from_ics(isr, closure, data, count, error)
                   2    empty, white, or black (IGNORED)
                   3    player 2 name (not necessarily black)
                   4    player 2 rating
-                  
+
                   The names/ratings are sorted out when the game
                   actually starts (below).
                */
@@ -2292,14 +2344,14 @@ read_from_ics(isr, closure, data, count, error)
                player2Rating = string_to_rating(star_match[4]);
 
                if (appData.debugMode)
-                 fprintf(debugFP, 
+                 fprintf(debugFP,
                          "Ratings from 'Creating:' %s %d, %s %d\n",
                          player1Name, player1Rating,
                          player2Name, player2Rating);
 
                continue;
            }
-           
+
            /* Improved generic start/end-of-game messages */
            if ((tkind=0, looking_at(buf, &i, "{Game * (* vs. *) *}*")) ||
                (tkind=1, looking_at(buf, &i, "{Game * (*(*) vs. *(*)) *}*"))){
@@ -2387,6 +2439,11 @@ read_from_ics(isr, closure, data, count, error)
                if (gameMode == IcsObserving &&
                    atoi(star_match[0]) == ics_gamenum)
                  {
+                         /* icsEngineAnalyze */
+                         if (appData.icsEngineAnalyze) {
+                            ExitAnalyzeMode();
+                                ModeHighlight();
+                         }
                      StopClocks();
                      gameMode = IcsIdle;
                      ics_gamenum = -1;
@@ -2448,8 +2505,8 @@ read_from_ics(isr, closure, data, count, error)
                        ClearPremoveHighlights();
                        if (appData.debugMode)
                          fprintf(debugFP, "Sending premove:\n");
-                         UserMoveEvent(premoveFromX, premoveFromY, 
-                                       premoveToX, premoveToY, 
+                         UserMoveEvent(premoveFromX, premoveFromY,
+                                       premoveToX, premoveToY,
                                        premovePromoChar);
                      }
                    }
@@ -2517,34 +2574,34 @@ read_from_ics(isr, closure, data, count, error)
 
            i++;                /* skip unparsed character and loop back */
        }
-       
+
        if (started != STARTED_MOVES && started != STARTED_BOARD &&
            started != STARTED_HOLDINGS && i > next_out) {
            SendToPlayer(&buf[next_out], i - next_out);
            next_out = i;
        }
-       
+
        leftover_len = buf_len - leftover_start;
        /* if buffer ends with something we couldn't parse,
           reparse it after appending the next read */
-       
+
     } else if (count == 0) {
        RemoveInputSource(isr);
-        DisplayFatalError("Connection closed by ICS", 0, 0);
+        DisplayFatalError(_("Connection closed by ICS"), 0, 0);
     } else {
-       DisplayFatalError("Error reading from ICS", error, 1);
+       DisplayFatalError(_("Error reading from ICS"), error, 1);
     }
 }
 
 
 /* Board style 12 looks like this:
-   
+
    <12> r-b---k- pp----pp ---bP--- ---p---- q------- ------P- P--Q--BP -----R-K W -1 0 0 0 0 0 0 paf MaxII 0 2 12 21 25 234 174 24 Q/d7-a4 (0:06) Qxa4 0 0
-   
+
  * The "<12> " is stripped before it gets to this routine.  The two
  * trailing 0's (flip state and clock ticking) are later addition, and
  * some chess servers may not have them, or may have only the first.
- * Additional trailing fields may be added in the future.  
+ * Additional trailing fields may be added in the future.
  */
 
 #define PATTERN "%72c%c%d%d%d%d%d%d%d%s%s%d%d%d%d%d%d%d%d%s%s%s%d%d"
@@ -2560,10 +2617,10 @@ read_from_ics(isr, closure, data, count, error)
 void
 ParseBoard12(string)
      char *string;
-{ 
+{
     GameMode newGameMode;
-    int gamenum, newGame, newMove, relation, basetime, increment, ics_flip = 0;
-    int j, k, n, moveNum, white_stren, black_stren, white_time, black_time;
+    int gamenum, newGame, newMove, relation, basetime, increment, ics_flip = 0, i;
+    int j, k, n, moveNum, white_stren, black_stren, white_time, black_time, takeback;
     int double_push, castle_ws, castle_wl, castle_bs, castle_bl, irrev_count;
     char to_play, board_chars[72];
     char move_str[500], str[500], elapsed_time[500];
@@ -2576,11 +2633,11 @@ ParseBoard12(string)
     char promoChar;
 
     fromX = fromY = toX = toY = -1;
-    
+
     newGame = FALSE;
 
     if (appData.debugMode)
-      fprintf(debugFP, "Parsing board: %s\n", string);
+      fprintf(debugFP, _("Parsing board: %s\n"), string);
 
     move_str[0] = NULLCHAR;
     elapsed_time[0] = NULLCHAR;
@@ -2592,7 +2649,7 @@ ParseBoard12(string)
               &ticking);
 
     if (n < 22) {
-       sprintf(str, "Failed to parse board string:\n\"%s\"", string);
+       sprintf(str, _("Failed to parse board string:\n\"%s\""), string);
        DisplayError(str, 0);
        return;
     }
@@ -2601,11 +2658,11 @@ ParseBoard12(string)
     moveNum = (moveNum - 1) * 2;
     if (to_play == 'B') moveNum++;
     if (moveNum >= MAX_MOVES) {
-      DisplayFatalError("Game too long; increase MAX_MOVES and recompile",
+      DisplayFatalError(_("Game too long; increase MAX_MOVES and recompile"),
                        0, 1);
       return;
     }
-    
+
     switch (relation) {
       case RELATION_OBSERVING_PLAYED:
       case RELATION_OBSERVING_STATIC:
@@ -2627,14 +2684,14 @@ ParseBoard12(string)
       case RELATION_ISOLATED_BOARD:
       default:
        /* Just display this board.  If user was doing something else,
-          we will forget about it until the next board comes. */ 
+          we will forget about it until the next board comes. */
        newGameMode = IcsIdle;
        break;
       case RELATION_STARTING_POSITION:
        newGameMode = gameMode;
        break;
     }
-    
+
     /* Modify behavior for initial board display on move listing
        of wild games.
        */
@@ -2663,19 +2720,19 @@ ParseBoard12(string)
        return;
       case H_GETTING_MOVES:
        /* Should not happen */
-       DisplayError("Error gathering move list: extra board", 0);
+       DisplayError(_("Error gathering move list: extra board"), 0);
        ics_getting_history = H_FALSE;
        return;
     }
-    
+
     /* Take action if this is the first board of a new game, or of a
        different game than is currently being displayed.  */
     if (gamenum != ics_gamenum || newGameMode != gameMode ||
        relation == RELATION_ISOLATED_BOARD) {
-       
+
        /* Forget the old game and get the history (if any) of the new one */
        if (gameMode != BeginningOfGame) {
-         Reset(FALSE, TRUE);
+       Reset(FALSE, TRUE);
        }
        newGame = TRUE;
        if (appData.autoRaiseBoard) BoardToTop();
@@ -2689,14 +2746,14 @@ ParseBoard12(string)
            sprintf(str, "%smoves %d\n", ics_prefix, gamenum);
            SendToICS(str);
        }
-       
+
        /* Initially flip the board to have black on the bottom if playing
           black or if the ICS flip flag is set, but let the user change
           it with the Flip View button. */
-       flipView = appData.autoFlipView ? 
+       flipView = appData.autoFlipView ?
          (newGameMode == IcsPlayingBlack) || ics_flip :
          appData.flipView;
-       
+
        /* Done with values from previous mode; copy in new ones */
        gameMode = newGameMode;
        ModeHighlight();
@@ -2719,7 +2776,7 @@ ParseBoard12(string)
        movesPerSession = 0;
        gameInfo.timeControl = TimeControlTagValue();
        gameInfo.variant = StringToVariant(gameInfo.event);
-       
+
        /* Do we have the ratings? */
        if (strcmp(player1Name, white) == 0 &&
            strcmp(player2Name, black) == 0) {
@@ -2745,7 +2802,7 @@ ParseBoard12(string)
            SendToICS("set shout 0\n");
        }
     }
-    
+
     /* Deal with midgame name changes */
     if (!newGame) {
        if (!gameInfo.white || strcmp(gameInfo.white, white) != 0) {
@@ -2757,7 +2814,7 @@ ParseBoard12(string)
            gameInfo.black = StrSave(black);
        }
     }
-    
+
     /* Throw away game result if anything actually changes in examine mode */
     if (gameMode == IcsExamining && !newGame) {
        gameInfo.result = GameUnfinished;
@@ -2766,7 +2823,7 @@ ParseBoard12(string)
            gameInfo.resultDetails = NULL;
        }
     }
-    
+
     /* In pausing && IcsExamining mode, we ignore boards coming
        in if they are in a different variation than we are. */
     if (pauseExamInvalid) return;
@@ -2777,7 +2834,7 @@ ParseBoard12(string)
            return;
        }
     }
-    
+
     /* Parse the board */
     for (k = 0; k < 8; k++)
       for (j = 0; j < 8; j++)
@@ -2787,16 +2844,26 @@ ParseBoard12(string)
        startedFromSetupPosition =
          !CompareBoards(board, initialPosition);
     }
-    
+
     if (ics_getting_history == H_GOT_REQ_HEADER ||
        ics_getting_history == H_GOT_UNREQ_HEADER) {
        /* This was an initial position from a move list, not
           the current position */
        return;
     }
-    
+
     /* Update currentMove and known move number limits */
     newMove = newGame || moveNum > forwardMostMove;
+
+       /* If we found takebacks during icsEngineAnalyze
+          try send to engine */
+       if (!newGame && appData.icsEngineAnalyze && moveNum < forwardMostMove) {
+               takeback = forwardMostMove - moveNum;
+               for (i = 0; i < takeback; i++) {
+                   if (appData.debugMode) fprintf(debugFP, "take back move\n");
+                   SendToProgram("undo\n", &first);
+                }
+       }
     if (newGame) {
        forwardMostMove = backwardMostMove = currentMove = moveNum;
        if (gameMode == IcsExamining && moveNum == 0) {
@@ -2813,7 +2880,7 @@ ParseBoard12(string)
        if (!pausing || currentMove > forwardMostMove)
          currentMove = forwardMostMove;
     } else {
-       /* New part of history that is not contiguous with old part */ 
+       /* New part of history that is not contiguous with old part */
        if (pausing && gameMode == IcsExamining) {
            pauseExamInvalid = TRUE;
            forwardMostMove = pauseExamForwardMostMove;
@@ -2826,7 +2893,7 @@ ParseBoard12(string)
            SendToICS(str);
        }
     }
-    
+
     /* Update the clocks */
     if (strchr(elapsed_time, '.')) {
       /* Time is in ms */
@@ -2837,7 +2904,7 @@ ParseBoard12(string)
       timeRemaining[0][moveNum] = whiteTimeRemaining = white_time * 1000;
       timeRemaining[1][moveNum] = blackTimeRemaining = black_time * 1000;
     }
-      
+
 
 #if ZIPPY
     if (appData.zippyPlay && newGame &&
@@ -2845,7 +2912,7 @@ ParseBoard12(string)
        gameMode != IcsExamining)
       ZippyFirstBoard(moveNum, basetime, increment);
 #endif
-    
+
     /* Put the move on the move list, first converting
        to canonical algebraic form. */
     if (moveNum > 0) {
@@ -2904,13 +2971,13 @@ ParseBoard12(string)
 
 #if ZIPPY
        /* Send move to chess program (BEFORE animating it). */
-       if (appData.zippyPlay && !newGame && newMove && 
+       if (appData.zippyPlay && !newGame && newMove &&
           (!appData.getMoveList || backwardMostMove == 0) && first.initDone) {
 
            if ((gameMode == IcsPlayingWhite && WhiteOnMove(moveNum)) ||
                (gameMode == IcsPlayingBlack && !WhiteOnMove(moveNum))) {
                if (moveList[moveNum - 1][0] == NULLCHAR) {
-                   sprintf(str, "Couldn't parse move \"%s\" from ICS",
+                   sprintf(str, _("Couldn't parse move \"%s\" from ICS"),
                            move_str);
                    DisplayError(str, 0);
                } else {
@@ -2932,7 +2999,7 @@ ParseBoard12(string)
                }
            } else if (gameMode == IcsObserving || gameMode == IcsExamining) {
              if (moveList[moveNum - 1][0] == NULLCHAR) {
-               sprintf(str, "Couldn't parse move \"%s\" from ICS", move_str);
+               sprintf(str, _("Couldn't parse move \"%s\" from ICS"), move_str);
                DisplayError(str, 0);
              } else {
                SendMoveToProgram(moveNum - 1, &first);
@@ -2952,7 +3019,7 @@ ParseBoard12(string)
            SetHighlights(fromX, fromY, toX, toY);
        }
     }
-    
+
     /* Start the clocks */
     whiteFlag = blackFlag = FALSE;
     appData.clockMode = !(basetime == 0 && increment == 0);
@@ -2969,28 +3036,28 @@ ParseBoard12(string)
       DisplayBothClocks();
     else
       StartClocks();
-    
+
     /* Display opponents and material strengths */
     if (gameInfo.variant != VariantBughouse &&
        gameInfo.variant != VariantCrazyhouse) {
        if (tinyLayout || smallLayout) {
-           sprintf(str, "%s(%d) %s(%d) {%d %d}", 
+           sprintf(str, "%s(%d) %s(%d) {%d %d}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment);
        } else {
-           sprintf(str, "%s (%d) vs. %s (%d) {%d %d}", 
+           sprintf(str, "%s (%d) vs. %s (%d) {%d %d}",
                    gameInfo.white, white_stren, gameInfo.black, black_stren,
                    basetime, increment);
        }
        DisplayTitle(str);
     }
 
-   
+
     /* Display the board */
     if (!pausing) {
-      
+
       if (appData.premove)
-         if (!gotPremove || 
+         if (!gotPremove ||
             ((gameMode == IcsPlayingWhite) && (WhiteOnMove(currentMove))) ||
             ((gameMode == IcsPlayingBlack) && (!WhiteOnMove(currentMove))))
              ClearPremoveHighlights();
@@ -3156,7 +3223,7 @@ ParseOneMove(move, moveNum, moveType, fromX, fromY, toX, toY, promoChar)
      ChessMove *moveType;
      int *fromX, *fromY, *toX, *toY;
      char *promoChar;
-{       
+{
     *moveType = yylexstr(moveNum, move);
     switch (*moveType) {
       case WhitePromotionQueen:
@@ -3263,7 +3330,7 @@ SendBoard(cps, moveNum)
      int moveNum;
 {
     char message[MSG_SIZ];
-    
+
     if (cps->useSetboard) {
       char* fen = PositionToFEN(moveNum);
       sprintf(message, "setboard %s\n", fen);
@@ -3284,13 +3351,13 @@ SendBoard(cps, moveNum)
        bp = &boards[moveNum][i][0];
        for (j = 0; j < BOARD_SIZE; j++, bp++) {
          if ((int) *bp < (int) BlackPawn) {
-           sprintf(message, "%c%c%c\n", PieceToChar(*bp), 
+           sprintf(message, "%c%c%c\n", PieceToChar(*bp),
                    'a' + j, '1' + i);
            SendToProgram(message, cps);
          }
        }
       }
-    
+
       SendToProgram("c\n", cps);
       for (i = BOARD_SIZE - 1; i >= 0; i--) {
        bp = &boards[moveNum][i][0];
@@ -3303,7 +3370,7 @@ SendBoard(cps, moveNum)
          }
        }
       }
-    
+
       SendToProgram(".\n", cps);
     }
 }
@@ -3365,7 +3432,7 @@ OKToStartUserMove(x, y)
       case IcsPlayingBlack:
        if (appData.zippyPlay) return FALSE;
        if (white_piece) {
-           DisplayMoveError("You are playing Black");
+           DisplayMoveError(_("You are playing Black"));
            return FALSE;
        }
        break;
@@ -3374,20 +3441,20 @@ OKToStartUserMove(x, y)
       case IcsPlayingWhite:
        if (appData.zippyPlay) return FALSE;
        if (!white_piece) {
-           DisplayMoveError("You are playing White");
+           DisplayMoveError(_("You are playing White"));
            return FALSE;
        }
        break;
 
       case EditGame:
        if (!white_piece && WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is White's turn");
+           DisplayMoveError(_("It is White's turn"));
            return FALSE;
-       }           
+       }
        if (white_piece && !WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is Black's turn");
+           DisplayMoveError(_("It is Black's turn"));
            return FALSE;
-       }           
+       }
        if (cmailMsgLoaded && (currentMove < cmailOldMove)) {
            /* Editing correspondence game history */
            /* Could disallow this or prompt for confirmation */
@@ -3405,21 +3472,21 @@ OKToStartUserMove(x, y)
        if (appData.icsActive) return FALSE;
        if (!appData.noChessProgram) {
            if (!white_piece) {
-               DisplayMoveError("You are playing White");
+               DisplayMoveError(_("You are playing White"));
                return FALSE;
            }
        }
        break;
-       
+
       case Training:
        if (!white_piece && WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is White's turn");
+           DisplayMoveError(_("It is White's turn"));
            return FALSE;
-       }           
+       }
        if (white_piece && !WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is Black's turn");
+           DisplayMoveError(_("It is Black's turn"));
            return FALSE;
-       }           
+       }
        break;
 
       default:
@@ -3428,7 +3495,7 @@ OKToStartUserMove(x, y)
     }
     if (currentMove != forwardMostMove && gameMode != AnalyzeMode
        && gameMode != AnalyzeFile && gameMode != Training) {
-       DisplayMoveError("Displayed position is not current");
+       DisplayMoveError(_("Displayed position is not current"));
        return FALSE;
     }
     return TRUE;
@@ -3452,7 +3519,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
     if ((fromX == toX) && (fromY == toY)) {
        return;
     }
-       
+
     /* Check if the user is playing in turn.  This is complicated because we
        let the user "pick up" a piece before it is his turn.  So the piece he
        tried to pick up may have been captured by the time he puts it down!
@@ -3478,7 +3545,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
       case MachinePlaysWhite:
        /* User is moving for Black */
        if (WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is White's turn");
+           DisplayMoveError(_("It is White's turn"));
            return;
        }
        break;
@@ -3486,7 +3553,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
       case MachinePlaysBlack:
        /* User is moving for White */
        if (!WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is Black's turn");
+           DisplayMoveError(_("It is Black's turn"));
            return;
        }
        break;
@@ -3500,13 +3567,13 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
            (int) boards[currentMove][fromY][fromX] <= (int) BlackKing) {
            /* User is moving for Black */
            if (WhiteOnMove(currentMove)) {
-               DisplayMoveError("It is White's turn");
+               DisplayMoveError(_("It is White's turn"));
                return;
            }
        } else {
            /* User is moving for White */
            if (!WhiteOnMove(currentMove)) {
-               DisplayMoveError("It is Black's turn");
+               DisplayMoveError(_("It is Black's turn"));
                return;
            }
        }
@@ -3516,7 +3583,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
        /* User is moving for Black */
        if (WhiteOnMove(currentMove)) {
            if (!appData.premove) {
-               DisplayMoveError("It is White's turn");
+               DisplayMoveError(_("It is White's turn"));
            } else if (toX >= 0 && toY >= 0) {
                premoveToX = toX;
                premoveToY = toY;
@@ -3524,7 +3591,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
                premoveFromY = fromY;
                premovePromoChar = promoChar;
                gotPremove = 1;
-               if (appData.debugMode) 
+               if (appData.debugMode)
                    fprintf(debugFP, "Got premove: fromX %d,"
                            "fromY %d, toX %d, toY %d\n",
                            fromX, fromY, toX, toY);
@@ -3537,7 +3604,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
        /* User is moving for White */
        if (!WhiteOnMove(currentMove)) {
            if (!appData.premove) {
-               DisplayMoveError("It is Black's turn");
+               DisplayMoveError(_("It is Black's turn"));
            } else if (toX >= 0 && toY >= 0) {
                premoveToX = toX;
                premoveToY = toY;
@@ -3545,7 +3612,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
                premoveFromY = fromY;
                premovePromoChar = promoChar;
                gotPremove = 1;
-               if (appData.debugMode) 
+               if (appData.debugMode)
                    fprintf(debugFP, "Got premove: fromX %d,"
                            "fromY %d, toX %d, toY %d\n",
                            fromX, fromY, toX, toY);
@@ -3571,12 +3638,12 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
 
     if (toX < 0 || toY < 0) return;
     userOfferedDraw = FALSE;
-       
+
     if (appData.testLegality) {
        moveType = LegalityTest(boards[currentMove], PosFlags(currentMove),
                                EP_UNKNOWN, fromY, fromX, toY, toX, promoChar);
        if (moveType == IllegalMove || moveType == ImpossibleMove) {
-           DisplayMoveError("Illegal move");
+           DisplayMoveError(_("Illegal move"));
            return;
        }
     } else {
@@ -3585,7 +3652,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
 
     if (gameMode == Training) {
       /* compare the move played on the board to the next move in the
-       * game. If they match, display the move and the opponent's response. 
+       * game. If they match, display the move and the opponent's response.
        * If they don't match, display an error message.
        */
       int saveAnimate;
@@ -3610,10 +3677,10 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
          gameMode = PlayFromGameFile;
          ModeHighlight();
          SetTrainingModeOff();
-         DisplayInformation("End of game");
+         DisplayInformation(_("End of game"));
        }
       } else {
-       DisplayError("Incorrect move", 0);
+       DisplayError(_("Incorrect move"), 0);
       }
       return;
     }
@@ -3706,7 +3773,7 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
       break;
     }
     break;
-    
+
   case MachinePlaysBlack:
   case MachinePlaysWhite:
     /* disable certain menu options while machine is thinking */
@@ -3832,7 +3899,7 @@ HandleMachineMove(message, cps)
        if (!ParseOneMove(machineMove, forwardMostMove, &moveType,
                              &fromX, &fromY, &toX, &toY, &promoChar)) {
            /* Machine move could not be parsed; ignore it. */
-           sprintf(buf1, "Illegal move \"%s\" from %s machine",
+           sprintf(buf1, _("Illegal move \"%s\" from %s machine"),
                    machineMove, cps->which);
            DisplayError(buf1, 0);
            if (gameMode == TwoMachinesPlay) {
@@ -3861,9 +3928,9 @@ HandleMachineMove(message, cps)
        strcpy(machineMove, currentMoveString);
        strcat(machineMove, "\n");
        strcpy(moveList[forwardMostMove], machineMove);
-    
+
        MakeMove(fromX, fromY, toX, toY, promoChar);/*updates forwardMostMove*/
-    
+
        if (gameMode == TwoMachinesPlay) {
            if (cps->other->sendTime) {
                SendTimeRemaining(cps->other,
@@ -3884,7 +3951,7 @@ HandleMachineMove(message, cps)
        if (!pausing && appData.ringBellAfterMoves) {
            RingBell();
        }
-       /* 
+       /*
         * Reenable menu items that were disabled while
         * machine was thinking
         */
@@ -3956,8 +4023,8 @@ HandleMachineMove(message, cps)
        AskQuestion(realname, buf2, buf1, cps->pr);
        return;
     }
-    /* Commands from the engine directly to ICS.  We don't allow these to be 
-     *  sent until we are logged on. Crafty kibitzes have been known to 
+    /* Commands from the engine directly to ICS.  We don't allow these to be
+     *  sent until we are logged on. Crafty kibitzes have been known to
      *  interfere with the login process.
      */
     if (loggedOn) {
@@ -3994,7 +4061,7 @@ HandleMachineMove(message, cps)
      */
     if (strncmp(message + 1, "llegal move", 11) == 0 ||
        strncmp(message, "Error", 5) == 0) {
-       if (StrStr(message, "name") || 
+       if (StrStr(message, "name") ||
            StrStr(message, "rating") || StrStr(message, "?") ||
            StrStr(message, "result") || StrStr(message, "board") ||
            StrStr(message, "bk") || StrStr(message, "computer") ||
@@ -4058,7 +4125,7 @@ HandleMachineMove(message, cps)
           message in analyze mored would be ignored. */
        if (cps == &first && programStats.ok_to_send == 0) {
            /* Bogus message from Crafty responding to "."  This filtering
-              can miss some of the bad messages, but fortunately the bug 
+              can miss some of the bad messages, but fortunately the bug
               is fixed in current Crafty versions, so it doesn't matter. */
            return;
        }
@@ -4073,7 +4140,7 @@ HandleMachineMove(message, cps)
        DisplayMove(currentMove-1); /* before DisplayMoveError */
        SwitchClocks();
        DisplayBothClocks();
-       sprintf(buf1, "Illegal move \"%s\" (rejected by %s chess program)",
+       sprintf(buf1, _("Illegal move \"%s\" (rejected by %s chess program)"),
                parseList[currentMove], cps->which);
        DisplayMoveError(buf1);
        DrawPosition(FALSE, boards[currentMove]);
@@ -4085,7 +4152,7 @@ HandleMachineMove(message, cps)
           Don't use it. */
        cps->sendTime = 0;
     }
-    
+
     /*
      * If chess program startup fails, exit with an error message.
      * Attempts to recover here are futile.
@@ -4098,14 +4165,14 @@ HandleMachineMove(message, cps)
        || (StrStr(message, "Permission denied") != NULL)) {
 
        cps->maybeThinking = FALSE;
-       sprintf(buf1, "Failed to start %s chess program %s on %s: %s\n",
+       sprintf(buf1, _("Failed to start %s chess program %s on %s: %s\n"),
                cps->which, cps->program, cps->host, message);
        RemoveInputSource(cps->isr);
        DisplayFatalError(buf1, 0, 1);
        return;
     }
-    
-    /* 
+
+    /*
      * Look for hint output
      */
     if (sscanf(message, "Hint: %s", buf1) == 1) {
@@ -4121,7 +4188,7 @@ HandleMachineMove(message, cps)
            } else {
                /* Hint move could not be parsed!? */
                sprintf(buf2,
-                       "Illegal hint move \"%s\"\nfrom %s chess program",
+                       _("Illegal hint move \"%s\"\nfrom %s chess program"),
                        buf1, cps->which);
                DisplayError(buf2, 0);
            }
@@ -4293,22 +4360,22 @@ HandleMachineMove(message, cps)
        } else if (gameMode == MachinePlaysWhite ||
                   gameMode == MachinePlaysBlack) {
          if (userOfferedDraw) {
-           DisplayInformation("Machine accepts your draw offer");
+           DisplayInformation(_("Machine accepts your draw offer"));
            GameEnds(GameIsDrawn, "Draw agreed", GE_XBOARD);
          } else {
-            DisplayInformation("Machine offers a draw\nSelect Action / Draw to agree");
+            DisplayInformation(_("Machine offers a draw\nSelect Action / Draw to agree"));
          }
        }
     }
 
-    
+
     /*
      * Look for thinking output
      */
     if (appData.showThinking) {
        int plylev, mvleft, mvtot, curscore, time;
        char mvname[MOVE_LEN];
-       unsigned long nodes;
+       u64 nodes;
        char plyext;
        int ignore = FALSE;
        int prefixHint = FALSE;
@@ -4325,6 +4392,10 @@ HandleMachineMove(message, cps)
            break;
          case AnalyzeMode:
          case AnalyzeFile:
+               break;
+         /* icsEngineAnalyze */
+         case IcsObserving:
+               if (!appData.icsEngineAnalyze) ignore = TRUE;
            break;
          case TwoMachinesPlay:
            if ((cps->twoMachinesColor[0] == 'w') !=
@@ -4339,7 +4410,7 @@ HandleMachineMove(message, cps)
 
        if (!ignore) {
            buf1[0] = NULLCHAR;
-           if (sscanf(message, "%d%c %d %d %lu %[^\n]\n",
+           if (sscanf(message, "%d%c %d %d" u64Display "%[^\n]\n",
                       &plylev, &plyext, &curscore, &time, &nodes, buf1) >= 5) {
 
                if (plyext != ' ' && plyext != '\t') {
@@ -4361,7 +4432,8 @@ HandleMachineMove(message, cps)
                    }
                    strncpy(programStats.movelist, buf1,
                            sizeof(programStats.movelist));
-                   buf1[sizeof(programStats.movelist) - 1] = NULLCHAR;
+                   programStats.movelist[sizeof(programStats.movelist) - 1]
+                     = NULLCHAR;
                } else {
                    sprintf(programStats.movelist, " no PV\n");
                }
@@ -4377,17 +4449,17 @@ HandleMachineMove(message, cps)
                } else {
                    programStats.line_is_book = 0;
                }
-                 
+
                sprintf(thinkOutput, "[%d]%c%+.2f %s%s%s",
-                       plylev, 
+                       plylev,
                        (gameMode == TwoMachinesPlay ?
                         ToUpper(cps->twoMachinesColor[0]) : ' '),
                        ((double) curscore) / 100.0,
                        prefixHint ? lastHint : "",
-                       prefixHint ? " " : "", buf1);
+                       prefixHint ? " " : "", programStats.movelist);
 
-               if (currentMove == forwardMostMove ||
-                   gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
+               if (currentMove == forwardMostMove || gameMode == AnalyzeMode
+                       || gameMode == AnalyzeFile || appData.icsEngineAnalyze) {
                    DisplayMove(currentMove - 1);
                    DisplayAnalysis();
                }
@@ -4411,14 +4483,14 @@ HandleMachineMove(message, cps)
                   mean "line isn't going to change" (Crafty
                   isn't searching, so stats won't change) */
                programStats.line_is_book = 1;
-                 
+
                if (currentMove == forwardMostMove || gameMode==AnalyzeMode ||
-                   gameMode == AnalyzeFile) {
+                   gameMode == AnalyzeFile || appData.icsEngineAnalyze) {
                    DisplayMove(currentMove - 1);
                    DisplayAnalysis();
                }
                return;
-           } else if (sscanf(message,"stat01: %d %lu %d %d %d %s",
+           } else if (sscanf(message,"stat01: %d" u64Display "%d %d %d %s",
                              &time, &nodes, &plylev, &mvleft,
                              &mvtot, mvname) >= 5) {
                /* The stat01: line is from Crafty (9.29+) in response
@@ -4458,7 +4530,7 @@ HandleMachineMove(message, cps)
                strcat(programStats.movelist, " ");
                strcat(programStats.movelist, p);
                if (currentMove == forwardMostMove || gameMode==AnalyzeMode ||
-                   gameMode == AnalyzeFile) {
+                   gameMode == AnalyzeFile || appData.icsEngineAnalyze) {
                    DisplayMove(currentMove - 1);
                    DisplayAnalysis();
                }
@@ -4471,7 +4543,7 @@ HandleMachineMove(message, cps)
 
 /* Parse a game score from the character string "game", and
    record it as the history of the current game.  The game
-   score is NOT assumed to start from the standard position. 
+   score is NOT assumed to start from the standard position.
    The display is not updated in any way.
    */
 void
@@ -4551,18 +4623,18 @@ ParseGameHistory(game)
            break;
          case AmbiguousMove:
            /* bug? */
-           sprintf(buf, "Ambiguous move in ICS output: \"%s\"", yy_text);
+           sprintf(buf, _("Ambiguous move in ICS output: \"%s\""), yy_text);
            DisplayError(buf, 0);
            return;
          case ImpossibleMove:
            /* bug? */
-           sprintf(buf, "Illegal move in ICS output: \"%s\"", yy_text);
+           sprintf(buf, _("Illegal move in ICS output: \"%s\""), yy_text);
            DisplayError(buf, 0);
            return;
          case (ChessMove) 0:   /* end of file */
            if (boardIndex < backwardMostMove) {
                /* Oops, gap.  How did that happen? */
-               DisplayError("Gap in move list", 0);
+               DisplayError(_("Gap in move list"), 0);
                return;
            }
            backwardMostMove =  blackPlaysFirst ? 1 : 0;
@@ -4784,7 +4856,7 @@ MakeMove(fromX, fromY, toX, toY, promoChar)
 {
     forwardMostMove++;
     if (forwardMostMove >= MAX_MOVES) {
-      DisplayFatalError("Game too long; increase MAX_MOVES and recompile",
+      DisplayFatalError(_("Game too long; increase MAX_MOVES and recompile"),
                        0, 1);
       return;
     }
@@ -4863,7 +4935,7 @@ InitChessProgram(cps)
        gameInfo.variant != VariantLoadable) {
       char *v = VariantName(gameInfo.variant);
       if (StrStr(cps->variants, v) == NULL) {
-       sprintf(buf, "Variant %s not supported by %s", v, cps->tidy);
+       sprintf(buf, _("Variant %s not supported by %s"), v, cps->tidy);
        DisplayFatalError(buf, 0, 1);
        return;
       }
@@ -4897,7 +4969,7 @@ InitChessProgram(cps)
       SendToProgram(buf, cps);
     }
     cps->initDone = TRUE;
-}   
+}
 
 
 void
@@ -4924,7 +4996,7 @@ StartChessProgram(cps)
        }
        err = StartChildProcess(buf, "", &cps->pr);
     }
-    
+
     if (err != 0) {
        sprintf(buf, "Startup failure on '%s'", cps->program);
        DisplayFatalError(buf, err, 1);
@@ -4932,7 +5004,7 @@ StartChessProgram(cps)
        cps->isr = NULL;
        return;
     }
-    
+
     cps->isr = AddInputSource(cps->pr, TRUE, ReceiveFromProgram, cps);
     if (cps->protocolVersion > 1) {
       sprintf(buf, "xboard\nprotover %d\n", cps->protocolVersion);
@@ -4992,8 +5064,8 @@ GameEnds(result, resultDetails, whosays)
 
     if (appData.icsActive && whosays == GE_ENGINE) {
        /* If we are playing on ICS, the server decides when the
-          game is over, but the engine can offer to draw, claim 
-          a draw, or resign. 
+          game is over, but the engine can offer to draw, claim
+          a draw, or resign.
         */
 #if ZIPPY
        if (appData.zippyPlay && first.initDone) {
@@ -5021,17 +5093,17 @@ GameEnds(result, resultDetails, whosays)
 
     /* If this is an ICS game, only ICS can really say it's done;
        if not, anyone can. */
-    isIcsGame = (gameMode == IcsPlayingWhite || 
-                gameMode == IcsPlayingBlack || 
-                gameMode == IcsObserving    || 
+    isIcsGame = (gameMode == IcsPlayingWhite ||
+                gameMode == IcsPlayingBlack ||
+                gameMode == IcsObserving    ||
                 gameMode == IcsExamining);
 
     if (!isIcsGame || whosays == GE_ICS) {
        /* OK -- not an ICS game, or ICS said it was done */
        StopClocks();
-       if (!isIcsGame && !appData.noChessProgram) 
+       if (!isIcsGame && !appData.noChessProgram)
          SetUserThinkingEnables();
-    
+
        if (resultDetails != NULL) {
            gameInfo.result = result;
            gameInfo.resultDetails = StrSave(resultDetails);
@@ -5058,7 +5130,7 @@ GameEnds(result, resultDetails, whosays)
            /* display last move only if game was not loaded from file */
            if ((whosays != GE_FILE) && (currentMove == forwardMostMove))
                DisplayMove(currentMove - 1);
-    
+
            if (forwardMostMove != 0) {
                if (gameMode != PlayFromGameFile && gameMode != EditGame) {
                    if (*appData.saveGameFile != NULLCHAR) {
@@ -5112,8 +5184,8 @@ GameEnds(result, resultDetails, whosays)
                }
            }
        } else if (gameMode == EditGame ||
-                  gameMode == PlayFromGameFile || 
-                  gameMode == AnalyzeMode || 
+                  gameMode == PlayFromGameFile ||
+                  gameMode == AnalyzeMode ||
                   gameMode == AnalyzeFile) {
            nextGameMode = gameMode;
        } else {
@@ -5152,7 +5224,7 @@ GameEnds(result, resultDetails, whosays)
        if (first.isr != NULL)
          RemoveInputSource(first.isr);
        first.isr = NULL;
-    
+
        if (first.pr != NoProc) {
            ExitAnalyzeMode();
            SendToProgram("quit\n", &first);
@@ -5176,7 +5248,7 @@ GameEnds(result, resultDetails, whosays)
        if (second.isr != NULL)
          RemoveInputSource(second.isr);
        second.isr = NULL;
-    
+
        if (second.pr != NoProc) {
            SendToProgram("quit\n", &second);
            DestroyChildProcess(second.pr, second.useSigterm);
@@ -5215,7 +5287,7 @@ GameEnds(result, resultDetails, whosays)
        } else {
            char buf[MSG_SIZ];
            gameMode = nextGameMode;
-           sprintf(buf, "Match %s vs. %s: final score %d-%d-%d",
+           sprintf(buf, _("Match %s vs. %s: final score %d-%d-%d"),
                    first.tidy, second.tidy,
                    first.matchWins, second.matchWins,
                    appData.matchGames - (first.matchWins + second.matchWins));
@@ -5232,12 +5304,12 @@ GameEnds(result, resultDetails, whosays)
 /* Assumes program was just initialized (initString sent).
    Leaves program in force mode. */
 void
-FeedMovesToProgram(cps, upto) 
+FeedMovesToProgram(cps, upto)
      ChessProgramState *cps;
      int upto;
 {
     int i;
-    
+
     if (appData.debugMode)
       fprintf(debugFP, "Feeding %smoves %d through %d to %s chess program\n",
              startedFromSetupPosition ? "position and " : "",
@@ -5259,7 +5331,7 @@ ResurrectChessProgram()
        If so, restart it and feed it all the moves made so far. */
 
     if (appData.noChessProgram || first.pr != NoProc) return;
-    
+
     StartChessProgram(&first);
     InitChessProgram(&first);
     FeedMovesToProgram(&first, currentMove);
@@ -5272,8 +5344,8 @@ ResurrectChessProgram()
        timeRemaining[1][currentMove] = blackTimeRemaining;
     }
 
-    if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) &&
-       first.analysisSupport) {
+    if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile ||
+                appData.icsEngineAnalyze) && first.analysisSupport) {
       SendToProgram("analyze\n", &first);
       first.analyzing = TRUE;
     }
@@ -5310,7 +5382,7 @@ Reset(redraw, init)
     ics_gamenum = -1;
     white_holding[0] = black_holding[0] = NULLCHAR;
     ClearProgramStats();
-    
+
     ResetFrontEnd();
     ClearHighlights();
     flipView = appData.flipView;
@@ -5374,7 +5446,7 @@ AutoPlayOneMove()
       ModeHighlight();
       return FALSE;
     }
-    
+
     toX = moveList[currentMove][2] - 'a';
     toY = moveList[currentMove][3] - '1';
 
@@ -5411,13 +5483,13 @@ LoadGameOneMove(readAhead)
     ChessMove moveType;
     char move[MSG_SIZ];
     char *p, *q;
-    
-    if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile && 
+
+    if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile &&
        gameMode != AnalyzeMode && gameMode != Training) {
        gameFileFP = NULL;
        return FALSE;
     }
-    
+
     yyboardindex = forwardMostMove;
     if (readAhead != (ChessMove)0) {
       moveType = readAhead;
@@ -5426,11 +5498,11 @@ LoadGameOneMove(readAhead)
          return FALSE;
       moveType = (ChessMove) yylex();
     }
-    
+
     done = FALSE;
     switch (moveType) {
       case Comment:
-       if (appData.debugMode) 
+       if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
        if (*p == '{' || *p == '[' || *p == '(') {
@@ -5581,7 +5653,7 @@ LoadGameOneMove(readAhead)
        if (appData.testLegality) {
            if (appData.debugMode)
              fprintf(debugFP, "Parsed IllegalMove: %s\n", yy_text);
-           sprintf(move, "Illegal move: %d.%s%s",
+           sprintf(move, _("Illegal move: %d.%s%s"),
                    (forwardMostMove / 2) + 1,
                    WhiteOnMove(forwardMostMove) ? " " : ".. ", yy_text);
            DisplayError(move, 0);
@@ -5601,7 +5673,7 @@ LoadGameOneMove(readAhead)
       case AmbiguousMove:
        if (appData.debugMode)
          fprintf(debugFP, "Parsed AmbiguousMove: %s\n", yy_text);
-       sprintf(move, "Ambiguous move: %d.%s%s",
+       sprintf(move, _("Ambiguous move: %d.%s%s"),
                (forwardMostMove / 2) + 1,
                WhiteOnMove(forwardMostMove) ? " " : ".. ", yy_text);
        DisplayError(move, 0);
@@ -5612,7 +5684,7 @@ LoadGameOneMove(readAhead)
       case ImpossibleMove:
        if (appData.debugMode)
          fprintf(debugFP, "Parsed ImpossibleMove: %s\n", yy_text);
-       sprintf(move, "Illegal move: %d.%s%s",
+       sprintf(move, _("Illegal move: %d.%s%s"),
                (forwardMostMove / 2) + 1,
                WhiteOnMove(forwardMostMove) ? " " : ".. ", yy_text);
        DisplayError(move, 0);
@@ -5635,7 +5707,7 @@ LoadGameOneMove(readAhead)
        /* currentMoveString is set as a side-effect of yylex */
        strcat(currentMoveString, "\n");
        strcpy(moveList[forwardMostMove], currentMoveString);
-       
+
        thinkOutput[0] = NULLCHAR;
        MakeMove(fromX, fromY, toX, toY, promoChar);
        currentMove = forwardMostMove;
@@ -5660,7 +5732,7 @@ LoadGameFromFile(filename, n, title, useList)
     } else {
        f = fopen(filename, "rb");
        if (f == NULL) {
-           sprintf(buf, "Can't open \"%s\"", filename);
+           sprintf(buf, _("Can't open \"%s\""), filename);
            DisplayError(buf, errno);
            return FALSE;
        }
@@ -5672,7 +5744,7 @@ LoadGameFromFile(filename, n, title, useList)
     if (useList && n == 0) {
        int error = GameListBuild(f);
        if (error) {
-           DisplayError("Cannot build game list", error);
+           DisplayError(_("Cannot build game list"), error);
        } else if (!ListEmpty(&gameList) &&
                   ((ListGame *) gameList.tailPred)->number > 1) {
            GameListPopUp(f, title);
@@ -5698,7 +5770,7 @@ MakeRegisteredMove()
            if (appData.debugMode)
              fprintf(debugFP, "Restoring %s for game %d\n",
                      cmailMove[lastLoadGameNumber - 1], lastLoadGameNumber);
-    
+
            thinkOutput[0] = NULLCHAR;
            strcpy(moveList[currentMove], cmailMove[lastLoadGameNumber - 1]);
            fromX = cmailMove[lastLoadGameNumber - 1][0] - 'a';
@@ -5708,13 +5780,13 @@ MakeRegisteredMove()
            promoChar = cmailMove[lastLoadGameNumber - 1][4];
            MakeMove(fromX, fromY, toX, toY, promoChar);
            ShowMove(fromX, fromY, toX, toY);
-             
+
            switch (MateTest(boards[currentMove], PosFlags(currentMove),
                             EP_UNKNOWN)) {
              case MT_NONE:
              case MT_CHECK:
                break;
-               
+
              case MT_CHECKMATE:
                if (WhiteOnMove(currentMove)) {
                    GameEnds(BlackWins, "Black mates", GE_PLAYER);
@@ -5722,14 +5794,14 @@ MakeRegisteredMove()
                    GameEnds(WhiteWins, "White mates", GE_PLAYER);
                }
                break;
-               
+
              case MT_STALEMATE:
                GameEnds(GameIsDrawn, "Stalemate", GE_PLAYER);
                break;
            }
 
            break;
-           
+
          case CMAIL_RESIGN:
            if (WhiteOnMove(currentMove)) {
                GameEnds(BlackWins, "White resigns", GE_PLAYER);
@@ -5737,11 +5809,11 @@ MakeRegisteredMove()
                GameEnds(WhiteWins, "Black resigns", GE_PLAYER);
            }
            break;
-           
+
          case CMAIL_ACCEPT:
            GameEnds(GameIsDrawn, "Draw agreed", GE_PLAYER);
            break;
-             
+
          default:
            break;
        }
@@ -5761,7 +5833,7 @@ CmailLoadGame(f, gameNumber, title, useList)
     int retVal;
 
     if (gameNumber > nCmailGames) {
-       DisplayError("No more games in this message", 0);
+       DisplayError(_("No more games in this message"), 0);
        return FALSE;
     }
     if (f == lastLoadGameFP) {
@@ -5802,11 +5874,11 @@ ReloadGame(offset)
 {
     int gameNumber = lastLoadGameNumber + offset;
     if (lastLoadGameFP == NULL) {
-       DisplayError("No game has been loaded yet", 0);
+       DisplayError(_("No game has been loaded yet"), 0);
        return FALSE;
     }
     if (gameNumber <= 0) {
-       DisplayError("Can't back up any further", 0);
+       DisplayError(_("Can't back up any further"), 0);
        return FALSE;
     }
     if (cmailMsgLoaded) {
@@ -5836,7 +5908,7 @@ LoadGame(f, gameNumber, title, useList)
     int err;
     GameMode oldGameMode;
 
-    if (appData.debugMode) 
+    if (appData.debugMode)
        fprintf(debugFP, "LoadGame(): on entry, gameMode %d\n", gameMode);
 
     if (gameMode == Training )
@@ -5854,14 +5926,14 @@ LoadGame(f, gameNumber, title, useList)
 
     if (useList) {
        lg = (ListGame *) ListElem(&gameList, gameNumber-1);
-       
+
        if (lg) {
            fseek(f, lg->offset, 0);
            GameListHighlight(gameNumber);
            gn = 1;
        }
        else {
-           DisplayError("Game number out of range", 0);
+           DisplayError(_("Game number out of range"), 0);
            return FALSE;
        }
     } else {
@@ -5872,7 +5944,7 @@ LoadGame(f, gameNumber, title, useList)
                gameNumber == 1) {
                gn = 1;
            } else {
-               DisplayError("Can't seek on game file", 0);
+               DisplayError(_("Can't seek on game file"), 0);
                return FALSE;
            }
        }
@@ -5909,12 +5981,12 @@ LoadGame(f, gameNumber, title, useList)
 
     /*
      * Skip the first gn-1 games in the file.
-     * Also skip over anything that precedes an identifiable 
-     * start of game marker, to avoid being confused by 
-     * garbage at the start of the file.  Currently 
+     * Also skip over anything that precedes an identifiable
+     * start of game marker, to avoid being confused by
+     * garbage at the start of the file.  Currently
      * recognized start of game markers are the move number "1",
      * the pattern "gnuchess .* game", the pattern
-     * "^[#;%] [^ ]* game file", and a PGN tag block.  
+     * "^[#;%] [^ ]* game file", and a PGN tag block.
      * A game that starts with one of the latter two patterns
      * will also have a move number 1, possibly
      * following a position diagram.
@@ -5931,7 +6003,7 @@ LoadGame(f, gameNumber, title, useList)
                nCmailGames = CMAIL_MAX_GAMES - gn;
            } else {
                Reset(TRUE, TRUE);
-               DisplayError("Game not found in file", 0);
+               DisplayError(_("Game not found in file"), 0);
            }
            return FALSE;
 
@@ -5940,7 +6012,7 @@ LoadGame(f, gameNumber, title, useList)
            gn--;
            lastLoadGameStart = cm;
            break;
-           
+
          case MoveNumberOne:
            switch (lastLoadGameStart) {
              case GNUChessGame:
@@ -6008,7 +6080,7 @@ LoadGame(f, gameNumber, title, useList)
            break;
        }
     }
-    
+
     if (appData.debugMode)
       fprintf(debugFP, "Parsed game start '%s' (%d)\n", yy_text, (int) cm);
 
@@ -6034,11 +6106,11 @@ LoadGame(f, gameNumber, title, useList)
            free(gameInfo.event);
        }
        gameInfo.event = StrSave(yy_text);
-    }  
+    }
 
     startedFromSetupPosition = FALSE;
     while (cm == PGNTag) {
-       if (appData.debugMode) 
+       if (appData.debugMode)
          fprintf(debugFP, "Parsed PGNTag: %s\n", yy_text);
        err = ParsePGNTag(yy_text, &gameInfo);
        if (!err) numPGNTags++;
@@ -6048,7 +6120,7 @@ LoadGame(f, gameNumber, title, useList)
          startedFromSetupPosition = TRUE;
          if (!ParseFEN(initial_position, &blackPlaysFirst, gameInfo.fen)) {
            Reset(TRUE, TRUE);
-           DisplayError("Bad FEN position in file", 0);
+           DisplayError(_("Bad FEN position in file"), 0);
            return FALSE;
          }
          CopyBoard(boards[0], initial_position);
@@ -6077,7 +6149,7 @@ LoadGame(f, gameNumber, title, useList)
        /* Handle comments interspersed among the tags */
        while (cm == Comment) {
            char *p;
-           if (appData.debugMode) 
+           if (appData.debugMode)
              fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
            p = yy_text;
            if (*p == '{' || *p == '[' || *p == '(') {
@@ -6136,13 +6208,13 @@ LoadGame(f, gameNumber, title, useList)
                }
            while (*p == ' ' || *p == '\t' ||
                   *p == '\n' || *p == '\r') p++;
-       
+
            if (strncmp(p, "black", strlen("black"))==0)
              blackPlaysFirst = TRUE;
            else
              blackPlaysFirst = FALSE;
            startedFromSetupPosition = TRUE;
-       
+
            CopyBoard(boards[0], initial_position);
            if (blackPlaysFirst) {
                currentMove = forwardMostMove = backwardMostMove = 1;
@@ -6171,11 +6243,11 @@ LoadGame(f, gameNumber, title, useList)
     if (startedFromSetupPosition) {
        SendBoard(&first, forwardMostMove);
        DisplayBothClocks();
-    }      
+    }
 
     while (cm == Comment) {
        char *p;
-       if (appData.debugMode) 
+       if (appData.debugMode)
          fprintf(debugFP, "Parsed Comment: %s\n", yy_text);
        p = yy_text;
        if (*p == '{' || *p == '[' || *p == '(') {
@@ -6191,7 +6263,7 @@ LoadGame(f, gameNumber, title, useList)
     if ((cm == (ChessMove) 0 && lastLoadGameStart != (ChessMove) 0) ||
        cm == WhiteWins || cm == BlackWins ||
        cm == GameIsDrawn || cm == GameUnfinished) {
-       DisplayMessage("", "No moves in game");
+       DisplayMessage("", _("No moves in game"));
        if (cmailMsgLoaded) {
            if (appData.debugMode)
              fprintf(debugFP, "Setting flipView to %d.\n", FALSE);
@@ -6212,7 +6284,7 @@ LoadGame(f, gameNumber, title, useList)
        DisplayComment(currentMove - 1, commentList[currentMove]);
       }
     }
-    if (!matchMode && appData.timeDelay != 0) 
+    if (!matchMode && appData.timeDelay != 0)
       DrawPosition(FALSE, boards[currentMove]);
 
     if (gameMode == AnalyzeFile || gameMode == AnalyzeMode) {
@@ -6220,7 +6292,7 @@ LoadGame(f, gameNumber, title, useList)
     }
 
     /* if the first token after the PGN tags is a move
-     * and not move number 1, retrieve it from the parser 
+     * and not move number 1, retrieve it from the parser
      */
     if (cm != MoveNumberOne)
        LoadGameOneMove(cm);
@@ -6249,7 +6321,7 @@ LoadGame(f, gameNumber, title, useList)
       AutoPlayGameLoop();
     }
 
-    if (appData.debugMode) 
+    if (appData.debugMode)
        fprintf(debugFP, "LoadGame(): on exit, gameMode %d\n", gameMode);
     return TRUE;
 }
@@ -6261,11 +6333,11 @@ ReloadPosition(offset)
 {
     int positionNumber = lastLoadPositionNumber + offset;
     if (lastLoadPositionFP == NULL) {
-       DisplayError("No position has been loaded yet", 0);
+       DisplayError(_("No position has been loaded yet"), 0);
        return FALSE;
     }
     if (positionNumber <= 0) {
-       DisplayError("Can't back up any further", 0);
+       DisplayError(_("Can't back up any further"), 0);
        return FALSE;
     }
     return LoadPosition(lastLoadPositionFP, positionNumber,
@@ -6287,7 +6359,7 @@ LoadPositionFromFile(filename, n, title)
     } else {
        f = fopen(filename, "rb");
        if (f == NULL) {
-           sprintf(buf, "Can't open \"%s\"", filename);
+           sprintf(buf, _("Can't open \"%s\""), filename);
            DisplayError(buf, errno);
            return FALSE;
        } else {
@@ -6306,7 +6378,7 @@ LoadPosition(f, positionNumber, title)
     char *p, line[MSG_SIZ];
     Board initial_position;
     int i, j, fenMode, pn;
-    
+
     if (gameMode == Training )
        SetTrainingModeOff();
 
@@ -6323,12 +6395,12 @@ LoadPosition(f, positionNumber, title)
     if (first.pr == NoProc) {
       StartChessProgram(&first);
       InitChessProgram(&first);
-    }    
+    }
     pn = positionNumber;
     if (positionNumber < 0) {
        /* Negative position number means to seek to that byte offset */
        if (fseek(f, -positionNumber, 0) == -1) {
-           DisplayError("Can't seek on position file", 0);
+           DisplayError(_("Can't seek on position file"), 0);
            return FALSE;
        };
        pn = 1;
@@ -6339,14 +6411,14 @@ LoadPosition(f, positionNumber, title)
                positionNumber == 1) {
                pn = 1;
            } else {
-               DisplayError("Can't seek on position file", 0);
+               DisplayError(_("Can't seek on position file"), 0);
                return FALSE;
            }
        }
     }
     /* See if this file is FEN or old-style xboard */
     if (fgets(line, MSG_SIZ, f) == NULL) {
-       DisplayError("Position not found in file", 0);
+       DisplayError(_("Position not found in file"), 0);
        return FALSE;
     }
     switch (line[0]) {
@@ -6368,7 +6440,7 @@ LoadPosition(f, positionNumber, title)
            /* skip postions before number pn */
            if (fgets(line, MSG_SIZ, f) == NULL) {
                Reset(TRUE, TRUE);
-               DisplayError("Position not found in file", 0);
+               DisplayError(_("Position not found in file"), 0);
                return FALSE;
            }
            if (fenMode || line[0] == '#') pn--;
@@ -6377,13 +6449,13 @@ LoadPosition(f, positionNumber, title)
 
     if (fenMode) {
        if (!ParseFEN(initial_position, &blackPlaysFirst, line)) {
-           DisplayError("Bad FEN position in file", 0);
+           DisplayError(_("Bad FEN position in file"), 0);
            return FALSE;
        }
     } else {
        (void) fgets(line, MSG_SIZ, f);
        (void) fgets(line, MSG_SIZ, f);
-    
+
        for (i = BOARD_SIZE - 1; i >= 0; i--) {
            (void) fgets(line, MSG_SIZ, f);
            for (p = line, j = 0; j < BOARD_SIZE; p++) {
@@ -6392,7 +6464,7 @@ LoadPosition(f, positionNumber, title)
                initial_position[i][j++] = CharToPiece(*p);
            }
        }
-    
+
        blackPlaysFirst = FALSE;
        if (!feof(f)) {
            (void) fgets(line, MSG_SIZ, f);
@@ -6401,7 +6473,7 @@ LoadPosition(f, positionNumber, title)
        }
     }
     startedFromSetupPosition = TRUE;
-    
+
     SendToProgram("force\n", &first);
     CopyBoard(boards[0], initial_position);
     if (blackPlaysFirst) {
@@ -6409,10 +6481,10 @@ LoadPosition(f, positionNumber, title)
        strcpy(moveList[0], "");
        strcpy(parseList[0], "");
        CopyBoard(boards[1], initial_position);
-       DisplayMessage("", "Black to play");
+       DisplayMessage("", _("Black to play"));
     } else {
        currentMove = forwardMostMove = backwardMostMove = 0;
-       DisplayMessage("", "White to play");
+       DisplayMessage("", _("White to play"));
     }
     SendBoard(&first, forwardMostMove);
 
@@ -6428,7 +6500,7 @@ LoadPosition(f, positionNumber, title)
     timeRemaining[0][1] = whiteTimeRemaining;
     timeRemaining[1][1] = blackTimeRemaining;
     DrawPosition(FALSE, boards[currentMove]);
-   
+
     return TRUE;
 }
 
@@ -6480,7 +6552,7 @@ SaveGameToFile(filename, append)
     } else {
        f = fopen(filename, append ? "a" : "w");
        if (f == NULL) {
-           sprintf(buf, "Can't open \"%s\"", filename);
+           sprintf(buf, _("Can't open \"%s\""), filename);
            DisplayError(buf, errno);
            return FALSE;
        } else {
@@ -6495,7 +6567,7 @@ SavePart(str)
 {
     static char buf[MSG_SIZ];
     char *p;
-    
+
     p = strchr(str, ' ');
     if (p == NULL) return str;
     strncpy(buf, str, p - str);
@@ -6515,11 +6587,11 @@ SaveGamePGN(f)
     char *movetext;
     char numtext[32];
     int movelen, numlen, blank;
-    
+
     tm = time((time_t *) NULL);
-    
+
     PrintPGNTags(f, &gameInfo);
-    
+
     if (backwardMostMove > 0 || startedFromSetupPosition) {
         char *fen = PositionToFEN(backwardMostMove);
         fprintf(f, "[FEN \"%s\"]\n[SetUp \"1\"]\n", fen);
@@ -6592,7 +6664,7 @@ SaveGamePGN(f)
 
        i++;
     }
-    
+
     /* Start a new line */
     if (linelen > 0) fprintf(f, "\n");
 
@@ -6621,12 +6693,12 @@ SaveGameOldStyle(f)
 {
     int i, offset;
     time_t tm;
-    
+
     tm = time((time_t *) NULL);
-    
+
     fprintf(f, "# %s game file -- %s", programName, ctime(&tm));
     PrintOpponents(f);
-    
+
     if (backwardMostMove > 0 || startedFromSetupPosition) {
        fprintf(f, "\n[--------------\n");
        PrintPosition(f, backwardMostMove);
@@ -6661,7 +6733,7 @@ SaveGameOldStyle(f)
            i++;
        }
     }
-    
+
     if (commentList[i] != NULL) {
        fprintf(f, "[%s]\n", commentList[i]);
     }
@@ -6706,7 +6778,7 @@ SavePositionToFile(filename)
     } else {
        f = fopen(filename, "a");
        if (f == NULL) {
-           sprintf(buf, "Can't open \"%s\"", filename);
+           sprintf(buf, _("Can't open \"%s\""), filename);
            DisplayError(buf, errno);
            return FALSE;
        } else {
@@ -6725,10 +6797,10 @@ SavePosition(f, dummy, dummy2)
 {
     time_t tm;
     char *fen;
-    
+
     if (appData.oldSaveStyle) {
        tm = time((time_t *) NULL);
-    
+
        fprintf(f, "# %s position file -- %s", programName, ctime(&tm));
        PrintOpponents(f);
        fprintf(f, "[--------------\n");
@@ -6753,7 +6825,7 @@ ReloadCmailMsgEvent(unregister)
     int i;
     struct stat inbuf, outbuf;
     int status;
-    
+
     /* Any registered moves are unregistered if unregister is set, */
     /* i.e. invoked by the signal handler */
     if (unregister) {
@@ -6781,7 +6853,7 @@ ReloadCmailMsgEvent(unregister)
        outFilename = (char *) malloc(strlen(appData.cmailGameName) + 5);
        sprintf(outFilename, "%s.out", appData.cmailGameName);
     }
-    
+
     status = stat(outFilename, &outbuf);
     if (status < 0) {
        cmailMailedMove = FALSE;
@@ -6789,10 +6861,10 @@ ReloadCmailMsgEvent(unregister)
        status = stat(inFilename, &inbuf);
        cmailMailedMove = (inbuf.st_mtime < outbuf.st_mtime);
     }
-    
+
     /* LoadGameFromFile(CMAIL_MAX_GAMES) with cmailMsgLoaded == TRUE
        counts the games, notes how each one terminated, etc.
-       
+
        It would be nice to remove this kludge and instead gather all
        the information while building the game list.  (And to keep it
        in the game list nodes instead of having a bunch of fixed-size
@@ -6802,7 +6874,7 @@ ReloadCmailMsgEvent(unregister)
        */
     cmailMsgLoaded = TRUE;
     LoadGameFromFile(inFilename, CMAIL_MAX_GAMES, "", FALSE);
-    
+
     /* Load first game in the file or popup game menu */
     LoadGameFromFile(inFilename, 0, appData.cmailGameName, TRUE);
 
@@ -6828,7 +6900,7 @@ RegisterMove()
        cmailMoveRegistered[lastLoadGameNumber - 1] = FALSE;
        nCmailMovesRegistered --;
 
-       if (cmailCommentList[lastLoadGameNumber - 1] != NULL) 
+       if (cmailCommentList[lastLoadGameNumber - 1] != NULL)
          {
              free(cmailCommentList[lastLoadGameNumber - 1]);
              cmailCommentList[lastLoadGameNumber - 1] = NULL;
@@ -6836,17 +6908,17 @@ RegisterMove()
     }
 
     if (cmailOldMove == -1) {
-       DisplayError("You have edited the game history.\nUse Reload Same Game and make your move again.", 0);
+       DisplayError(_("You have edited the game history.\nUse Reload Same Game and make your move again."), 0);
        return FALSE;
     }
 
     if (currentMove > cmailOldMove + 1) {
-       DisplayError("You have entered too many moves.\nBack up to the correct position and try again.", 0);
+       DisplayError(_("You have entered too many moves.\nBack up to the correct position and try again."), 0);
        return FALSE;
     }
 
     if (currentMove < cmailOldMove) {
-       DisplayError("Displayed position is not current.\nStep forward to the correct position and try again.", 0);
+       DisplayError(_("Displayed position is not current.\nStep forward to the correct position and try again."), 0);
        return FALSE;
     }
 
@@ -6875,11 +6947,11 @@ RegisterMove()
 
        sprintf(string,
                "%s.game.out.%d", appData.cmailGameName, lastLoadGameNumber);
-       
+
        f = fopen(string, "w");
        if (appData.oldSaveStyle) {
            SaveGameOldStyle(f); /* also closes the file */
-           
+
            sprintf(string, "%s.pos.out", appData.cmailGameName);
            f = fopen(string, "w");
            SavePosition(f, 0, NULL); /* also closes the file */
@@ -6887,14 +6959,14 @@ RegisterMove()
            fprintf(f, "{--------------\n");
            PrintPosition(f, currentMove);
            fprintf(f, "--------------}\n\n");
-           
+
            SaveGame(f, 0, NULL); /* also closes the file*/
        }
-       
+
        cmailMoveRegistered[lastLoadGameNumber - 1] = TRUE;
        nCmailMovesRegistered ++;
     } else if (nCmailGames == 1) {
-       DisplayError("You have not made a move yet", 0);
+       DisplayError(_("You have not made a move yet"), 0);
        return FALSE;
     }
 
@@ -6915,33 +6987,33 @@ MailMoveEvent()
     char *arcDir;
 
     if (! cmailMsgLoaded) {
-       DisplayError("The cmail message is not loaded.\nUse Reload CMail Message and make your move again.", 0);
+       DisplayError(_("The cmail message is not loaded.\nUse Reload CMail Message and make your move again."), 0);
        return;
     }
 
     if (nCmailGames == nCmailResults) {
-       DisplayError("No unfinished games", 0);
+       DisplayError(_("No unfinished games"), 0);
        return;
     }
 
 #if CMAIL_PROHIBIT_REMAIL
     if (cmailMailedMove) {
-       sprintf(msg, "You have already mailed a move.\nWait until a move arrives from your opponent.\nTo resend the same move, type\n\"cmail -remail -game %s\"\non the command line.", appData.cmailGameName);
+       sprintf(msg, _("You have already mailed a move.\nWait until a move arrives from your opponent.\nTo resend the same move, type\n\"cmail -remail -game %s\"\non the command line."), appData.cmailGameName);
        DisplayError(msg, 0);
        return;
     }
 #endif
 
     if (! (cmailMailedMove || RegisterMove())) return;
-    
+
     if (   cmailMailedMove
        || (nCmailMovesRegistered + nCmailResults == nCmailGames)) {
        sprintf(string, partCommandString,
                appData.debugMode ? " -v" : "", appData.cmailGameName);
-       commandOutput = popen(string, "rb");
+       commandOutput = popen(string, "r");
 
        if (commandOutput == NULL) {
-           DisplayError("Failed to invoke cmail", 0);
+           DisplayError(_("Failed to invoke cmail"), 0);
        } else {
            for (nBuffers = 0; (! feof(commandOutput)); nBuffers ++) {
                nBytes = fread(buffer, 1, MSG_SIZ - 1, commandOutput);
@@ -6999,11 +7071,11 @@ CmailMsg()
     char number[5];
     char string[MSG_SIZ];      /* Space for game-list */
     int  i;
-    
+
     if (!cmailMsgLoaded) return "";
 
     if (cmailMailedMove) {
-       sprintf(cmailMsg, "Waiting for reply from opponent\n");
+       sprintf(cmailMsg, _("Waiting for reply from opponent\n"));
     } else {
        /* Create a list of games left */
        sprintf(string, "[");
@@ -7016,7 +7088,7 @@ CmailMsg()
                    sprintf(number, "%d", i + 1);
                    prependComma = 1;
                }
-               
+
                strcat(string, number);
            }
        }
@@ -7026,17 +7098,17 @@ CmailMsg()
            switch (nCmailGames) {
              case 1:
                sprintf(cmailMsg,
-                       "Still need to make move for game\n");
+                       _("Still need to make move for game\n"));
                break;
-               
+
              case 2:
                sprintf(cmailMsg,
-                       "Still need to make moves for both games\n");
+                       _("Still need to make moves for both games\n"));
                break;
-               
+
              default:
                sprintf(cmailMsg,
-                       "Still need to make moves for all %d games\n",
+                       _("Still need to make moves for all %d games\n"),
                        nCmailGames);
                break;
            }
@@ -7044,21 +7116,21 @@ CmailMsg()
            switch (nCmailGames - nCmailMovesRegistered - nCmailResults) {
              case 1:
                sprintf(cmailMsg,
-                       "Still need to make a move for game %s\n",
+                       _("Still need to make a move for game %s\n"),
                        string);
                break;
-               
+
              case 0:
                if (nCmailResults == nCmailGames) {
-                   sprintf(cmailMsg, "No unfinished games\n");
+                   sprintf(cmailMsg, _("No unfinished games\n"));
                } else {
-                   sprintf(cmailMsg, "Ready to send mail\n");
+                   sprintf(cmailMsg, _("Ready to send mail\n"));
                }
                break;
-               
+
              default:
                sprintf(cmailMsg,
-                       "Still need to make moves for games %s\n",
+                       _("Still need to make moves for games %s\n"),
                        string);
            }
        }
@@ -7154,7 +7226,7 @@ PauseEvent()
            DisplayBothClocks();
        }
        if (gameMode == PlayFromGameFile) {
-           if (appData.timeDelay >= 0) 
+           if (appData.timeDelay >= 0)
                AutoPlayGameLoop();
        } else if (gameMode == IcsExamining && pauseExamInvalid) {
            Reset(FALSE, TRUE);
@@ -7210,9 +7282,9 @@ EditCommentEvent()
     char title[MSG_SIZ];
 
     if (currentMove < 1 || parseList[currentMove - 1][0] == NULLCHAR) {
-       strcpy(title, "Edit comment");
+       strcpy(title, _("Edit comment"));
     } else {
-       sprintf(title, "Edit comment on %d.%s%s", (currentMove - 1) / 2 + 1,
+       sprintf(title, _("Edit comment on %d.%s%s"), (currentMove - 1) / 2 + 1,
                WhiteOnMove(currentMove - 1) ? " " : ".. ",
                parseList[currentMove - 1]);
     }
@@ -7236,17 +7308,19 @@ AnalyzeModeEvent()
       return;
 
     if (gameMode != AnalyzeFile) {
-       EditGameEvent();
-       if (gameMode != EditGame) return;
+               if (!appData.icsEngineAnalyze) {
+                       EditGameEvent();
+               if (gameMode != EditGame) return;
+               }
        ResurrectChessProgram();
        SendToProgram("analyze\n", &first);
        first.analyzing = TRUE;
        /*first.maybeThinking = TRUE;*/
        first.maybeThinking = FALSE; /* avoid killing GNU Chess */
-       AnalysisPopUp("Analysis",
-                     "Starting analysis mode...\nIf this message stays up, your chess program does not support analysis.");
+       AnalysisPopUp(_("Analysis"),
+                     _("Starting analysis mode...\nIf this message stays up, your chess program does not support analysis."));
     }
-    gameMode = AnalyzeMode;
+    if (!appData.icsEngineAnalyze) gameMode = AnalyzeMode;
     pausing = FALSE;
     ModeHighlight();
     SetGameInfo();
@@ -7270,8 +7344,8 @@ AnalyzeFileEvent()
        first.analyzing = TRUE;
        /*first.maybeThinking = TRUE;*/
        first.maybeThinking = FALSE; /* avoid killing GNU Chess */
-       AnalysisPopUp("Analysis",
-                     "Starting analysis mode...\nIf this message stays up, your chess program does not support analysis.");
+       AnalysisPopUp(_("Analysis"),
+                     _("Starting analysis mode...\nIf this message stays up, your chess program does not support analysis."));
     }
     gameMode = AnalyzeFile;
     pausing = FALSE;
@@ -7292,25 +7366,25 @@ MachineWhiteEvent()
       return;
 
 
-    if (gameMode == PlayFromGameFile || 
-       gameMode == TwoMachinesPlay  || 
-       gameMode == Training         || 
-       gameMode == AnalyzeMode      || 
+    if (gameMode == PlayFromGameFile ||
+       gameMode == TwoMachinesPlay  ||
+       gameMode == Training         ||
+       gameMode == AnalyzeMode      ||
        gameMode == EndOfGame)
        EditGameEvent();
 
-    if (gameMode == EditPosition) 
+    if (gameMode == EditPosition)
         EditPositionDone();
 
     if (!WhiteOnMove(currentMove)) {
-       DisplayError("It is not White's turn", 0);
+       DisplayError(_("It is not White's turn"), 0);
        return;
     }
-  
+
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
       ExitAnalyzeMode();
 
-    if (gameMode == EditGame || gameMode == AnalyzeMode || 
+    if (gameMode == EditGame || gameMode == AnalyzeMode ||
        gameMode == AnalyzeFile)
        TruncateGame();
 
@@ -7355,25 +7429,25 @@ MachineBlackEvent()
        return;
 
 
-    if (gameMode == PlayFromGameFile || 
-       gameMode == TwoMachinesPlay  || 
-       gameMode == Training         || 
-       gameMode == AnalyzeMode      || 
+    if (gameMode == PlayFromGameFile ||
+       gameMode == TwoMachinesPlay  ||
+       gameMode == Training         ||
+       gameMode == AnalyzeMode      ||
        gameMode == EndOfGame)
         EditGameEvent();
 
-    if (gameMode == EditPosition) 
+    if (gameMode == EditPosition)
         EditPositionDone();
 
     if (WhiteOnMove(currentMove)) {
-       DisplayError("It is not Black's turn", 0);
+       DisplayError(_("It is not Black's turn"), 0);
        return;
     }
-    
+
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile)
       ExitAnalyzeMode();
 
-    if (gameMode == EditGame || gameMode == AnalyzeMode || 
+    if (gameMode == EditGame || gameMode == AnalyzeMode ||
        gameMode == AnalyzeFile)
        TruncateGame();
 
@@ -7438,7 +7512,7 @@ TwoMachinesEvent P((void))
     int i;
     char buf[MSG_SIZ];
     ChessProgramState *onmove;
-    
+
     if (appData.noChessProgram) return;
 
     switch (gameMode) {
@@ -7447,7 +7521,7 @@ TwoMachinesEvent P((void))
       case MachinePlaysWhite:
       case MachinePlaysBlack:
        if (WhiteOnMove(forwardMostMove) == (gameMode == MachinePlaysWhite)) {
-           DisplayError("Wait until your turn,\nor select Move Now", 0);
+           DisplayError(_("Wait until your turn,\nor select Move Now"), 0);
            return;
        }
        /* fall through */
@@ -7479,7 +7553,7 @@ TwoMachinesEvent P((void))
        } else {
          /* kludge: allow timeout for initial "feature" command */
          FreezeUI();
-         DisplayMessage("", "Starting second chess program");
+         DisplayMessage("", _("Starting second chess program"));
          ScheduleDelayedEvent(TwoMachinesEventIfReady, FEATURE_TIMEOUT);
        }
        return;
@@ -7544,7 +7618,7 @@ TrainingEvent()
     if (gameMode == Training) {
       SetTrainingModeOff();
       gameMode = PlayFromGameFile;
-      DisplayMessage("", "Training mode off");
+      DisplayMessage("", _("Training mode off"));
     } else {
       gameMode = Training;
       animateTraining = appData.animate;
@@ -7552,10 +7626,10 @@ TrainingEvent()
       /* make sure we are not already at the end of the game */
       if (currentMove < forwardMostMove) {
        SetTrainingModeOn();
-       DisplayMessage("", "Training mode on");
+       DisplayMessage("", _("Training mode on"));
       } else {
        gameMode = PlayFromGameFile;
-       DisplayError("Already at end of game", 0);
+       DisplayError(_("Already at end of game"), 0);
       }
     }
     ModeHighlight();
@@ -7585,7 +7659,7 @@ IcsClientEvent()
       case AnalyzeFile:
        ExitAnalyzeMode();
        break;
-       
+
       default:
        EditGameEvent();
        break;
@@ -7636,13 +7710,13 @@ EditGameEvent()
        break;
       case IcsPlayingBlack:
       case IcsPlayingWhite:
-       DisplayError("Warning: You are still playing a game", 0);
+       DisplayError(_("Warning: You are still playing a game"), 0);
        break;
       case IcsObserving:
-       DisplayError("Warning: You are still observing a game", 0);
+       DisplayError(_("Warning: You are still observing a game"), 0);
        break;
       case IcsExamining:
-       DisplayError("Warning: You are still examining a game", 0);
+       DisplayError(_("Warning: You are still examining a game"), 0);
        break;
       case IcsIdle:
        break;
@@ -7650,7 +7724,7 @@ EditGameEvent()
       default:
        return;
     }
-    
+
     pausing = FALSE;
     StopClocks();
     first.offeredDraw = second.offeredDraw = 0;
@@ -7677,8 +7751,8 @@ EditGameEvent()
            whiteFlag = blackFlag = 0;
        }
        DisplayTitle("");
-    }          
-    
+    }
+
     gameMode = EditGame;
     ModeHighlight();
     SetGameInfo();
@@ -7692,16 +7766,16 @@ EditPositionEvent()
        EditGameEvent();
        return;
     }
-    
+
     EditGameEvent();
     if (gameMode != EditGame) return;
-    
+
     gameMode = EditPosition;
     ModeHighlight();
     SetGameInfo();
     if (currentMove > 0)
       CopyBoard(boards[0], boards[currentMove]);
-    
+
     blackPlaysFirst = !WhiteOnMove(currentMove);
     ResetClocks();
     currentMove = forwardMostMove = backwardMostMove = 0;
@@ -7712,6 +7786,11 @@ EditPositionEvent()
 void
 ExitAnalyzeMode()
 {
+       /* icsEngineAnalyze - possible call from other functions */
+       if (appData.icsEngineAnalyze) {
+           appData.icsEngineAnalyze = FALSE;
+               DisplayMessage("","Close ICS engine analyze...");
+       }
     if (first.analysisSupport && first.analyzing) {
       SendToProgram("exit\n", &first);
       first.analyzing = FALSE;
@@ -7768,7 +7847,7 @@ SendMultiLineToICS(buf)
     len = strlen(buf);
     if (len > MSG_SIZ)
       len = MSG_SIZ;
-  
+
     strncpy(temp, buf, len);
     temp[len] = 0;
 
@@ -7890,7 +7969,7 @@ DropMenuEvent(selection, x, y)
       case IcsPlayingWhite:
       case MachinePlaysBlack:
        if (!WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is Black's turn");
+           DisplayMoveError(_("It is Black's turn"));
            return;
        }
        moveType = WhiteDrop;
@@ -7898,7 +7977,7 @@ DropMenuEvent(selection, x, y)
       case IcsPlayingBlack:
       case MachinePlaysWhite:
        if (WhiteOnMove(currentMove)) {
-           DisplayMoveError("It is White's turn");
+           DisplayMoveError(_("It is White's turn"));
            return;
        }
        moveType = BlackDrop;
@@ -7915,7 +7994,7 @@ DropMenuEvent(selection, x, y)
                                 + (int) BlackPawn - (int) WhitePawn);
     }
     if (boards[currentMove][y][x] != EmptySquare) {
-       DisplayMoveError("That square is occupied");
+       DisplayMoveError(_("That square is occupied"));
        return;
     }
 
@@ -7926,7 +8005,7 @@ void
 AcceptEvent()
 {
     /* Accept a pending offer of any kind from opponent */
-    
+
     if (appData.icsActive) {
         SendToICS(ics_prefix);
        SendToICS("accept\n");
@@ -7939,7 +8018,7 @@ AcceptEvent()
            GameEnds(GameIsDrawn, "Draw agreed", GE_PLAYER);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_ACCEPT;
        } else {
-           DisplayError("There is no pending offer on this move", 0);
+           DisplayError(_("There is no pending offer on this move"), 0);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_MOVE;
        }
     } else {
@@ -7951,7 +8030,7 @@ void
 DeclineEvent()
 {
     /* Decline a pending offer of any kind from opponent */
-    
+
     if (appData.icsActive) {
         SendToICS(ics_prefix);
        SendToICS("decline\n");
@@ -7965,7 +8044,7 @@ DeclineEvent()
            DisplayComment(cmailOldMove - 1, "Draw declined");
 #endif /*NOTDEF*/
        } else {
-           DisplayError("There is no pending offer on this move", 0);
+           DisplayError(_("There is no pending offer on this move"), 0);
        }
     } else {
        /* Not used for offers from chess program */
@@ -8001,7 +8080,7 @@ CallFlagEvent()
                else
                  GameEnds(BlackWins, "Black wins on time", GE_PLAYER);
            } else {
-               DisplayError("Your opponent is not out of time", 0);
+               DisplayError(_("Your opponent is not out of time"), 0);
            }
            break;
          case MachinePlaysBlack:
@@ -8012,7 +8091,7 @@ CallFlagEvent()
                else
                  GameEnds(WhiteWins, "White wins on time", GE_PLAYER);
            } else {
-               DisplayError("Your opponent is not out of time", 0);
+               DisplayError(_("Your opponent is not out of time"), 0);
            }
            break;
        }
@@ -8023,14 +8102,14 @@ void
 DrawEvent()
 {
     /* Offer draw or accept pending draw offer from opponent */
-    
+
     if (appData.icsActive) {
        /* Note: tournament rules require draw offers to be
           made after you make your move but before you punch
           your clock.  Currently ICS doesn't let you do that;
           instead, you immediately punch your clock after making
           a move, but you can offer a draw at any time. */
-       
+
         SendToICS(ics_prefix);
        SendToICS("draw\n");
     } else if (cmailMsgLoaded) {
@@ -8047,7 +8126,7 @@ DrawEvent()
            DisplayComment(currentMove - 1, offer);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_DRAW;
        } else {
-           DisplayError("You must make your move before offering a draw", 0);
+           DisplayError(_("You must make your move before offering a draw"), 0);
            cmailMoveType[lastLoadGameNumber - 1] = CMAIL_MOVE;
        }
     } else if (first.offeredDraw) {
@@ -8064,7 +8143,7 @@ void
 AdjournEvent()
 {
     /* Offer Adjourn or accept pending Adjourn offer from opponent */
-    
+
     if (appData.icsActive) {
         SendToICS(ics_prefix);
        SendToICS("adjourn\n");
@@ -8078,7 +8157,7 @@ void
 AbortEvent()
 {
     /* Offer Abort or accept pending Abort offer from opponent */
-    
+
     if (appData.icsActive) {
         SendToICS(ics_prefix);
        SendToICS("abort\n");
@@ -8091,7 +8170,7 @@ void
 ResignEvent()
 {
     /* Resign.  You can do this even if it's not your turn. */
-    
+
     if (appData.icsActive) {
         SendToICS(ics_prefix);
        SendToICS("resign\n");
@@ -8152,12 +8231,12 @@ ForwardInner(target)
 
     if (gameMode == PlayFromGameFile && !pausing)
       PauseEvent();
-    
+
     if (gameMode == IcsExamining && pausing)
       limit = pauseExamForwardMostMove;
     else
       limit = forwardMostMove;
-    
+
     if (target > limit) target = limit;
 
     if (target > 0 && moveList[target - 1][0]) {
@@ -8179,8 +8258,8 @@ ForwardInner(target)
            }
        }
     }
-    if (gameMode == EditGame || gameMode == AnalyzeMode || 
-       gameMode == Training || gameMode == PlayFromGameFile || 
+    if (gameMode == EditGame || gameMode == AnalyzeMode ||
+       gameMode == Training || gameMode == PlayFromGameFile ||
        gameMode == AnalyzeFile) {
        while (currentMove < target) {
            SendMoveToProgram(currentMove++, &first);
@@ -8188,7 +8267,7 @@ ForwardInner(target)
     } else {
        currentMove = target;
     }
-    
+
     if (gameMode == EditGame || gameMode == EndOfGame) {
        whiteTimeRemaining = timeRemaining[0][currentMove];
        blackTimeRemaining = timeRemaining[1][currentMove];
@@ -8221,13 +8300,13 @@ ToEndEvent()
        /* to optimze, we temporarily turn off analysis mode while we feed
         * the remaining moves to the engine. Otherwise we get analysis output
         * after each move.
-        */ 
+        */
         if (first.analysisSupport) {
          SendToProgram("exit\nforce\n", &first);
          first.analyzing = FALSE;
        }
     }
-       
+
     if (gameMode == IcsExamining && !pausing) {
         SendToICS(ics_prefix);
        SendToICS("forward 999999\n");
@@ -8260,7 +8339,7 @@ BackwardInner(target)
     }
     if (gameMode == PlayFromGameFile && !pausing)
       PauseEvent();
-    
+
     if (moveList[target][0]) {
        int fromX, fromY, toX, toY;
        toX = moveList[target][2] - 'a';
@@ -8289,7 +8368,7 @@ BackwardInner(target)
     } else {
        currentMove = target;
     }
-    
+
     if (gameMode == EditGame || gameMode == EndOfGame) {
        whiteTimeRemaining = timeRemaining[0][currentMove];
        blackTimeRemaining = timeRemaining[1][currentMove];
@@ -8320,7 +8399,7 @@ ToStartEvent()
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
        /* to optimze, we temporarily turn off analysis mode while we undo
         * all the moves. Otherwise we get analysis output after each undo.
-        */ 
+        */
         if (first.analysisSupport) {
          SendToProgram("exit\nforce\n", &first);
          first.analyzing = FALSE;
@@ -8360,11 +8439,11 @@ void
 RevertEvent()
 {
     if (gameMode != IcsExamining) {
-       DisplayError("You are not examining a game", 0);
+       DisplayError(_("You are not examining a game"), 0);
        return;
     }
     if (pausing) {
-       DisplayError("You can't revert while pausing", 0);
+       DisplayError(_("You can't revert while pausing"), 0);
        return;
     }
     SendToICS(ics_prefix);
@@ -8378,7 +8457,7 @@ RetractMoveEvent()
       case MachinePlaysWhite:
       case MachinePlaysBlack:
        if (WhiteOnMove(forwardMostMove) == (gameMode == MachinePlaysWhite)) {
-           DisplayError("Wait until your turn,\nor select Move Now", 0);
+           DisplayError(_("Wait until your turn,\nor select Move Now"), 0);
            return;
        }
        if (forwardMostMove < 2) return;
@@ -8418,14 +8497,14 @@ MoveNowEvent()
     switch (gameMode) {
       case MachinePlaysWhite:
        if (!WhiteOnMove(forwardMostMove)) {
-           DisplayError("It is your turn", 0);
+           DisplayError(_("It is your turn"), 0);
            return;
        }
        cps = &first;
        break;
       case MachinePlaysBlack:
        if (WhiteOnMove(forwardMostMove)) {
-           DisplayError("It is your turn", 0);
+           DisplayError(_("It is your turn"), 0);
            return;
        }
        cps = &first;
@@ -8475,19 +8554,19 @@ HintEvent()
     switch (gameMode) {
       case MachinePlaysWhite:
        if (WhiteOnMove(forwardMostMove)) {
-           DisplayError("Wait until your turn", 0);
+           DisplayError(_("Wait until your turn"), 0);
            return;
        }
        break;
       case BeginningOfGame:
       case MachinePlaysBlack:
        if (!WhiteOnMove(forwardMostMove)) {
-           DisplayError("Wait until your turn", 0);
+           DisplayError(_("Wait until your turn"), 0);
            return;
        }
        break;
       default:
-       DisplayError("No hint available", 0);
+       DisplayError(_("No hint available"), 0);
        return;
     }
     SendToProgram("hint\n", &first);
@@ -8501,14 +8580,14 @@ BookEvent()
     switch (gameMode) {
       case MachinePlaysWhite:
        if (WhiteOnMove(forwardMostMove)) {
-           DisplayError("Wait until your turn", 0);
+           DisplayError(_("Wait until your turn"), 0);
            return;
        }
        break;
       case BeginningOfGame:
       case MachinePlaysBlack:
        if (!WhiteOnMove(forwardMostMove)) {
-           DisplayError("Wait until your turn", 0);
+           DisplayError(_("Wait until your turn"), 0);
            return;
        }
        break;
@@ -8541,7 +8620,7 @@ PrintPosition(fp, move)
      int move;
 {
     int i, j;
-    
+
     for (i = BOARD_SIZE - 1; i >= 0; i--) {
        for (j = 0; j < BOARD_SIZE; j++) {
            char c = PieceToChar(boards[move][i][j]);
@@ -8781,19 +8860,19 @@ SendToProgram(message, cps)
 
     if (cps->pr == NULL) return;
     Attention(cps);
-    
+
     if (appData.debugMode) {
        TimeMark now;
        GetTimeMark(&now);
-       fprintf(debugFP, "%ld >%-6s: %s", 
+       fprintf(debugFP, "%ld >%-6s: %s",
                SubtractTimeMarks(&now, &programStartTime),
                cps->which, message);
     }
-    
+
     count = strlen(message);
     outCount = OutputToProcess(cps->pr, message, count, &error);
     if (outCount < count && !exiting) {
-       sprintf(buf, "Error writing to %s chess program", cps->which);
+       sprintf(buf, _("Error writing to %s chess program"), cps->which);
        DisplayFatalError(buf, error, 1);
     }
 }
@@ -8814,13 +8893,13 @@ ReceiveFromProgram(isr, closure, message, count, error)
     if (count <= 0) {
        if (count == 0) {
            sprintf(buf,
-                   "Error: %s chess program (%s) exited unexpectedly",
+                   _("Error: %s chess program (%s) exited unexpectedly"),
                    cps->which, cps->program);
            RemoveInputSource(cps->isr);
            DisplayFatalError(buf, 0, 1);
        } else {
            sprintf(buf,
-                   "Error reading from %s chess program (%s)",
+                   _("Error reading from %s chess program (%s)"),
                    cps->which, cps->program);
            RemoveInputSource(cps->isr);
            DisplayFatalError(buf, error, 1);
@@ -8828,20 +8907,31 @@ ReceiveFromProgram(isr, closure, message, count, error)
        GameEnds((ChessMove) 0, NULL, GE_PLAYER);
        return;
     }
-    
+
     if ((end_str = strchr(message, '\r')) != NULL)
       *end_str = NULLCHAR;
     if ((end_str = strchr(message, '\n')) != NULL)
       *end_str = NULLCHAR;
-    
+
     if (appData.debugMode) {
        TimeMark now;
        GetTimeMark(&now);
-       fprintf(debugFP, "%ld <%-6s: %s\n", 
+       fprintf(debugFP, "%ld <%-6s: %s\n",
                SubtractTimeMarks(&now, &programStartTime),
                cps->which, message);
     }
-    HandleMachineMove(message, cps);
+       /* if icsEngineAnalyze is active we block all
+          whisper and kibitz output, because nobody want
+          see this
+        */
+       if (appData.icsEngineAnalyze) {
+               if (strstr(message, "whisper") != NULL ||
+                   strstr(message, "kibitz") != NULL ||
+                       strstr(message, "tellics") != NULL) return;
+               HandleMachineMove(message, cps);
+       } else {
+               HandleMachineMove(message, cps);
+       }
 }
 
 
@@ -8914,7 +9004,7 @@ SendTimeRemaining(cps, machineWhite)
     }
     if (time <= 0) time = 1;
     if (otime <= 0) otime = 1;
-    
+
     sprintf(message, "time %ld\notim %ld\n", time, otime);
     SendToProgram(message, cps);
 }
@@ -9001,7 +9091,7 @@ FeatureDone(cps, val)
 void
 ParseFeatures(args, cps)
      char* args;
-     ChessProgramState *cps;  
+     ChessProgramState *cps;
 {
   char *p = args;
   char *q;
@@ -9013,10 +9103,10 @@ ParseFeatures(args, cps)
     if (*p == NULLCHAR) return;
 
     if (BoolFeature(&p, "setboard", &cps->useSetboard, cps)) continue;
-    if (BoolFeature(&p, "time", &cps->sendTime, cps)) continue;    
-    if (BoolFeature(&p, "draw", &cps->sendDrawOffers, cps)) continue;    
-    if (BoolFeature(&p, "sigint", &cps->useSigint, cps)) continue;    
-    if (BoolFeature(&p, "sigterm", &cps->useSigterm, cps)) continue;    
+    if (BoolFeature(&p, "time", &cps->sendTime, cps)) continue;
+    if (BoolFeature(&p, "draw", &cps->sendDrawOffers, cps)) continue;
+    if (BoolFeature(&p, "sigint", &cps->useSigint, cps)) continue;
+    if (BoolFeature(&p, "sigterm", &cps->useSigterm, cps)) continue;
     if (BoolFeature(&p, "reuse", &val, cps)) {
       /* Engine can disable reuse, but can't enable it if user said no */
       if (!val) cps->reuse = FALSE;
@@ -9143,7 +9233,7 @@ DisplayMove(moveNumber)
     char res[MSG_SIZ];
     char cpThinkOutput[MSG_SIZ];
 
-    if (moveNumber == forwardMostMove - 1 || 
+    if (moveNumber == forwardMostMove - 1 ||
        gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
 
        strcpy(cpThinkOutput, thinkOutput);
@@ -9164,7 +9254,7 @@ DisplayMove(moveNumber)
     } else {
        res[0] = NULLCHAR;
     }
-    
+
     if (moveNumber < 0 || parseList[moveNumber][0] == NULLCHAR) {
        DisplayMessage(res, cpThinkOutput);
     } else {
@@ -9181,7 +9271,8 @@ DisplayAnalysisText(text)
 {
     char buf[MSG_SIZ];
 
-    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) {
+    if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
+               || appData.icsEngineAnalyze) {
        sprintf(buf, "Analysis (%s)", first.tidy);
        AnalysisPopUp(buf, text);
     }
@@ -9206,16 +9297,16 @@ DisplayAnalysis()
     double nps;
     static char *xtra[] = { "", " (--)", " (++)" };
     int h, m, s, cs;
-  
+
     if (programStats.time == 0) {
        programStats.time = 1;
     }
-  
+
     if (programStats.got_only_move) {
        strcpy(buf, programStats.movelist);
     } else {
-       nps = (((double)programStats.nodes) /
-              (((double)programStats.time)/100.0));
+       nps = (u64ToDouble(programStats.nodes) /
+             ((double)programStats.time /100.0));
 
        cs = programStats.time % 100;
        s = programStats.time / 100;
@@ -9226,32 +9317,32 @@ DisplayAnalysis()
 
        if (programStats.moves_left > 0 && appData.periodicUpdates) {
          if (programStats.move_name[0] != NULLCHAR) {
-           sprintf(buf, "depth=%d %d/%d(%s) %+.2f %s%s\nNodes: %lu NPS: %d\nTime: %02d:%02d:%02d.%02d",
+           sprintf(buf, "depth=%d %d/%d(%s) %+.2f %s%s\nNodes: "u64Display" NPS: %d\nTime: %02d:%02d:%02d.%02d",
                    programStats.depth,
                    programStats.nr_moves-programStats.moves_left,
                    programStats.nr_moves, programStats.move_name,
                    ((float)programStats.score)/100.0, programStats.movelist,
                    only_one_move(programStats.movelist)?
                    xtra[programStats.got_fail] : "",
-                   programStats.nodes, (int)nps, h, m, s, cs);
+                   (u64)programStats.nodes, (int)nps, h, m, s, cs);
          } else {
-           sprintf(buf, "depth=%d %d/%d %+.2f %s%s\nNodes: %lu NPS: %d\nTime: %02d:%02d:%02d.%02d",
+           sprintf(buf, "depth=%d %d/%d %+.2f %s%s\nNodes: "u64Display" NPS: %d\nTime: %02d:%02d:%02d.%02d",
                    programStats.depth,
                    programStats.nr_moves-programStats.moves_left,
                    programStats.nr_moves, ((float)programStats.score)/100.0,
                    programStats.movelist,
                    only_one_move(programStats.movelist)?
                    xtra[programStats.got_fail] : "",
-                   programStats.nodes, (int)nps, h, m, s, cs);
+                   (u64)programStats.nodes, (int)nps, h, m, s, cs);
          }
        } else {
-           sprintf(buf, "depth=%d %+.2f %s%s\nNodes: %lu NPS: %d\nTime: %02d:%02d:%02d.%02d",
+           sprintf(buf, "depth=%d %+.2f %s%s\nNodes: "u64Display" NPS: %d\nTime: %02d:%02d:%02d.%02d",
                    programStats.depth,
                    ((float)programStats.score)/100.0,
                    programStats.movelist,
                    only_one_move(programStats.movelist)?
                    xtra[programStats.got_fail] : "",
-                   programStats.nodes, (int)nps, h, m, s, cs);
+                   (u64)programStats.nodes, (int)nps, h, m, s, cs);
        }
     }
     DisplayAnalysisText(buf);
@@ -9323,9 +9414,9 @@ CheckFlags()
                }
            } else {
                if (blackFlag) {
-                   DisplayTitle("Both flags fell");
+                   DisplayTitle(_("Both flags fell"));
                } else {
-                   DisplayTitle("White's flag fell");
+                   DisplayTitle(_("White's flag fell"));
                    if (appData.autoCallFlag) {
                        GameEnds(BlackWins, "Black wins on time", GE_XBOARD);
                        return TRUE;
@@ -9345,9 +9436,9 @@ CheckFlags()
                }
            } else {
                if (whiteFlag) {
-                   DisplayTitle("Both flags fell");
+                   DisplayTitle(_("Both flags fell"));
                } else {
-                   DisplayTitle("Black's flag fell");
+                   DisplayTitle(_("Black's flag fell"));
                    if (appData.autoCallFlag) {
                        GameEnds(WhiteWins, "White wins on time", GE_XBOARD);
                        return TRUE;
@@ -9418,7 +9509,7 @@ GetTimeMark(tm)
     struct timezone timeZone;
 
     gettimeofday(&timeVal, &timeZone);
-    tm->sec = (long) timeVal.tv_sec; 
+    tm->sec = (long) timeVal.tv_sec;
     tm->ms = (int) (timeVal.tv_usec / 1000L);
 
 #else /*!HAVE_GETTIMEOFDAY*/
@@ -9457,7 +9548,7 @@ SubtractTimeMarks(tm2, tm1)
  * We give the human user a slight advantage if he is playing white---the
  * clocks don't run until he makes his first move, so it takes zero time.
  * Also, we don't account for network lag, so we could get out of sync
- * with GNU Chess's clock -- but then, referees are always right.  
+ * with GNU Chess's clock -- but then, referees are always right.
  */
 
 static TimeMark tickStartTM;
@@ -9481,7 +9572,7 @@ NextTickLength(timeRemaining)
 
 /* Stop clocks and reset to a fresh time control */
 void
-ResetClocks() 
+ResetClocks()
 {
     (void) StopClockTimer();
     if (appData.icsActive) {
@@ -9508,7 +9599,7 @@ DecrementClocks()
 
     if (!appData.clockMode) return;
     if (gameMode==AnalyzeMode || gameMode == AnalyzeFile) return;
-       
+
     GetTimeMark(&now);
 
     lastTickLength = SubtractTimeMarks(&now, &tickStartTM);
@@ -9528,7 +9619,7 @@ DecrementClocks()
     }
 
     if (CheckFlags()) return;
-       
+
     tickStartTM = now;
     intendedTickLength = NextTickLength(timeRemaining - fudge) + fudge;
     StartClockTimer(intendedTickLength);
@@ -9536,9 +9627,9 @@ DecrementClocks()
     /* if the time remaining has fallen below the alarm threshold, sound the
      * alarm. if the alarm has sounded and (due to a takeback or time control
      * with increment) the time remaining has increased to a level above the
-     * threshold, reset the alarm so it can sound again. 
+     * threshold, reset the alarm so it can sound again.
      */
-    
+
     if (appData.icsActive && appData.icsAlarm) {
 
        /* make sure we are dealing with the user's clock */
@@ -9548,7 +9639,7 @@ DecrementClocks()
 
        if (alarmSounded && (timeRemaining > appData.icsAlarmTime)) {
            alarmSounded = FALSE;
-       } else if (!alarmSounded && (timeRemaining <= appData.icsAlarmTime)) { 
+       } else if (!alarmSounded && (timeRemaining <= appData.icsAlarmTime)) {
            PlayAlarmSound();
            alarmSounded = TRUE;
        }
@@ -9607,12 +9698,12 @@ SwitchClocks()
       whiteTimeRemaining : blackTimeRemaining);
     StartClockTimer(intendedTickLength);
 }
-       
+
 
 /* Stop both clocks */
 void
 StopClocks()
-{      
+{
     long lastTickLength;
     TimeMark now;
 
@@ -9631,7 +9722,7 @@ StopClocks()
     }
     CheckFlags();
 }
-       
+
 /* Start clock of player on move.  Time may have been reset, so
    if clock is already running, stop and restart it. */
 void
@@ -9657,7 +9748,7 @@ TimeString(ms)
     long second, minute, hour, day;
     char *sign = "";
     static char buf[32];
-    
+
     if (ms > 0 && ms <= 9900) {
       /* convert milliseconds to tenths, rounding up */
       double tenths = floor( ((double)(ms + 99L)) / 100.00 );
@@ -9675,14 +9766,14 @@ TimeString(ms)
        sign = "-";
        second = -second;
     }
-    
+
     day = second / (60 * 60 * 24);
     second = second % (60 * 60 * 24);
     hour = second / (60 * 60);
     second = second % (60 * 60);
     minute = second / 60;
     second = second % 60;
-    
+
     if (day > 0)
       sprintf(buf, " %s%ld:%02ld:%02ld:%02ld ",
              sign, day, hour, minute, second);
@@ -9690,7 +9781,7 @@ TimeString(ms)
       sprintf(buf, " %s%ld:%02ld:%02ld ", sign, hour, minute, second);
     else
       sprintf(buf, " %s%2ld:%02ld ", sign, minute, second);
-    
+
     return buf;
 }
 
@@ -9703,13 +9794,13 @@ StrStr(string, match)
      char *string, *match;
 {
     int i, length;
-    
+
     length = strlen(match);
-    
+
     for (i = strlen(string) - length; i >= 0; i--, string++)
       if (!strncmp(match, string, length))
        return string;
-    
+
     return NULL;
 }
 
@@ -9718,9 +9809,9 @@ StrCaseStr(string, match)
      char *string, *match;
 {
     int i, j, length;
-    
+
     length = strlen(match);
-    
+
     for (i = strlen(string) - length; i >= 0; i--, string++) {
        for (j = 0; j < length; j++) {
            if (ToLower(match[j]) != ToLower(string[j]))
@@ -9738,7 +9829,7 @@ StrCaseCmp(s1, s2)
      char *s1, *s2;
 {
     char c1, c2;
-    
+
     for (;;) {
        c1 = ToLower(*s1++);
        c2 = ToLower(*s2++);
@@ -9854,7 +9945,7 @@ PositionToFEN(move)
     if (boards[move][7][4] == BlackKing) {
        if (boards[move][7][7] == BlackRook) *p++ = 'k';
        if (boards[move][7][0] == BlackRook) *p++ = 'q';
-    }      
+    }
     if (q == p) *p++ = '-';
     *p++ = ' ';
 
@@ -9884,7 +9975,7 @@ PositionToFEN(move)
 
     /* Fullmove number */
     sprintf(p, "%d", (move / 2) + 1);
-    
+
     return StrSave(buf);
 }
 
@@ -9928,7 +10019,7 @@ ParseFEN(board, blackPlaysFirst, fen)
       case 'w':
        *blackPlaysFirst = FALSE;
        break;
-      case 'b': 
+      case 'b':
        *blackPlaysFirst = TRUE;
        break;
       default:
@@ -9937,7 +10028,7 @@ ParseFEN(board, blackPlaysFirst, fen)
     /* !!We ignore the rest of the FEN notation */
     return TRUE;
 }
-      
+
 void
 EditPositionPasteFEN(char *fen)
 {
@@ -9945,7 +10036,7 @@ EditPositionPasteFEN(char *fen)
     Board initial_position;
 
     if (!ParseFEN(initial_position, &blackPlaysFirst, fen)) {
-      DisplayError("Bad FEN position in clipboard", 0);
+      DisplayError(_("Bad FEN position in clipboard"), 0);
       return ;
     } else {
       int savedBlackPlaysFirst = blackPlaysFirst;