/*****************************************************************************/
/***     Include files                                                     ***/
/*****************************************************************************/

#include "world.h"                      /* Include data for this application.*/
#include "wrld_msg.h"                   /* Include label defines for the     */
                                        /*  message catalog.                 */

/*****************************************************************************/
/***     Center a window in the middle of the screen.                      ***/
/*****************************************************************************/

void center_the_window(HWND hwnd)
{
  RECTL win_rect;                       /* Bounding rectangle for dialog.    */
  LONG  win_width, win_height;          /* Height and width of message box.  */

                                        /*  Get the bounding rect for the win*/
                                        /*  Calculate width and height.      */
                                        /*  Move the dialog to center of the */
                                        /*   screen.                         */
  WinQueryWindowRect(hwnd, &win_rect);
  win_width = win_rect.xRight - win_rect.xLeft;
  win_height = win_rect.yTop - win_rect.yBottom;
  WinSetWindowPos(hwnd, HWND_TOP, (SHORT) (screen_width - win_width) / 2,
                  (SHORT) (screen_height - win_height) / 2, win_width,
                  win_height, SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
}

/*****************************************************************************/
/***     Initialize routine for program.                                   ***/
/*****************************************************************************/

MRESULT EXPENTRY message_dialog_func(HWND hwnd, ULONG mess, MPARAM parm1,
                                     MPARAM parm2)
{
  switch (mess)
  {
                                        /* When we initialize the dialog...  */
                                        /*  Hide window while updating the   */
                                        /*   text...                         */
                                        /*  Set title of dialog.             */
                                        /*  Set text in text field.          */
                                        /*  Set text in "OK" button.         */
                                        /*  Center dialog on screen.         */
                                        /*  Return OK.                       */
    case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
                     WinSetWindowText(hwnd, error_title);
                     WinSetDlgItemText(hwnd, MESSAGE_TEXT, error_text);
                     WinSetDlgItemText(hwnd, MESSAGE_OK,
                        catgets(msg_handle, MSG, MSG_OK, "OK"));
                     center_the_window(hwnd);
                     return(MRESULT)TRUE;

                                        /* For other messages, use default   */
    default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  }

                                        /* Return OK.                        */
  return((MRESULT) 0);
}

/*****************************************************************************/
/***     Display a cultural message box                                    ***/
/*****************************************************************************/

void error_message(HWND parent_window, char *the_text, char *the_title)
{
                                        /* Set up the title and text.        */
                                        /* Display the message dialog box.   */
  error_title = the_title;
  error_text = the_text;
  WinDlgBox(HWND_DESKTOP, parent_window, message_dialog_func, 0,
            MESSAGE_DIALOG, 0);
}

/*****************************************************************************/
/***     Initialize routine for program.                                   ***/
/*****************************************************************************/

void initialize(void)
{
  int count;                            /* Loop counter.                     */

                                        /* Loop through all the locales...   */
                                        /*  Clear out "active" flag for each */
                                        /*   locale's dialog (not visible).  */
                                        /* To start with, we don't have any  */
                                        /*  of the message locale menu items */
                                        /*  checked.                         */
                                        /* Start off with text in menus.     */
                                        /* Start off with no minimized icon. */
  for (count = 0; count < NUM_LOCALES; count++)
  {
      locale_active[count] = 0;
  }
  cur_mess_locale = NO_LOCALE;
  icons_in_menus = FALSE;
  icon_pointer = (HPOINTER) NULL;
}

/*****************************************************************************/
/***     Set up text for messages menu (called from many places)           ***/
/*****************************************************************************/

void set_messages_menu(void)
{
  static MENUITEM menu_item = {0, MIS_TEXT, 0, 0, 0, 0}; /* A menu struct.   */
  int count;                            /* Loop counter.                     */

                                        /* We want to put the text version   */
                                        /*  in the menu items of the message */
                                        /*  menu.                            */
                                        /* For each one...                   */
                                        /*  Change it to a text menu item.   */
                                        /*  Send a message so it knows that. */
                                        /*  Set the text in the menu item.   */
                                        /* Check the proper locale.          */
  for (count = 0; count < NUM_LOCALES; count++)
  {
    menu_item.id = (ULONG) (MENU_LANGS_LANG0 + count);
    WinSendMsg(hwnd_menu, MM_SETITEM, MPFROM2SHORT(0, TRUE), MPFROMP(&menu_item));
    set_menu_text(MENU_LANGS_LANG0 + count, MEN_LANGS_LANG0 + count,
                  def_locs[count]);
  }
  WinCheckMenuItem(hwnd_menu, MENU_LANGS_LANG0 + cur_mess_locale, TRUE);
}

/*****************************************************************************/
/***     Set up text for menus and main window title from message catalog  ***/
/*****************************************************************************/

int set_text_for_menus(void)
{
  char *ret_string;                     /* Value of the LC_MESSAGES locale   */
                                        /*  variable.                        */
  int count;                            /* Loop variable.                    */
  nl_catd t_handle;                     /* Temp handle for msg catalog.      */

                                        /* If no locale menu item is yet set.*/
                                        /*  Get the LC_MESSAGES var.         */
                                        /*  Loop through the locales...      */
                                        /*   When we find the one that       */
                                        /*    matches LC_MESSAGES...         */
                                        /*    Save the locale number.        */
                                        /*    End the loop now.              */
  if   (cur_mess_locale == NO_LOCALE)
  {
       ret_string = setlocale(LC_MESSAGES, NULL);
       for (count = 0; count < NUM_LOCALES; count++)
       {
         if (strcoll(ret_string, locale_names[count]) == 0)
         {
            cur_mess_locale = count;
            count = NUM_LOCALES;
         }
       }
  }
  else
  {
                                        /* If another locale already active. */
                                        /*  Create the new catalog name.     */
                                        /*  Try to open it.                  */
                                        /*  If we can't open it...           */
                                        /*   Print out an error message (from*/
                                        /*    the old message catalog).      */
                                        /*   Leave the routine.              */
                                        /*  Otherwise...                     */
                                        /*   Close the old message catalog.  */
                                        /*   Use the new one.                */
       sprintf(t_cat_name, CAT_NAME, locale_names[cur_mess_locale]);
       /* NOTE: Uses LANG instead of LC_MESSAGES locale category. This should
        * be changed. */
       t_handle = catopen(t_cat_name, 0);
       if   (t_handle == CATD_ERR)
       {
            error_message(hwndClient,
                          catgets(msg_handle, HELP, HELP_NO_LOC, "Could not open the specified message catalog."),
                          catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
            return(FALSE);
       }
       else
       {
            catclose(msg_handle);
            msg_handle = t_handle;
       }
  }

                                        /* Set the main window title from    */
                                        /*  the message catalog.             */
                                        /* Set the menu items from the       */
                                        /*  message catalog.                 */
                                        /* If not icons (text items instead),*/
                                        /*  Place the text in the messages   */
                                        /*   menu.                           */
  WinSetWindowText(hwndFrame,
                   catgets(msg_handle, MESS_MAIN, MESS_TITLE,
                           "World demo program"));
  set_menu_text(MENU_FILE, MEN_FILE, "~File");
  set_menu_text(MENU_FILE_HELP, MEN_FILE_HELP, "~Help\tF1");
  set_menu_text(MENU_FILE_ABOUT, MEN_FILE_ABOUT, "~About WORLD");
  set_menu_text(MENU_LOCALE, MEN_LOCALE, "~Locale");
  set_menu_text(MENU_LOCALE_SET, MEN_LOCALE_SET, "~Set path");
  set_menu_text(MENU_OPTIONS, MEN_OPTIONS, "~Options");
  set_menu_text(MENU_OPTIONS_ICON, MEN_OPTIONS_ICON, "~Show icons in menus");
  set_menu_text(MENU_LANGS, MEN_LANGS, "~Message");
  if (!icons_in_menus)
  {
     set_messages_menu();
  }

                                        /* For each of the locales...        */
                                        /*  If the dialog for that locale is */
                                        /*   open...                         */
                                        /*   Change the title, buttons and   */
                                        /*    static text for it to the new  */
                                        /*    message catalog's values.      */
  for (count = 0; count < NUM_LOCALES; count++)
  {
      if (locale_active[count])
      {
         WinSendMsg(locale_windows[count], WM_REDRAW_NLS_TEXT, NULL, NULL);
      }
  }

                                        /* Everything was set OK.            */
  return(TRUE);
}

/*****************************************************************************/
/***     Open the message catalog for the program.                         ***/
/*****************************************************************************/

void open_message_catalog(void)
{
                                        /* Set locale for messages.          */
                                        /* Create the message catalog path.  */
                                        /* Open the message catalog.         */
                                        /* If we can't open it...            */
                                        /*  Print out an error.              */
  setlocale(LC_ALL, "");
  sprintf(t_cat_name, CAT_NAME, setlocale(LC_MESSAGES, NULL));
  msg_handle = catopen(t_cat_name, 0);
  if (msg_handle == CATD_ERR)
  {
     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
                   "Could not locale message catalog.  Using default messages.",
                   "Help for WORLD", 0, MB_NOICON | MB_OK );
  }
}

/*****************************************************************************/
/***     Sort collation array based on cultural collation                  ***/
/*****************************************************************************/

                                        /* This routine does a brain-dead    */
                                        /*  simple bubble sort of the array  */
                                        /*  of names, sorting with the       */
                                        /*  culturally-based strcoll.        */
                                        /* NOTE: It assumes that the         */
                                        /*  LC_COLLATE variable is set.      */
void sort_coll_arr(void)
{
  int count1, count2;                   /* Two loop iteration variables.     */
  nam t_str;                            /* String to be used for swapping.   */

                                        /* Iterate through the array.        */
                                        /*  Loop through the items...        */
                                        /*   If we need to swap 2 items,     */
                                        /*    Do the swap.                   */
  for (count1 = (NUM_COLL_STRINGS - 1); count1 > 0; count1--)
  {
      for (count2 = 0; count2 < count1; count2++)
      {
          if (strcoll(coll_arr[count2], coll_arr[count2 + 1]) > 0)
          {
             strcpy(t_str, coll_arr[count2]);
             strcpy(coll_arr[count2], coll_arr[count2 + 1]);
             strcpy(coll_arr[count2 + 1], t_str);
          }
      }
  }
}

/*****************************************************************************/
/***     Load collation array with strings                                 ***/
/*****************************************************************************/

void load_coll_arr(void)
{
  int count = 0;                        /* Index array for insertions.       */

                                        /* Add some strings to the array.    */
  strcpy(coll_arr[count++], "lion");
  strcpy(coll_arr[count++],"crow");
  strcpy(coll_arr[count++],"chimp");
  strcpy(coll_arr[count++],"loon");
  strcpy(coll_arr[count++],"llama");
  strcpy(coll_arr[count++],"camel");
  sprintf(coll_arr[count++], "c%ct%c", o_circumflex, e_accute);
  sprintf(coll_arr[count++], "c%ct%c", 'o', 'e');
  sprintf(coll_arr[count++], "c%ct%c", o_circumflex, 'e');
  sprintf(coll_arr[count++], "c%ct%c", 'o', e_accute);
}

/*****************************************************************************/
/***     Country dialog procedure                                          ***/
/*****************************************************************************/

MRESULT EXPENTRY country_proc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  int count;                            /* General loop counter.             */
  HWND list_box;                        /* Window handle for list box.       */

  char temp_string[255];                /* Temporary string used in formats. */

  double num = 1000.00;                 /* Number converted into money.      */
  time_t ltime;                         /* Time variable for time.           */
  struct tm *ptmT = NULL;               /* Time structure for date/time.     */

  switch(msg)
  {
                                        /* When we get the "init dialog" msg */
    case WM_INITDLG:
         {
                                        /* Save the locale number with the   */
                                        /*  dialog...                        */
                                        /* Mark that the dialog is now open  */
                                        /*  so it won't be displayed more    */
                                        /*  than once...                     */
                                        /* Move the dialog box to a location */
                                        /*  on the screen based on locale.   */
                                        /* Set the title based on locale     */
                                        /*  (look it up in message catalog). */
                                        /* Set up labels.                    */
                                        /* Set the collate and cancel buttons*/
           WinSetWindowUShort(hwnd, 0, which_locale);
           locale_active[which_locale]++;
           WinSetWindowPos(hwnd, HWND_TOP, locale_locs[which_locale].x,
                           locale_locs[which_locale].y, 76, 112,
                           SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);
           WinSetWindowText(hwnd, catgets(msg_handle, MESS_COUNTRY,
                                          COUNTRY_TITLE_BASE + which_locale,
                                          def_cntry[which_locale]));
           WinSetDlgItemText(hwnd, COUNTRY_DATE_LABEL,
                             catgets(msg_handle, MSG, MSG_DATE, "Date:"));
           WinSetDlgItemText(hwnd, COUNTRY_TIME_LABEL,
                             catgets(msg_handle, MSG, MSG_TIME, "Time:"));
           WinSetDlgItemText(hwnd, COUNTRY_MONEY_LABEL,
                             catgets(msg_handle, MSG, MSG_MONEY, "Monetary:"));
           WinSetDlgItemText(hwnd, COUNTRY_COLL_BUTTON,
                             catgets(msg_handle, MSG, MSG_COLLATE, "Collate"));
           WinSetDlgItemText(hwnd, COUNTRY_CANCEL_BUTTON,
                             catgets(msg_handle, MSG, MSG_CANCEL, "Cancel"));

                                        /* Build the locale name.            */
                                        /* Set the locale to that locale.    */
           sprintf(temp_locale_path, "%s\\%s", locale_path,
                   locale_names[which_locale]);
           setlocale(LC_ALL, temp_locale_path);

                                        /* Get window handle of the list box.*/
                                        /* Load some strings into the array. */
                                        /* Loop through the strings in array.*/
                                        /*  Put each one in the list box.    */
           list_box = WinWindowFromID(hwnd, COUNTRY_COLLATE);
           load_coll_arr();
           for (count = 0; count < NUM_COLL_STRINGS; count++)
           {
               WinInsertLboxItem(list_box, LIT_END, (PSZ) coll_arr[count]);
           }

                                        /* Get the time.                     */
                                        /* Convert to local time.            */
                                        /* Format date culturally.           */
                                        /* Place on dialog.                  */
           time(&ltime);
           ptmT = localtime(&ltime);
           strftime(temp_string, sizeof(temp_string), "%x", ptmT);
           WinSetDlgItemText(hwnd, COUNTRY_DATE, temp_string);

                                        /* Format the time culturally.       */
                                        /* Place on dialog.                  */
           strftime(temp_string, sizeof(temp_string), "%X", ptmT);
           WinSetDlgItemText(hwnd, COUNTRY_TIME, temp_string);

                                        /* Format a monetary amount.         */
                                        /* Place on dialog.                  */
           strfmon(temp_string, sizeof(temp_string), "%n", num);
           WinSetDlgItemText(hwnd, COUNTRY_MONEY, temp_string);
         }
         break;
    case WM_COMMAND:
         switch(SHORT1FROMMP(mp1))
         {
                                        /* If they press the collate button. */
           case COUNTRY_COLL_BUTTON:
                                        /* Get the locale number from the    */
                                        /*  dialog.                          */
                                        /* Form the locale name.             */
                                        /* Set the locale.                   */
                which_locale = WinQueryWindowUShort(hwnd, 0);
                sprintf(temp_locale_path, "%s\\%s", locale_path,
                        locale_names[which_locale]);
                setlocale(LC_ALL, temp_locale_path);

                                        /* Delete all the items in the list  */
                                        /*  box.                             */
                                        /* Load the strings into the array   */
                                        /*  (the strings could be sorted from*/
                                        /*   another locale).                */
                                        /* Sort the strings culturally.      */
                                        /* Get window handle for the list box*/
                                        /* Load all the strings into the list*/
                                        /*  box.                             */
                WinSendDlgItemMsg(hwnd, COUNTRY_COLLATE, LM_DELETEALL, 0, 0);
                load_coll_arr();
                sort_coll_arr();
                list_box = WinWindowFromID(hwnd, COUNTRY_COLLATE);
                for (count = 0; count < NUM_COLL_STRINGS; count++)
                {
                    WinInsertLboxItem(list_box, LIT_END, (PSZ) coll_arr[count]);
                }
                break;
                                        /* If they cancel the dialog...      */
           case COUNTRY_CANCEL_BUTTON:
                                        /* Get the locale from the dialog.   */
                                        /* Set the flag so the dialog can    */
                                        /*  be opened again.                 */
                                        /* Close the dialog.                 */
                which_locale = WinQueryWindowUShort(hwnd, 0);
                locale_active[which_locale]--;
                WinPostMsg(hwnd, WM_CLOSE, NULL, NULL);
                break;
           default : break;
         }
         break;
    case WM_ERASEBACKGROUND:
         return((MRESULT) 1);
      case WM_REDRAW_NLS_TEXT:
                                        /* Get the locale number for this dlg*/
                                        /* Redraw title and dialog controls  */
                                        /*  that depend on language.  Assume */
                                        /*  that new message catalog is open.*/
         count = WinQueryWindowUShort(hwnd, 0);
         WinSetWindowText(hwnd, catgets(msg_handle, MESS_COUNTRY,
                          COUNTRY_TITLE_BASE + count, def_cntry[count]));
         WinSetDlgItemText(hwnd, COUNTRY_COLL_BUTTON,
                           catgets(msg_handle, MSG, MSG_COLLATE, "Collate"));
         WinSetDlgItemText(hwnd, COUNTRY_CANCEL_BUTTON,
                           catgets(msg_handle, MSG, MSG_CANCEL, "Cancel"));
         WinSetDlgItemText(hwnd, COUNTRY_DATE_LABEL,
                           catgets(msg_handle, MSG, MSG_DATE, "Date:"));
         WinSetDlgItemText(hwnd, COUNTRY_TIME_LABEL,
                           catgets(msg_handle, MSG, MSG_TIME, "Time:"));
         WinSetDlgItemText(hwnd, COUNTRY_MONEY_LABEL,
                           catgets(msg_handle, MSG, MSG_MONEY, "Monetary:"));
         break;
    default:
         return(WinDefDlgProc(hwnd, msg, mp1, mp2));
  }
  return((MRESULT) 0);
}

/*****************************************************************************/
/***     Display basic help dialog                                         ***/
/*****************************************************************************/

void display_help(void)
{
                                        /* Display the help message.         */
  error_message(hwndClient,
                catgets(msg_handle, HELP, HELP_TEXT,
                "To load a locale for a country, use the mouse to select a city."),
                catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
  return ;
}

/*****************************************************************************/
/***     Procedure to handle the locale path dialog box                    ***/
/*****************************************************************************/

MRESULT EXPENTRY locale_path_dialog_func(HWND hwnd, ULONG mess,
                                         MPARAM parm1, MPARAM parm2)
{
  switch (mess)
  {
                                        /* When we initialize the dialog...  */
                                        /*  Hide window while updating the   */
                                        /*   text...                         */
                                        /*  Set title of dialog.             */
                                        /*  Set the current path in the      */
                                        /*   entry field.                    */
                                        /*  Set text in "OK" button.         */
                                        /*  Center dialog on screen.         */
                                        /*  Return OK.                       */
    case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
                     WinSetWindowText(hwnd,
                        catgets(msg_handle, LPD, LPD_TITLE, "Locale Path"));
                     WinSetDlgItemText(hwnd, LOCALE_PATH_ENTRY, locale_path);
                     WinSetDlgItemText(hwnd, LOCALE_PATH_OK,
                        catgets(msg_handle, MSG, MSG_OK, "OK"));
                     center_the_window(hwnd);
                     return(MRESULT)TRUE;
                                        /* If we get a WM_COMMAND...         */
                                        /*  If it is "OK" button.            */
                                        /*   Get the locale path from entry  */
                                        /*    field.                         */
                                        /*   Dismiss the dialog box.         */
                                        /*   Call on default processing.     */
                                        /*  Otherwise, call on default...    */

    case WM_COMMAND: switch (SHORT1FROMMP(parm1))
                     {
                       case LOCALE_PATH_OK:
                            WinQueryDlgItemText(hwnd, LOCALE_PATH_ENTRY,
                                                sizeof(locale_path),
                                                (PSZ) locale_path);
                            WinDismissDlg(hwnd, FALSE);
                            return WinDefDlgProc(hwnd, mess, parm1, parm2);
                       default:
                            return WinDefDlgProc(hwnd, mess, parm1, parm2);
                     }
                     break;

                                        /* For other messages, use default   */
    default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  }

                                        /* Return OK.                        */
  return((MRESULT) 0);
}

/*****************************************************************************/
/***     Procedure to handle the about path dialog box                     ***/
/*****************************************************************************/

MRESULT EXPENTRY about_dialog_func(HWND hwnd, ULONG mess, MPARAM parm1,
                                   MPARAM parm2)
{
  switch (mess)
  {
                                        /* When we initialize the dialog...  */
                                        /*  Hide window while updating the   */
                                        /*   text...                         */
                                        /*  Set title of dialog.             */
                                        /*  Set text in "OK" button.         */
                                        /*  Set text in other fields.        */
                                        /*  Return OK.                       */
    case WM_INITDLG: WinEnableWindowUpdate(hwnd, FALSE);
                     WinSetWindowText(hwnd,
                        catgets(msg_handle, ABT, ABT_DIALOG, "About WORLD"));
                     WinSetDlgItemText(hwnd, ABOUT_OK,
                        catgets(msg_handle, MSG, MSG_OK, "OK"));
                     WinSetDlgItemText(hwnd, ABOUT_TITLE,
                        catgets(msg_handle, ABT, ABT_TITLE, "World Demo Program"));
                     WinSetDlgItemText(hwnd, ABOUT_PRODUCER,
                        catgets(msg_handle, ABT, ABT_PRODUCER, "Produced by:"));
                     WinSetDlgItemText(hwnd, ABOUT_WRITER,
                        catgets(msg_handle, ABT, ABT_WRITER, "Written by:"));
                     WinSetDlgItemText(hwnd, ABOUT_WHERE,
                        catgets(msg_handle, ABT, ABT_WHERE, "Made in Texas"));
                     WinSetDlgItemText(hwnd, ABOUT_DIRECTOR,
                        catgets(msg_handle, ABT, ABT_DIRECTOR, "Directed by:"));
                     center_the_window(hwnd);
                     return(MRESULT)TRUE;

                                        /* For other messages, use default   */
    default:         return WinDefDlgProc(hwnd, mess, parm1, parm2);
  }

                                        /* Return OK.                        */
  return((MRESULT) 0);
}

/*****************************************************************************/
/***     Set locale-based icon                                             ***/
/*****************************************************************************/

void set_locale_based_icon(void)
{
  char *ret_string;                     /* Return value of LC_MESSAGES.      */

                                        /* This routine loads an icon from   */
                                        /*  a directory based on the current */
                                        /*  locale.  It then uses that icon  */
                                        /*  for the minimized icon.  Instead */
                                        /*  the scheme used, one could parse */
                                        /*  the NLSPATH environment variable,*/
                                        /*  and check each directory for the */
                                        /*  named icon.                      */

                                        /* If existing icon, delete it.      */
                                        /* Read the icon from proper locale  */
                                        /*  directory.                       */
                                        /* Get locale for program's icon.    */
                                        /* Form icon path name (from the     */
                                        /*  current locale (or LC_MESSAGES   */
                                        /*  if none assigned).               */
                                        /* Load the icon from the file.      */
                                        /* Set up as program's icon.         */
  if (icon_pointer != (HPOINTER) NULL)
  {
     WinDestroyPointer(icon_pointer);
  }
  if   (cur_mess_locale != NO_LOCALE)
  {
       sprintf(t_icon_name, ICON_NAME, locale_names[cur_mess_locale]);
  }
  else
  {
       ret_string = setlocale(LC_MESSAGES, NULL);
       sprintf(t_icon_name, ICON_NAME, ret_string);
  }
  icon_pointer = WinLoadFileIcon(t_icon_name, FALSE);
  WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) icon_pointer, NULL);
}

/*****************************************************************************/
/***     Try to open a locale dialog                                       ***/
/*****************************************************************************/

void try_to_open(int the_locale, HWND parent_window)
{
                                        /* If the locale isn't already open. */
  if (!locale_active[the_locale])
  {
                                        /* Set the locale in a global.       */
                                        /* Form the locale name string.      */
    which_locale = the_locale;
    sprintf(temp_locale_path, "%s\\%s.DLL", locale_path,
            locale_names[which_locale]);

                                        /* If the locale file (.dll) isn't   */
                                        /*  found...                         */
                                        /*  Print a warning.                 */
                                        /* Else, open the dialog for the     */
                                        /*  locale.                          */
    if   (stat(temp_locale_path, &stat_buffer) == FILE_NOT_FOUND)
    {
         error_message(hwndClient,
                   catgets(msg_handle, LOCALE, LOCALE_TEXT,
         "The locale path specified is invalid.  Please use the Locale Menu to enter the correct path."),
                   catgets(msg_handle, LOCALE, LOCALE_TITLE, "Help for WORLD"));
    }
    else
    {
         locale_windows[which_locale] = WinLoadDlg(hwndClient, parent_window,
                                                   country_proc, 0L,
                                                   COUNTRY_DIALOG, NULL);
    }
  }
}

/*****************************************************************************/
/***     Window procedure for client child of main window                  ***/
/*****************************************************************************/

MRESULT EXPENTRY ClientWndProc(HWND hwndWnd, ULONG ulMsg, MPARAM mpParm1,
                               MPARAM mpParm2)
{
  int t_menu;                           /* Used to remember which locale menu*/
                                        /*  item is selected.                */
  int old_locale;                       /* Old value of "current locale"     */
  int count;                            /* Loop counter.                     */
  static MENUITEM menu_item = {0, MIS_BITMAP, 0, 0, 0, 0};
                                        /* Menu item structure for icons.    */

  switch (ulMsg)
  {
    case WM_CREATE:
         {
           HPS hpsWnd;                  /* Handle to presentation space.     */

                                        /* Get presentation space.           */
                                        /* Load bitmap into it.              */
                                        /*   Read in bitmap for that locale  */
                                        /*    (the flag). For menus.         */
                                        /* Release the presentation space.   */
           hpsWnd = WinGetPS(hwndWnd);
           GpiLoadBitmap(hpsWnd, NULLHANDLE, BITMAP_WORLD, 500, 350);
           for (count = 0; count < NUM_LOCALES; count++)
           {
             locale_bitmaps[count] = GpiLoadBitmap(hpsWnd, NULLHANDLE,
                                                   BITMAP_LANG0 + count,
                                                   32, 32);
           }
           WinReleasePS(hpsWnd);
         }
         break;
    case WM_ERASEBACKGROUND:
         return MRFROMSHORT(TRUE);
    case WM_PAINT:
         {
           HPS          hpsWnd;         /* Presentation space handle.        */
           HBITMAP      hbmBitmap;      /* Bitmap handle.                    */
           POINTL       ptl;            /* A point used in painting.         */

                                        /* Bitmap drawn from the corner.     */
           ptl.x = 0;
           ptl.y = 0;

                                        /* Start painting.                   */
                                        /* Clear the presentation space.     */
           hpsWnd = WinBeginPaint(hwndWnd, 0L, 0L);
           GpiErase(hpsWnd);

                                        /* Load in the bitmap.               */
                                        /* Draw it on the presentation space.*/
                                        /* Release the memory for the bitmap.*/
                                        /* End painting.                     */
           hbmBitmap = GpiLoadBitmap(hpsWnd, NULLHANDLE, BITMAP_WORLD,
                                     557, 353);
           WinDrawBitmap(hpsWnd, hbmBitmap, NULL, &ptl, CLR_NEUTRAL,
                         CLR_BACKGROUND, DBM_NORMAL);
           GpiDeleteBitmap(hbmBitmap);
           WinEndPaint(hpsWnd);
         }
         break;
                                        /* If the user clicks or double      */
                                        /*  clicks...                        */
    case WM_BUTTON1DOWN:
    case WM_BUTTON1DBLCLK:
         {
           int sel_a_city = FALSE;      /* Was a city selected?              */
           SHORT x, y;                  /* Mouse location.                   */

                                        /* Get the location of the click.    */
           x = MOUSEMSG(&ulMsg)->x;
           y = MOUSEMSG(&ulMsg)->y;

                                        /* Go through all the locales...     */
                                        /*  If the click is in the rectangle */
                                        /*   defined for this locale...      */
                                        /*   Try to open the dialog.         */
                                        /*   Mark that we did click on a city*/
                                        /*   Terminate the loop.             */
           for (count = 0; count < NUM_LOCALES; count++)
           {
               if (((x > locale_hit_locs[count].xLeft) &&
                    (x < locale_hit_locs[count].xRight)) &&
                   ((y > locale_hit_locs[count].yBottom) &&
                    (y < locale_hit_locs[count].yTop)))
               {
                  try_to_open(count, hwndWnd);
                  sel_a_city = TRUE;
                  count = NUM_LOCALES;
               }
           }

                                        /* If no city selected...            */
                                        /*  Put up a message.                */
           if (!sel_a_city)
           {
              error_message(hwndWnd,
                        catgets(msg_handle, HELP, SEL_TEXT, "Please select a city."),
                        catgets(msg_handle, HELP, HELP_TITLE, "Help for WORLD"));
           }
         }
         break;
                                        /* If a menu item selected...        */
                                        /* Put up proper dialog for the item.*/
    case WM_COMMAND:
         switch (SHORT1FROMMP(mpParm1))
         {
           case MENU_LOCALE_SET:
                            WinDlgBox(HWND_DESKTOP, hwndWnd,
                                      locale_path_dialog_func, 0,
                                      LOCALE_PATH_DIALOG, 0);
                            break;
           case MENU_FILE_HELP:
                            display_help();
                            break;
           case MENU_FILE_ABOUT:
                            WinDlgBox(HWND_DESKTOP, hwndWnd, about_dialog_func,
                                      0, ABOUT_DIALOG, 0);
                            break;
           case MENU_OPTIONS_ICON:
                                        /* Toggling the icon in menus option.*/
                                        /*  Toggle the flag.                 */
                                        /*  Check/uncheck item as needed.    */
                            icons_in_menus = !icons_in_menus;
                            WinCheckMenuItem(hwnd_menu, MENU_OPTIONS_ICON,
                                             icons_in_menus);

                                        /* If drawing icons now...           */
                                        /*  Loop through all locales.        */
                                        /*   Set bitmap for each menu item.  */
                                        /*   Set id of each menu item.       */
                                        /*   Send change to the menu.        */
                            if   (icons_in_menus)
                            {
                                 for (count = 0; count < NUM_LOCALES; count++)
                                 {
                                   menu_item.hItem = (ULONG)
                                                     locale_bitmaps[count];
                                   menu_item.id = (ULONG) (MENU_LANGS_LANG0 +
                                                           count);
                                   WinSendMsg(hwnd_menu, MM_SETITEM,
                                              MPFROM2SHORT(0, TRUE),
                                              MPFROMP(&menu_item));
                                 }
                            }
                            else
                            {
                                        /* If setting text in menu, do it.   */
                                 set_messages_menu();
                            }
                                        /* Check proper item in menu.        */
                            WinCheckMenuItem(hwnd_menu, MENU_LANGS_LANG0 +
                                             cur_mess_locale, TRUE);
                            break;
           case MENU_LANGS_LANG0:
           case MENU_LANGS_LANG1:
           case MENU_LANGS_LANG2:
           case MENU_LANGS_LANG3:
           case MENU_LANGS_LANG4:
           case MENU_LANGS_LANG5:
           case MENU_LANGS_LANG6:
           case MENU_LANGS_LANG7:
           case MENU_LANGS_LANG8:
           case MENU_LANGS_LANG9:
           case MENU_LANGS_LANG10:
           case MENU_LANGS_LANG11:
                                        /* If they select a new message lang.*/
                                        /*  Get the menu item number.        */
                                        /*  If they selected a new language  */
                                        /*   Save the old locale number.     */
                                        /*   Set up the new locale number.   */
                                        /*   If changing the message catalog */
                                        /*    and setting the menu texts went*/
                                        /*    OK...                          */
                                        /*    Uncheck the old locale item.   */
                                        /*    Check the new locale menu item.*/
                                        /*    Change the main program icon to*/
                                        /*     one appropriate for the new   */
                                        /*     locale.                       */
                                        /*   Otherwise...                    */
                                        /*    Restore the original locale num*/
                            t_menu = SHORT1FROMMP(mpParm1);
                            if ((t_menu - MENU_LANGS_LANG0) != cur_mess_locale)
                            {
                               old_locale = cur_mess_locale;
                               cur_mess_locale = t_menu - MENU_LANGS_LANG0;
                               if   (set_text_for_menus())
                               {
                                    WinCheckMenuItem(hwnd_menu,
                                                     MENU_LANGS_LANG0 +
                                                     old_locale, FALSE);
                                    WinCheckMenuItem(hwnd_menu, t_menu, TRUE);
                                    set_locale_based_icon();
                               }
                               else
                               {
                                    cur_mess_locale = old_locale;
                               }
                            }
                            break;
           default:
                            return WinDefWindowProc(hwndWnd, ulMsg, mpParm1,
                                                    mpParm2);
         }
         break;
    default: return WinDefWindowProc(hwndWnd, ulMsg, mpParm1, mpParm2);
  }
  return MRFROMSHORT(FALSE);
}

/*****************************************************************************/
/***     Clean up at end of program                                        ***/
/*****************************************************************************/

void clean_up(void)
{
  int count;                            /* Loop counter.                     */

                                        /* Get rid of the minimized icon.    */
                                        /* Get rid of all locale bitmaps.    */
  WinDestroyPointer(icon_pointer);
  for (count = 0; count < NUM_LOCALES; count++)
  {
      GpiDeleteBitmap(locale_bitmaps[count]);
  }

}

/*****************************************************************************/
/***     Main program                                                      ***/
/*****************************************************************************/

INT main(void)
{
  HAB            habAnchor;             /* Anchor block for program.         */
  HMQ            hmqQueue;              /* Message queue for program.        */
  QMSG           qmMsg;                 /* A message to pull from queue.     */
  ULONG          ulFlags;               /* Creation flags for window frame.  */

                                        /* Initialize values for the program.*/
  initialize();

                                        /* Get the anchor block for program. */
                                        /* Create message queue for program. */
  habAnchor = WinInitialize(0);
  hmqQueue = WinCreateMsgQueue(habAnchor, 0);

                                        /* Open the message catalog          */
  open_message_catalog();

                                        /* Register main window class        */
                                        /* Define flags for frame window for */
                                        /*  main window.  Standard window    */
                                        /*  except: no maximize box, and we  */
                                        /*  will position the window.        */
                                        /* Create the main window.           */
                                        /*  NOTE: The title for the window   */
                                        /*  is gotten from the message       */
                                        /*  catalog.                         */
  WinRegisterClass(habAnchor, CLS_CLIENT, ClientWndProc, CS_SIZEREDRAW, 0);
  ulFlags = FCF_STANDARD & ~FCF_MAXBUTTON & ~FCF_SHELLPOSITION &
            ~FCF_ICON;
  hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &ulFlags, CLS_CLIENT, "",
                                 0, NULLHANDLE, RES_CLIENT, &hwndClient);
  set_locale_based_icon();

                                        /* Get a handle to the menu window   */
                                        /*  (will need this later to change  */
                                        /*   the text of the menu items).    */
                                        /* Set the language for the menus    */
                                        /*  (and title) based on the locale  */
                                        /*  settings.                        */
  hwnd_menu = WinWindowFromID(hwndFrame, FID_MENU);
  set_text_for_menus();

                                        /* If window created OK...           */
                                        /*  Get the width and height of the  */
                                        /*   screen, so we can center.       */
                                        /*  Center the window in the screen. */
  if (hwndFrame != NULLHANDLE)
  {
     screen_width = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
     screen_height = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
     WinSetWindowPos(hwndFrame, NULLHANDLE,
                     (SHORT) (screen_width - WIN_WIDTH) / 2,
                     (SHORT) (screen_height - WIN_HEIGHT) / 2,
                     WIN_WIDTH, WIN_HEIGHT,
                     SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW);

                                        /*  Main message loop:               */
                                        /*  While there are more messages... */
                                        /*   Dispatch this message.          */
     while (WinGetMsg(habAnchor, &qmMsg, NULLHANDLE, 0, 0))
     {
       WinDispatchMsg(habAnchor, &qmMsg);
     }

                                        /*  We're done.  Get rid of the main */
                                        /*   window.                         */
     WinDestroyWindow(hwndFrame);
  }

                                        /* Close the active message catalog. */
  catclose(msg_handle);

                                        /* Get rid of the message queue.     */
                                        /* Get rid of the anchor block.      */
                                        /* Clean up anything that needs it.  */
                                        /* Terminate the program.            */
  WinDestroyMsgQueue(hmqQueue);
  WinTerminate(habAnchor);
  clean_up();
  return(EXIT_NORMAL);
}
