// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/language_combobox_model.h"

#include "base/i18n/rtl.h"
#include "base/string_split.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "content/browser/user_metrics.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "unicode/uloc.h"

///////////////////////////////////////////////////////////////////////////////
// LanguageList used to enumerate native names corresponding to the
// language code (e.g. English (United States) for en-US)
//

LanguageList::LanguageList() {
  // Enumerate the languages we know about.
  const std::vector<std::string>& locale_codes =
      l10n_util::GetAvailableLocales();
  InitNativeNames(locale_codes);
}

LanguageList::LanguageList(
    const std::vector<std::string>& locale_codes) {
  InitNativeNames(locale_codes);
}

LanguageList::~LanguageList() {}

void LanguageList::InitNativeNames(
    const std::vector<std::string>& locale_codes) {
  const std::string app_locale = g_browser_process->GetApplicationLocale();
  for (size_t i = 0; i < locale_codes.size(); ++i) {
    std::string locale_code_str = locale_codes[i];
    const char* locale_code = locale_codes[i].c_str();

    // TODO(jungshik): Even though these strings are used for the UI,
    // the old code does not add an RTL mark for RTL locales. Make sure
    // that it's ok without that.
    string16 name_in_current_ui =
        l10n_util::GetDisplayNameForLocale(locale_code, app_locale, false);
    string16 name_native =
        l10n_util::GetDisplayNameForLocale(locale_code, locale_code, false);

    locale_names_.push_back(name_in_current_ui);
    native_names_[name_in_current_ui] =
        LocaleData(name_native, locale_codes[i]);
  }

  // Sort using locale specific sorter.
  l10n_util::SortStrings16(g_browser_process->GetApplicationLocale(),
                           &locale_names_);
}

void LanguageList::CopySpecifiedLanguagesUp(const std::string& locale_codes) {
  DCHECK(!locale_names_.empty());
  std::vector<std::string> locale_codes_vector;
  base::SplitString(locale_codes, ',', &locale_codes_vector);
  for (size_t i = 0; i != locale_codes_vector.size(); i++) {
    const int locale_index = GetIndexFromLocale(locale_codes_vector[i]);
    CHECK_NE(locale_index, -1);
    locale_names_.insert(locale_names_.begin(), locale_names_[locale_index]);
  }
}

// Overridden from ComboboxModel:
int LanguageList::get_languages_count() const {
  return static_cast<int>(locale_names_.size());
}

string16 LanguageList::GetLanguageNameAt(int index) const {
  DCHECK(static_cast<int>(locale_names_.size()) > index);
  LocaleDataMap::const_iterator it =
      native_names_.find(locale_names_[index]);
  DCHECK(it != native_names_.end());

  // If the name is the same in the native language and local language,
  // don't show it twice.
  if (it->second.native_name == locale_names_[index])
    return it->second.native_name;

  // We must add directionality formatting to both the native name and the
  // locale name in order to avoid text rendering problems such as misplaced
  // parentheses or languages appearing in the wrong order.
  string16 locale_name = locale_names_[index];
  base::i18n::AdjustStringForLocaleDirection(&locale_name);

  string16 native_name = it->second.native_name;
  base::i18n::AdjustStringForLocaleDirection(&native_name);

  // We used to have a localizable template here, but none of translators
  // changed the format. We also want to switch the order of locale_name
  // and native_name without going back to translators.
  std::string formatted_item;
  base::SStringPrintf(&formatted_item, "%s - %s",
                      UTF16ToUTF8(locale_name).c_str(),
                      UTF16ToUTF8(native_name).c_str());
  if (base::i18n::IsRTL())
    // Somehow combo box (even with LAYOUTRTL flag) doesn't get this
    // right so we add RTL BDO (U+202E) to set the direction
    // explicitly.
    formatted_item.insert(0, "\xE2\x80\xAE");  // U+202E = UTF-8 0xE280AE
  return UTF8ToUTF16(formatted_item);
}

// Return the locale for the given index.  E.g., may return pt-BR.
std::string LanguageList::GetLocaleFromIndex(int index) const {
  DCHECK(static_cast<int>(locale_names_.size()) > index);
  LocaleDataMap::const_iterator it =
      native_names_.find(locale_names_[index]);
  DCHECK(it != native_names_.end());

  return it->second.locale_code;
}

int LanguageList::GetIndexFromLocale(const std::string& locale) const {
  for (size_t i = 0; i < locale_names_.size(); ++i) {
    LocaleDataMap::const_iterator it =
        native_names_.find(locale_names_[i]);
    DCHECK(it != native_names_.end());
    if (it->second.locale_code == locale)
      return static_cast<int>(i);
  }
  return -1;
}

///////////////////////////////////////////////////////////////////////////////
// LanguageComboboxModel used to populate a combobox with native names
//

LanguageComboboxModel::LanguageComboboxModel()
    : profile_(NULL) {
}

LanguageComboboxModel::LanguageComboboxModel(
    Profile* profile, const std::vector<std::string>& locale_codes)
    : LanguageList(locale_codes),
      profile_(profile) {
}

LanguageComboboxModel::~LanguageComboboxModel() {}

int LanguageComboboxModel::GetItemCount() {
  return get_languages_count();
}

string16 LanguageComboboxModel::GetItemAt(int index) {
  return GetLanguageNameAt(index);
}

// Returns the index of the language currently specified in the user's
// preference file.  Note that it's possible for language A to be picked
// while chrome is currently in language B if the user specified language B
// via --lang.  Since --lang is not a persistent setting, it seems that it
// shouldn't be reflected in this combo box.  We return -1 if the value in
// the pref doesn't map to a know language (possible if the user edited the
// prefs file manually).
int LanguageComboboxModel::GetSelectedLanguageIndex(const std::string& prefs) {
  PrefService* local_state;
  if (!profile_)
    local_state = g_browser_process->local_state();
  else
    local_state = profile_->GetPrefs();

  DCHECK(local_state);
  const std::string& current_locale = local_state->GetString(prefs.c_str());

  return GetIndexFromLocale(current_locale);
}
