package com.door43.translationstudio.newui.library;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.design.widget.TabLayout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.door43.translationstudio.R;
import com.door43.translationstudio.core.Library;
import com.door43.translationstudio.core.Project;
import com.door43.translationstudio.core.SourceLanguage;
import com.door43.translationstudio.core.SourceTranslation;
import com.door43.translationstudio.core.TargetTranslation;
import com.door43.translationstudio.core.Typography;
import com.door43.translationstudio.dialogs.CustomAlertDialog;
import com.door43.translationstudio.newui.BaseFragment;
import com.door43.translationstudio.tasks.DownloadProjectImageTask;
import com.door43.translationstudio.tasks.DownloadSourceLanguageTask;
import com.door43.translationstudio.AppContext;
import com.door43.util.tasks.ManagedTask;
import com.door43.util.tasks.TaskManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class ServerLibraryDetailFragment extends BaseFragment implements ManagedTask.OnFinishedListener {
public static final String ARG_PROJECT_ID = "item_id";
private static final String TAB_SOURCE_LANGUAGES = "tab_source_languages";
private static final String TAB_DRAFT_LANGUAGES = "tab_draft_languages";
private static final String STATE_SELECTED_TAB = "state_selected_tab";
public static final String DOWNLOAD_SOURCE_LANGUAGE_TASK_GROUP = "download_source_language_task";
private Project mProject;
private String mImagePath;
private Library mServerLibrary;
private ViewHolder mHolder;
private String mSelectedTab = TAB_SOURCE_LANGUAGES;
private OnEventListener mListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mServerLibrary = AppContext.getLibrary();
if (getArguments().containsKey(ARG_PROJECT_ID)) {
String projectId = getArguments().getString(ARG_PROJECT_ID);
mProject = mServerLibrary.getProject(projectId, Locale.getDefault().getLanguage());
// TODO: handle null project
}
if(savedInstanceState != null) {
mSelectedTab = savedInstanceState.getString(STATE_SELECTED_TAB, TAB_SOURCE_LANGUAGES);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_server_library_detail, container, false);
mHolder = new ViewHolder(rootView);
rebuildLayout();
return rootView;
}
public void rebuildLayout() {
// disconnect tasks listeners
List<ManagedTask> tasks = TaskManager.getGroupedTasks(ServerLibraryDetailFragment.DOWNLOAD_SOURCE_LANGUAGE_TASK_GROUP);
for(ManagedTask task:tasks) {
task.removeAllOnFinishedListener();
task.removeAllOnProgressListener();
}
if(mHolder != null) {
// project info
mHolder.mDateModified.setText("v. " + mProject.dateModified);
mHolder.mProjectTitle.setText(mProject.name);
mHolder.mProjectDescription.setText(mProject.description);
mHolder.mIcon.setBackgroundResource(R.drawable.ic_library_books_black_24dp);
// delete project
if (AppContext.getLibrary().projectHasSource(mProject.getId())) {
mHolder.mDeleteButton.setVisibility(View.VISIBLE);
mHolder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// TRICKY: we can't let users delete projects that have target Translations
TargetTranslation[] targetTranslations = AppContext.getTranslator().getTargetTranslations();
boolean projectHasTargetTranslations = false;
for(TargetTranslation targetTranslation:targetTranslations){
if(targetTranslation.getProjectId().equals(mProject.getId())) {
projectHasTargetTranslations = true;
break;
}
}
if(projectHasTargetTranslations) {
CustomAlertDialog.Create(getActivity())
.setTitle(R.string.label_delete)
.setIcon(R.drawable.ic_info_black_24dp)
.setMessage(R.string.cannot_delete_project_with_translations)
.setPositiveButton(R.string.dismiss, null)
.show("DelWarn");
} else {
CustomAlertDialog.Create(getActivity())
.setTitle(R.string.label_delete)
.setIcon(R.drawable.ic_delete_black_24dp)
.setMessage(R.string.confirm_delete_project)
.setPositiveButton(R.string.confirm, new View.OnClickListener() {
@Override
public void onClick(View v) {
AppContext.getLibrary().deleteProject(mProject.getId());
mListener.onProjectDeleted(mProject.getId());
}
})
.setNegativeButton(R.string.no, null)
.show("DelConfirm");
}
}
});
} else {
mHolder.mDeleteButton.setVisibility(View.GONE);
}
// fonts
SourceLanguage fontSourceLanguage = mServerLibrary.getSourceLanguage(mProject.getId(), mProject.sourceLanguageId);
Typography.formatSub(getActivity(), mHolder.mProjectDescription, fontSourceLanguage.getId(), fontSourceLanguage.getDirection());
Typography.formatTitle(getActivity(), mHolder.mProjectTitle, fontSourceLanguage.getId(), fontSourceLanguage.getDirection());
// custom project icon
if (mImagePath == null) {
// TODO: hook this up
// if (TaskManager.getTask(mTaskId) != null) {
// // connect to existing task
// DownloadProjectImageTask task = (DownloadProjectImageTask) TaskManager.getTask(IMAGE_TASK_PREFIX+mProject.getId());
// task.addOnFinishedListener(this);
// } else {
// // begin downloading the image
// DownloadProjectImageTask task = new DownloadProjectImageTask(mProject);
// task.addOnFinishedListener(this);
// TaskManager.addTask(task, IMAGE_TASK_PREFIX+mProject.getId());
// }
} else {
loadImage();
}
// tabs
final List<SourceLanguage> sourceLanguages = getSourceLanguages();
final List<SourceLanguage> draftLanguages = getDraftLanguages();
mHolder.mTabLayout.removeAllTabs();
if(sourceLanguages.size() > 0) {
TabLayout.Tab tab = mHolder.mTabLayout.newTab();
tab.setText(R.string.languages);
tab.setTag(TAB_SOURCE_LANGUAGES);
mHolder.mTabLayout.addTab(tab);
}
if(draftLanguages.size() > 0) {
TabLayout.Tab tab = mHolder.mTabLayout.newTab();
tab.setText(R.string.drafts);
tab.setTag(TAB_DRAFT_LANGUAGES);
mHolder.mTabLayout.addTab(tab);
}
// select correct tab
for(int i = 0; i < mHolder.mTabLayout.getTabCount(); i ++) {
TabLayout.Tab tab = mHolder.mTabLayout.getTabAt(i);
if(tab.getTag().equals(mSelectedTab)) {
tab.select();
break;
}
}
// tab listener
mHolder.mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
mSelectedTab = (String) tab.getTag();
if(mSelectedTab.equals(TAB_DRAFT_LANGUAGES)) {
mHolder.mAdapter.changeDataSet(mProject.getId(), mServerLibrary.getAvailableUpdates(), draftLanguages);
} else {
mHolder.mAdapter.changeDataSet(mProject.getId(), mServerLibrary.getAvailableUpdates(), sourceLanguages);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
// load languages
if(mSelectedTab.equals(TAB_DRAFT_LANGUAGES)) {
mHolder.mAdapter.changeDataSet(mProject.getId(), mServerLibrary.getAvailableUpdates(), draftLanguages);
} else {
mHolder.mAdapter.changeDataSet(mProject.getId(), mServerLibrary.getAvailableUpdates(), sourceLanguages);
}
// list
mHolder.mLanguageList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final ServerLibraryLanguageAdapter.ListItem item = mHolder.mAdapter.getItem(position);
// ignore clicks if a task is already running.
DownloadSourceLanguageTask task = (DownloadSourceLanguageTask)TaskManager.getTask(mProject.getId() + "-" + item.sourceLanguage.getId());
if(task == null || task.isFinished()) {
boolean isDownloaded = AppContext.getLibrary().sourceLanguageHasSource(mProject.getId(), item.sourceLanguage.getId());
if (!isDownloaded) {
// just download the update
task = new DownloadSourceLanguageTask(mProject.getId(), item.sourceLanguage.getId());
task.addOnFinishedListener(ServerLibraryDetailFragment.this);
TaskManager.addTask(task, mProject.getId() + "-" + item.sourceLanguage.getId());
TaskManager.groupTask(task, DOWNLOAD_SOURCE_LANGUAGE_TASK_GROUP);
task.addOnFinishedListener(item.onFinishedListener);
task.addOnProgressListener(item.onProgressListener);
} else {
// confirm with the user
CustomAlertDialog.Create(getActivity())
.setTitle(R.string.download)
.setIcon(R.drawable.ic_refresh_black_24dp)
.setMessage(R.string.source_language_already_downloaded)
.setPositiveButton(R.string.yes, new View.OnClickListener() {
@Override
public void onClick(View v) {
DownloadSourceLanguageTask task = new DownloadSourceLanguageTask(mProject.getId(), item.sourceLanguage.getId());
task.addOnFinishedListener(ServerLibraryDetailFragment.this);
TaskManager.addTask(task, mProject.getId() + "-" + item.sourceLanguage.getId());
TaskManager.groupTask(task, DOWNLOAD_SOURCE_LANGUAGE_TASK_GROUP);
task.addOnFinishedListener(item.onFinishedListener);
task.addOnProgressListener(item.onProgressListener);
}
})
.setNegativeButton(R.string.no, null)
.show("LangAlready");
}
}
}
});
}
}
public void onSaveInstanceState(Bundle out) {
out.putString(STATE_SELECTED_TAB, mSelectedTab);
super.onSaveInstanceState(out);
}
@Override
public void onDestroy() {
List<ManagedTask> tasks = TaskManager.getGroupedTasks(ServerLibraryDetailFragment.DOWNLOAD_SOURCE_LANGUAGE_TASK_GROUP);
for(ManagedTask task:tasks) {
task.removeAllOnFinishedListener();
task.removeAllOnProgressListener();
}
super.onDestroy();
}
private List<SourceLanguage> getSourceLanguages() {
// TRICKY: we convert the source translations to source languages so we only get
// languages that meet the minimum checking level
SourceTranslation[] sourceTranslations = mServerLibrary.getSourceTranslations(mProject.getId());
Map<String, SourceLanguage> sourceLanguages = new HashMap<>();
for(SourceTranslation sourceTranslation:sourceTranslations) {
SourceLanguage sourceLanguage = mServerLibrary.getSourceLanguage(mProject.getId(), sourceTranslation.sourceLanguageSlug);
// TRICKY: a source language could be represented several times due to multiple resources
if(!sourceLanguages.containsKey(sourceLanguage.getId())) {
sourceLanguages.put(sourceLanguage.getId(), sourceLanguage);
}
}
return new ArrayList(sourceLanguages.values());
}
/**
* Returns a list of unique source languages that have drafts available
* @return
*/
private List<SourceLanguage> getDraftLanguages() {
// TRICKY: we convert the source translations to source languages so we only get
// languages that meet the minimum checking level
SourceTranslation[] draftTranslations = mServerLibrary.getDraftTranslations(mProject.getId());
Map<String, SourceLanguage> draftLanguages = new HashMap<>();
for(SourceTranslation draftTranslation:draftTranslations) {
SourceLanguage sourceLanguage = mServerLibrary.getSourceLanguage(mProject.getId(), draftTranslation.sourceLanguageSlug);
// TRICKY: a source language could be represented several times due to multiple resources
if(!draftLanguages.containsKey(sourceLanguage.getId())) {
draftLanguages.put(sourceLanguage.getId(), sourceLanguage);
}
}
return new ArrayList<>(draftLanguages.values());
}
/**
* Called when the image download is complete
* @param task
*/
@Override
public void onFinished(final ManagedTask task) {
TaskManager.clearTask(task);
if(task instanceof DownloadProjectImageTask) {
mImagePath = ((DownloadProjectImageTask) task).getImagePath();
// TODO: do we need to run this on the main thread?
loadImage();
} else if(task instanceof DownloadSourceLanguageTask) {
Handler hand = new Handler(Looper.getMainLooper());
hand.post(new Runnable() {
@Override
public void run() {
rebuildLayout();
if (((DownloadSourceLanguageTask) task).getSuccess()) {
mListener.onSourceLanguageDownloaded(((DownloadSourceLanguageTask) task).getProjectId(), ((DownloadSourceLanguageTask) task).getSourceLanguageId());
}
}
});
}
}
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
this.mListener = (OnEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnEventListener");
}
}
/**
* Loads the image from the disk
*/
private void loadImage() {
// TODO: update this
// if(mImagePath != null) {
// AppContext.context().getImageLoader().loadImage(mImagePath, new SimpleImageLoadingListener() {
// @Override
// public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// if (mIcon != null) {
// mIcon.setImageBitmap(loadedImage);
// AnimationUtilities.fadeIn(mIcon, 100);
// }
// }
// });
// }
}
/**
* Sets the id of the project to be displayed
* @param projectId
*/
public void setProjectId(String projectId) {
mProject = mServerLibrary.getProject(projectId, Locale.getDefault().getLanguage());
// TODO: handle null project
rebuildLayout();
}
private class ViewHolder {
public final TextView mDateModified;
public final TextView mProjectTitle;
public final TextView mProjectDescription;
public final ImageView mIcon;
public final Button mDeleteButton;
public final TabLayout mTabLayout;
private final ListView mLanguageList;
private final ServerLibraryLanguageAdapter mAdapter;
public ViewHolder(View v) {
mLanguageList = (ListView)v.findViewById(R.id.language_list);
mAdapter = new ServerLibraryLanguageAdapter(getActivity());
mLanguageList.setAdapter(mAdapter);
mTabLayout = (TabLayout)v.findViewById(R.id.language_tabs);
mDateModified = (TextView)v.findViewById(R.id.dateModifiedTextView);
mProjectTitle = (TextView)v.findViewById(R.id.modelTitle);
mProjectDescription = (TextView)v.findViewById(R.id.modelDescription);
mIcon = (ImageView)v.findViewById(R.id.modelImage);
mDeleteButton = (Button)v.findViewById(R.id.deleteProjectButton);
}
}
public interface OnEventListener {
void onSourceLanguageDownloaded(String projectId, String sourceLanguageId);
void onProjectDeleted(String projectId);
}
}