<commit_before>/*
 * $Id$
 *
 * Copyright (c) 2007 by <NAME>, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */
package VASSAL.i18n;

import java.awt.Component;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.UIManager;

import VASSAL.Info;
import VASSAL.build.module.gamepieceimage.StringEnumConfigurer;
import VASSAL.preferences.Prefs;

public class Resources {
  /*
   * Translation of VASSAL is handled by standard Java I18N tools.
   * 
   * vassalBundle - Resource Bundle for the VASSAL player interface editorBundle - Resource Bundle for the Module Editor
   * 
   * These are implemented as PropertyResourceBundles, normally to be found in the VASSAL jar file. VASSAL will search
   * first in the VASSAL install directory for bundles, then follow the standard Java Class Path
   */
  protected static BundleHelper vassalBundle;
  protected static BundleHelper editorBundle;
  public static final String LOCALE_PREF_KEY = "Locale"; // Preferences key for the user's Locale
  protected static final Collection<Locale> supportedLocales = Arrays.asList(new Locale[]{Locale.ENGLISH, Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN,
                                                                                          Locale.JAPANESE});
  protected static Locale locale = Locale.getDefault();
  static {
    ArrayList<String> languages = new ArrayList<String>();
    for (Locale l : getSupportedLocales()) {
      languages.add(l.getLanguage());
    }
    String savedLocale = Prefs.getGlobalPrefs().getStoredValue(LOCALE_PREF_KEY);
    Locale preferredLocale = new Locale(savedLocale == null ? Locale.getDefault().getLanguage() : savedLocale);
    if (!Resources.getSupportedLocales().contains(preferredLocale)) {
      preferredLocale = Locale.ENGLISH;
    }
    Resources.setLocale(preferredLocale);
    StringEnumConfigurer localeConfig = new StringEnumConfigurer(Resources.LOCALE_PREF_KEY, getString("Prefs.language"), languages.toArray(new String[languages
        .size()])) {
      public Component getControls() {
        if (box == null) {
          Component c = super.getControls();
          box.setRenderer(new DefaultListCellRenderer() {
            private static final long serialVersionUID = 1L;

            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
              JLabel l = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
              l.setText(new Locale((String) value).getDisplayLanguage());
              return l;
            }
          });
          return c;
        }
        else {
          return super.getControls();
        }
      }
    };
    localeConfig.setValue(Resources.getLocale().getLanguage());
    Prefs.getGlobalPrefs().addOption(getString("Prefs.general_tab"), localeConfig);
  }

  public static Collection<Locale> getSupportedLocales() {
    return supportedLocales;
  }

  public static Collection<String> getVassalKeys() {
    return Collections.list(vassalBundle.getResourceBundle().getKeys());
  }

  public static Collection<String> getEditorKeys() {
    return Collections.list(editorBundle.getResourceBundle().getKeys());
  }
  /*
   * Translation of individual modules is handled differently. There may be multiple Module.properties file active -
   * Potentially one in the module plus one in each Extension loaded. These will be read into UberProperties structures
   * with each file loaded supplying defaults for subsequent files.
   */
  protected static String MODULE_BUNDLE = "Module"; //$NON-NLS-1$
  /*
   * Commonly used i18n keys used in multiple components. By defining them centrally, they will only have to be
   * translated once. Reference to these string should be made as follows:
   * 
   * Resources.getString(Resources.VASSAL)
   */
  public static final String VASSAL = "General.VASSAL"; //$NON-NLS-1$
  public static final String ADD = "General.add"; //$NON-NLS-1$
  public static final String REMOVE = "General.remove"; //$NON-NLS-1$
  public static final String INSERT = "General.insert"; //$NON-NLS-1$
  public static final String YES = "General.yes"; //$NON-NLS-1$
  public static final String NO = "General.no"; //$NON-NLS-1$
  public static final String CANCEL = "General.cancel"; //$NON-NLS-1$
  public static final String SAVE = "General.save"; //$NON-NLS-1$
  public static final String OK = "General.ok"; //$NON-NLS-1$
  public static final String MENU = "General.menu"; //$NON-NLS-1$
  public static final String LOAD = "General.load"; //$NON-NLS-1$
  public static final String QUIT = "General.quit"; //$NON-NLS-1$
  public static final String EDIT = "General.edit"; //$NON-NLS-1$
  public static final String NEW = "General.new"; //$NON-NLS-1$
  public static final String FILE = "General.file"; //$NON-NLS-1$
  public static final String TOOLS = "General.tools"; //$NON-NLS-1$
  public static final String HELP = "General.help"; //$NON-NLS-1$
  public static final String CLOSE = "General.close"; //$NON-NLS-1$
  public static final String DATE_DISPLAY = "General.date_display"; //$NON-NLS-1$
  public static final String NEXT = "General.next"; //$NON-NLS-1$
  public static final String REFRESH = "General.refresh"; //$NON-NLS-1$
  public static final String SELECT = "General.select"; //$NON-NLS-1$
  /*
   * All i18n keys for the Module Editor must commence with "Editor.", This allows us to use a single
   * Resources.getString() call for both resource bundles.
   */
  public static final String EDITOR_PREFIX = "Editor."; //$NON-NLS-1$
  /*
   * Common Editor labels that appear in many components.
   */
  public static final String BUTTON_TEXT = "Editor.button_text_label"; //$NON-NLS-1$
  public static final String TOOLTIP_TEXT = "Editor.tooltip_text_label"; //$NON-NLS-1$
  public static final String BUTTON_ICON = "Editor.button_icon_label"; //$NON-NLS-1$
  public static final String HOTKEY_LABEL = "Editor.hotkey_label"; //$NON-NLS-1$
  public static final String COLOR_LABEL = "Editor.color_label"; //$NON-NLS-1$
  public static final String NAME_LABEL = "Editor.name_label"; //$NON-NLS-1$

  /**
   * Localize a user interface String.
   * 
   * @param id
   *          String Id
   * @return Localized result
   */
  public static String getString(String id) {
    return getBundleForKey(id).getString(id);
  }

  protected static BundleHelper getBundleForKey(String id) {
    return id.startsWith(EDITOR_PREFIX) ? getEditorBundle() : getVassalBundle();
  }

  protected static BundleHelper getEditorBundle() {
    if (editorBundle == null) {
      editorBundle = new BundleHelper(ResourceBundle.getBundle("VASSAL.i18n.Editor", locale, new VassalPropertyClassLoader()));
    }
    return editorBundle;
  }

  protected static BundleHelper getVassalBundle() {
    if (vassalBundle == null) {
      vassalBundle = new BundleHelper(ResourceBundle.getBundle("VASSAL.i18n.VASSAL", locale, new VassalPropertyClassLoader()));
    }
    return vassalBundle;
  }

  /**
   * Localize a VASSAL user interface string
   * 
   * @param id
   *          String id
   * @return Localized result<commit_msg>Bug fix:  Allow user to select unsupported language if they provide a resource bundle<commit_after>/*
 * $Id$
 *
 * Copyright (c) 2007 by <NAME>, <NAME>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */
package VASSAL.i18n;

import java.awt.Component;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.UIManager;

import VASSAL.Info;
import VASSAL.build.module.gamepieceimage.StringEnumConfigurer;
import VASSAL.preferences.Prefs;

public class Resources {
  /*
   * Translation of VASSAL is handled by standard Java I18N tools.
   * 
   * vassalBundle - Resource Bundle for the VASSAL player interface editorBundle - Resource Bundle for the Module Editor
   * 
   * These are implemented as PropertyResourceBundles, normally to be found in the VASSAL jar file. VASSAL will search
   * first in the VASSAL install directory for bundles, then follow the standard Java Class Path
   */
  protected static BundleHelper vassalBundle;
  protected static BundleHelper editorBundle;
  private static VassalPropertyClassLoader bundleLoader = new VassalPropertyClassLoader();
  public static final String LOCALE_PREF_KEY = "Locale"; // Preferences key for the user's Locale
  protected static Collection<Locale> supportedLocales = Arrays.asList(new Locale[]{Locale.ENGLISH, Locale.GERMAN, Locale.FRENCH, Locale.ITALIAN,
                                                                                          Locale.JAPANESE});
  protected static Locale locale = Locale.getDefault();
  static {
    // If the user has a resource bundle for their default language on their local machine, add it to the list of supported locales
    if (ResourceBundle.getBundle("VASSAL.i18n.VASSAL", Locale.getDefault(), bundleLoader).getLocale().getLanguage().equals(Locale.getDefault().getLanguage())) {
      List<Locale> tmp = new ArrayList<Locale>();
      tmp.add(Locale.getDefault());
      tmp.addAll(supportedLocales);
      supportedLocales = tmp;
    }
    ArrayList<String> languages = new ArrayList<String>();
    for (Locale l : getSupportedLocales()) {
      languages.add(l.getLanguage());
    }
    Locale myLocale = Locale.getDefault();
    String savedLocale = Prefs.getGlobalPrefs().getStoredValue(LOCALE_PREF_KEY);
    if (savedLocale == null) {
      myLocale = supportedLocales.iterator().next();
    }
    else {
      myLocale = new Locale(savedLocale);
    }
    Resources.setLocale(myLocale);
    StringEnumConfigurer localeConfig = new StringEnumConfigurer(Resources.LOCALE_PREF_KEY, getString("Prefs.language"), languages.toArray(new String[languages
        .size()])) {
      public Component getControls() {
        if (box == null) {
          Component c = super.getControls();
          box.setRenderer(new DefaultListCellRenderer() {
            private static final long serialVersionUID = 1L;

            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
              JLabel l = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
              l.setText(new Locale((String) value).getDisplayLanguage());
              return l;
            }
          });
          return c;
        }
        else {
          return super.getControls();
        }
      }
    };
    localeConfig.setValue(Resources.getLocale().getLanguage());
    Prefs.getGlobalPrefs().addOption(getString("Prefs.general_tab"), localeConfig);
  }

  public static Collection<Locale> getSupportedLocales() {
    return supportedLocales;
  }

  public static Collection<String> getVassalKeys() {
    return Collections.list(vassalBundle.getResourceBundle().getKeys());
  }

  public static Collection<String> getEditorKeys() {
    return Collections.list(editorBundle.getResourceBundle().getKeys());
  }
  /*
   * Translation of individual modules is handled differently. There may be multiple Module.properties file active -
   * Potentially one in the module plus one in each Extension loaded. These will be read into UberProperties structures
   * with each file loaded supplying defaults for subsequent files.
   */
  protected static String MODULE_BUNDLE = "Module"; //$NON-NLS-1$
  /*
   * Commonly used i18n keys used in multiple components. By defining them centrally, they will only have to be
   * translated once. Reference to these string should be made as follows:
   * 
   * Resources.getString(Resources.VASSAL)
   */
  public static final String VASSAL = "General.VASSAL"; //$NON-NLS-1$
  public static final String ADD = "General.add"; //$NON-NLS-1$
  public static final String REMOVE = "General.remove"; //$NON-NLS-1$
  public static final String INSERT = "General.insert"; //$NON-NLS-1$
  public static final String YES = "General.yes"; //$NON-NLS-1$
  public static final String NO = "General.no"; //$NON-NLS-1$
  public static final String CANCEL = "General.cancel"; //$NON-NLS-1$
  public static final String SAVE = "General.save"; //$NON-NLS-1$
  public static final String OK = "General.ok"; //$NON-NLS-1$
  public static final String MENU = "General.menu"; //$NON-NLS-1$
  public static final String LOAD = "General.load"; //$NON-NLS-1$
  public static final String QUIT = "General.quit"; //$NON-NLS-1$
  public static final String EDIT = "General.edit"; //$NON-NLS-1$
  public static final String NEW = "General.new"; //$NON-NLS-1$
  public static final String FILE = "General.file"; //$NON-NLS-1$
  public static final String TOOLS = "General.tools"; //$NON-NLS-1$
  public static final String HELP = "General.help"; //$NON-NLS-1$
  public static final String CLOSE = "General.close"; //$NON-NLS-1$
  public static final String DATE_DISPLAY = "General.date_display"; //$NON-NLS-1$
  public static final String NEXT = "General.next"; //$NON-NLS-1$
  public static final String REFRESH = "General.refresh"; //$NON-NLS-1$
  public static final String SELECT = "General.select"; //$NON-NLS-1$
  /*
   * All i18n keys for the Module Editor must commence with "Editor.", This allows us to use a single
   * Resources.getString() call for both resource bundles.
   */
  public static final String EDITOR_PREFIX = "Editor."; //$NON-NLS-1$
  /*
   * Common Editor labels that appear in many components.
   */
  public static final String BUTTON_TEXT = "Editor.button_text_label"; //$NON-NLS-1$
  public static final String TOOLTIP_TEXT = "Editor.tooltip_text_label"; //$NON-NLS-1$
  public static final String BUTTON_ICON = "Editor.button_icon_label"; //$NON-NLS-1$
  public static final String HOTKEY_LABEL = "Editor.hotkey_label"; //$NON-NLS-1$
  public static final String COLOR_LABEL = "Editor.color_label"; //$NON-NLS-1$
  public static final String NAME_LABEL = "Editor.name_label"; //$NON-NLS-1$

  /**
   * Localize a user interface String.
   * 
   * @param id
   *          String Id
   * @return Localized result
   */
  public static String getString(String id) {
    return getBundleForKey(id).getString(id);
  }

  protected static BundleHelper getBundleForKey(String id) {
    return id.startsWith(EDITOR_PREFIX) ? getEditorBundle() : getVassalBundle();
  }

  protected static BundleHelper getEditorBundle() {
    if (editorBundle == null) {
      editorBundle = new BundleHelper(ResourceBundle.getBundle("VASSAL.i18n.Editor", locale, bundleLoader));
    }
    return editorBundle;
  }

  protected static BundleHelper getVassalBundle() {
    if (vassalBundle == null) {
      vassalBundle = new BundleHelper(ResourceBundle.getBundle("VASSAL.i18n.VASSAL", locale, bundleLoader));
    }
    return vassalBundle;
  }

  /**
   * Localize a VASSAL user interface string
   * 
   * @param id
   *          String id
   * @return Localized result
{'fraction_non_alphanumeric': 0.10449735449735449, 'fraction_numerical': 0.005772005772005772, 'mean_word_length': 3.4772543741588158, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '902629', 'n_tokens_mistral': 4855, 'n_tokens_neox': 4759, 'n_words': 1487}