package com.battlelancer.seriesguide.ui.dialogs;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatDialogFragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import com.battlelancer.seriesguide.R;
import com.battlelancer.seriesguide.settings.DisplaySettings;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* A dialog displaying a list of languages and regions to choose from, posting a {@link
* LocalizationChangedEvent} if a language or region different from the given ones was chosen.
*/
public class MovieLocalizationDialogFragment extends AppCompatDialogFragment {
private static final String STATE_LIST_VISIBLE = "listVisible";
public static class LocalizationChangedEvent {
}
public static class ItemsLoadedEvent {
public final List<LocalizationAdapter.LocalizationItem> items;
public final int type;
public ItemsLoadedEvent(
List<LocalizationAdapter.LocalizationItem> items, int type) {
this.items = items;
this.type = type;
}
}
public static void show(FragmentManager fragmentManager) {
MovieLocalizationDialogFragment dialog = new MovieLocalizationDialogFragment();
dialog.show(fragmentManager, "dialog-language");
}
private Unbinder unbinder;
@BindView(R.id.buttonPositive) Button buttonOk;
@BindView(R.id.recyclerViewLocalization) RecyclerView recyclerView;
@BindView(R.id.textViewLocalizationLanguage) TextView textViewLanguage;
@BindView(R.id.textViewLocalizationRegion) TextView textViewRegion;
@BindView(R.id.buttonLocalizationLanguage) Button buttonLanguage;
@BindView(R.id.buttonLocalizationRegion) Button buttonRegion;
private LocalizationAdapter adapter;
int type;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.dialog_localization, container, false);
unbinder = ButterKnife.bind(this, view);
buttonOk.setText(android.R.string.ok);
buttonOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
adapter = new LocalizationAdapter(onItemClickListener);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
updateButtonText();
buttonLanguage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setListVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
String[] languageCodes = getContext().getResources()
.getStringArray(R.array.languageCodesMovies);
List<LocalizationAdapter.LocalizationItem> items = new ArrayList<>(
languageCodes.length);
for (String languageCode : languageCodes) {
// example: "en-US"
String languageDisplayName = new Locale(languageCode.substring(0, 2),
languageCode.substring(3)).getDisplayName();
items.add(new LocalizationAdapter.LocalizationItem(languageCode,
languageDisplayName));
}
final Collator collator = Collator.getInstance();
Collections.sort(items,
new Comparator<LocalizationAdapter.LocalizationItem>() {
@Override
public int compare(LocalizationAdapter.LocalizationItem left,
LocalizationAdapter.LocalizationItem right) {
return collator.compare(left.displayText,
right.displayText);
}
});
EventBus.getDefault().postSticky(new ItemsLoadedEvent(items, 0));
}
}).run();
}
});
buttonRegion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setListVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
String[] regionCodes = Locale.getISOCountries();
List<LocalizationAdapter.LocalizationItem> items = new ArrayList<>(
regionCodes.length);
for (String regionCode : regionCodes) {
// example: "en-US"
String displayCountry = new Locale("", regionCode).getDisplayCountry();
items.add(new LocalizationAdapter.LocalizationItem(regionCode,
displayCountry));
}
final Collator collator = Collator.getInstance();
Collections.sort(items,
new Comparator<LocalizationAdapter.LocalizationItem>() {
@Override
public int compare(LocalizationAdapter.LocalizationItem left,
LocalizationAdapter.LocalizationItem right) {
return collator.compare(left.displayText,
right.displayText);
}
});
EventBus.getDefault().postSticky(new ItemsLoadedEvent(items, 1));
}
}).run();
}
});
return view;
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState == null) {
setListVisible(false);
} else {
setListVisible(savedInstanceState.getBoolean(STATE_LIST_VISIBLE, false));
}
ItemsLoadedEvent loadedEvent = EventBus.getDefault().getStickyEvent(ItemsLoadedEvent.class);
if (loadedEvent != null) {
adapter.updateItems(loadedEvent.items);
type = loadedEvent.type;
}
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_LIST_VISIBLE, recyclerView.getVisibility() == View.VISIBLE);
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
EventBus.getDefault().post(new LocalizationChangedEvent());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventItemsLoaded(ItemsLoadedEvent event) {
recyclerView.scrollToPosition(0);
type = event.type;
adapter.updateItems(event.items);
}
private void updateButtonText() {
// example: "en-US"
String languageCode = DisplaySettings.getMoviesLanguage(getContext());
String languageDisplayName = new Locale(languageCode.substring(0, 2),
languageCode.substring(3)).getDisplayName();
buttonLanguage.setText(languageDisplayName);
String regionCode = DisplaySettings.getMoviesRegion(getContext());
buttonRegion.setText(new Locale("", regionCode).getDisplayCountry());
}
public void setListVisible(boolean visible) {
recyclerView.setVisibility(visible ? View.VISIBLE : View.GONE);
int visibility = visible ? View.GONE : View.VISIBLE;
buttonLanguage.setVisibility(visibility);
textViewLanguage.setVisibility(visibility);
buttonRegion.setVisibility(visibility);
textViewRegion.setVisibility(visibility);
}
private LocalizationAdapter.OnItemClickListener onItemClickListener
= new LocalizationAdapter.OnItemClickListener() {
@Override
public void onItemClick(String code) {
setListVisible(false);
if (type == 0) {
PreferenceManager.getDefaultSharedPreferences(getContext()).edit()
.putString(DisplaySettings.KEY_MOVIES_LANGUAGE, code)
.apply();
} else if (type == 1) {
PreferenceManager.getDefaultSharedPreferences(getContext()).edit()
.putString(DisplaySettings.KEY_MOVIES_REGION, code)
.apply();
}
updateButtonText();
}
};
public static class LocalizationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static class LocalizationItem {
public final String code;
public final String displayText;
public LocalizationItem(String code, String displayText) {
this.code = code;
this.displayText = displayText;
}
}
public interface OnItemClickListener {
void onItemClick(String code);
}
@NonNull private final List<LocalizationItem> items;
@NonNull private final OnItemClickListener onItemClickListener;
public LocalizationAdapter(@NonNull OnItemClickListener onItemClickListener) {
this.items = new ArrayList<>();
this.onItemClickListener = onItemClickListener;
}
public void updateItems(@NonNull List<LocalizationItem> items) {
this.items.clear();
this.items.addAll(items);
notifyDataSetChanged();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_dropdown, parent, false);
return new ViewHolder(view, onItemClickListener);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ViewHolder) {
ViewHolder actualHolder = (ViewHolder) holder;
LocalizationItem item = items.get(position);
actualHolder.code = item.code;
actualHolder.title.setText(item.displayText);
}
}
@Override
public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
@BindView(android.R.id.text1) TextView title;
String code;
public ViewHolder(View itemView, final OnItemClickListener onItemClickListener) {
super(itemView);
ButterKnife.bind(this, itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.onItemClick(code);
}
});
}
}
}
}