package org.wikipedia.language;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import org.wikipedia.R;
import org.wikipedia.WikipediaApp;
import org.wikipedia.activity.ThemedActionBarActivity;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.dataclient.mwapi.MwQueryResponse;
import org.wikipedia.history.HistoryEntry;
import org.wikipedia.page.PageActivity;
import org.wikipedia.page.PageTitle;
import org.wikipedia.views.ViewAnimations;
import org.wikipedia.views.WikiErrorView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import retrofit2.Call;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.wikipedia.util.DeviceUtil.hideSoftKeyboard;
public class LangLinksActivity extends ThemedActionBarActivity {
public static final int ACTIVITY_RESULT_LANGLINK_SELECT = 1;
public static final String ACTION_LANGLINKS_FOR_TITLE = "org.wikipedia.langlinks_for_title";
public static final String EXTRA_PAGETITLE = "org.wikipedia.pagetitle";
private static final String LANGUAGE_ENTRIES_BUNDLE_KEY = "languageEntries";
private static final String GOTHIC_LANGUAGE_CODE = "got";
private List<PageTitle> languageEntries;
private PageTitle title;
private WikipediaApp app;
private LangLinksClient client;
private ClientCallback callback;
private ListView langLinksList;
private View langLinksProgress;
private View langLinksContainer;
private View langLinksEmpty;
private View langLinksNoMatch;
private WikiErrorView langLinksError;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = WikipediaApp.getInstance();
setContentView(R.layout.activity_langlinks);
if (!getIntent().getAction().equals(ACTION_LANGLINKS_FOR_TITLE)) {
throw new RuntimeException("Only ACTION_LANGLINKS_FOR_TITLE is supported");
}
langLinksList = (ListView) findViewById(R.id.langlinks_list);
langLinksProgress = findViewById(R.id.langlinks_load_progress);
langLinksContainer = findViewById(R.id.langlinks_list_container);
langLinksEmpty = findViewById(R.id.langlinks_empty);
langLinksNoMatch = findViewById(R.id.langlinks_no_match);
langLinksError = (WikiErrorView) findViewById(R.id.langlinks_error);
EditText langLinksFilter = (EditText) findViewById(R.id.langlinks_filter);
title = getIntent().getParcelableExtra(EXTRA_PAGETITLE);
if (savedInstanceState != null && savedInstanceState.containsKey(LANGUAGE_ENTRIES_BUNDLE_KEY)) {
languageEntries = savedInstanceState.getParcelableArrayList(LANGUAGE_ENTRIES_BUNDLE_KEY);
}
client = new LangLinksClient();
fetchLangLinks();
langLinksError.setRetryClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewAnimations.crossFade(langLinksError, langLinksProgress);
fetchLangLinks();
}
});
langLinksList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PageTitle langLink = (PageTitle) parent.getAdapter().getItem(position);
app.setMruLanguageCode(langLink.getWikiSite().languageCode());
HistoryEntry historyEntry = new HistoryEntry(langLink, HistoryEntry.SOURCE_LANGUAGE_LINK);
Intent intent = PageActivity.newIntent(LangLinksActivity.this, historyEntry, langLink);
setResult(ACTIVITY_RESULT_LANGLINK_SELECT, intent);
hideSoftKeyboard(LangLinksActivity.this);
finish();
}
});
langLinksFilter.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// the languages might not be loaded yet...
if (langLinksList.getAdapter() == null) {
return;
}
((LangLinksAdapter) langLinksList.getAdapter()).setFilterText(s.toString());
//Check if there are no languages that match the filter
if (langLinksList.getAdapter().getCount() == 0) {
langLinksNoMatch.setVisibility(View.VISIBLE);
} else {
langLinksNoMatch.setVisibility(View.GONE);
}
}
});
}
@Override
public void onBackPressed() {
hideSoftKeyboard(this);
super.onBackPressed();
}
@Override
protected void setTheme() {
setActionBarTheme();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (languageEntries != null) {
outState.putParcelableArrayList(LANGUAGE_ENTRIES_BUNDLE_KEY, new ArrayList<Parcelable>(languageEntries));
}
}
private void displayLangLinks() {
if (languageEntries.size() == 0) {
ViewAnimations.crossFade(langLinksProgress, langLinksEmpty);
} else {
langLinksList.setAdapter(new LangLinksAdapter(languageEntries, app));
ViewAnimations.crossFade(langLinksProgress, langLinksContainer);
}
}
private void fetchLangLinks() {
if (languageEntries == null) {
client.request(title.getWikiSite(), title, new ClientCallback());
} else {
displayLangLinks();
}
}
private class ClientCallback implements LangLinksClient.Callback {
@Override public void success(@NonNull Call<MwQueryResponse<LangLinks>> call, @NonNull List<PageTitle> links) {
languageEntries = links;
updateLanguageEntriesSupported(languageEntries);
sortLanguageEntriesByMru(languageEntries);
displayLangLinks();
}
@Override public void failure(@NonNull Call<MwQueryResponse<LangLinks>> call, @NonNull Throwable caught) {
ViewAnimations.crossFade(langLinksProgress, langLinksError);
langLinksError.setError(caught);
}
private void updateLanguageEntriesSupported(List<PageTitle> languageEntries) {
for (ListIterator<PageTitle> it = languageEntries.listIterator(); it.hasNext();) {
PageTitle link = it.next();
String languageCode = link.getWikiSite().languageCode();
if (GOTHIC_LANGUAGE_CODE.equals(languageCode)) {
// Remove Gothic since it causes Android to segfault.
it.remove();
} else if (Locale.CHINESE.getLanguage().equals(languageCode)) {
// Replace Chinese with Simplified and Traditional dialects.
it.remove();
for (String dialect : Arrays.asList(AppLanguageLookUpTable.SIMPLIFIED_CHINESE_LANGUAGE_CODE,
AppLanguageLookUpTable.TRADITIONAL_CHINESE_LANGUAGE_CODE)) {
it.add(new PageTitle(link.getText(), WikiSite.forLanguageCode(dialect)));
}
}
}
}
private void sortLanguageEntriesByMru(List<PageTitle> entries) {
int addIndex = 0;
for (String language : WikipediaApp.getInstance().getMruLanguageCodes()) {
for (int i = 0; i < entries.size(); i++) {
if (entries.get(i).getWikiSite().languageCode().equals(language)) {
PageTitle entry = entries.remove(i);
entries.add(addIndex++, entry);
break;
}
}
}
}
}
private static final class LangLinksAdapter extends BaseAdapter {
private final List<PageTitle> originalLanguageEntries;
private final List<PageTitle> languageEntries;
private final WikipediaApp app;
private LangLinksAdapter(List<PageTitle> languageEntries, WikipediaApp app) {
this.originalLanguageEntries = languageEntries;
this.languageEntries = new ArrayList<>(originalLanguageEntries);
this.app = app;
}
public void setFilterText(String filter) {
languageEntries.clear();
filter = filter.toLowerCase();
for (PageTitle entry : originalLanguageEntries) {
String languageCode = entry.getWikiSite().languageCode();
String canonicalName = defaultString(app.getAppLanguageCanonicalName(languageCode));
String localizedName = defaultString(app.getAppLanguageLocalizedName(languageCode));
if (canonicalName.toLowerCase().contains(filter)
|| localizedName.toLowerCase().contains(filter)) {
languageEntries.add(entry);
}
}
notifyDataSetInvalidated();
}
@Override
public int getCount() {
return languageEntries.size();
}
@Override
public PageTitle getItem(int position) {
return languageEntries.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_language_list_entry, parent, false);
}
PageTitle item = getItem(position);
String languageCode = item.getWikiSite().languageCode();
String localizedLanguageName = app.getAppLanguageLocalizedName(languageCode);
TextView localizedLanguageNameTextView = (TextView) convertView.findViewById(R.id.localized_language_name);
TextView articleTitleTextView = (TextView) convertView.findViewById(R.id.language_subtitle);
localizedLanguageNameTextView.setText(localizedLanguageName);
articleTitleTextView.setText(item.getDisplayText());
return convertView;
}
}
}