/*
* Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.network;
import java.util.*;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.*;
import android.widget.BaseAdapter;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.network.ZLNetworkException;
import org.geometerplus.zlibrary.core.language.ZLLanguageUtil;
import org.geometerplus.zlibrary.ui.androidfly.R;
import org.geometerplus.android.util.UIUtil;
import org.geometerplus.fbreader.network.*;
import org.geometerplus.fbreader.network.opds.OPDSCustomLink;
public class NetworkLibraryActivity extends NetworkBaseActivity {
static final String ADD_CATALOG = "android.fbreader.action.ADD_CATALOG";
private static final String ADD_CATALOG_TITLE_KEY = "title";
private static final String ADD_CATALOG_SUMMARY_KEY = "summary";
private static final String ADD_CATALOG_ID_KEY = "id";
private static final String ADD_CATALOG_URLS_MAP_KEY = "urls";
static void addLinkToIntent(Intent intent, ICustomNetworkLink link) {
final String textUrl = link.getUrlInfo(INetworkLink.URL_MAIN).URL;
intent.setData(Uri.parse(textUrl));
intent
.putExtra(ADD_CATALOG_TITLE_KEY, link.getTitle())
.putExtra(ADD_CATALOG_SUMMARY_KEY, link.getSummary())
.putExtra(ADD_CATALOG_ID_KEY, link.getId())
.putExtra(ADD_CATALOG_URLS_MAP_KEY, link.urlInfoMap());
}
static ICustomNetworkLink getLinkFromIntent(Intent intent) {
final Uri uri = intent.getData();
if (uri == null || !intent.hasExtra(ADD_CATALOG_ID_KEY)) {
return null;
}
return new OPDSCustomLink(
intent.getIntExtra(ADD_CATALOG_ID_KEY, ICustomNetworkLink.INVALID_ID),
uri.getHost(),
intent.getStringExtra(ADD_CATALOG_TITLE_KEY),
intent.getStringExtra(ADD_CATALOG_SUMMARY_KEY),
(HashMap<String,UrlInfo>)intent.getSerializableExtra(ADD_CATALOG_URLS_MAP_KEY)
);
}
private NetworkTree myTree;
private volatile Intent myIntent;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
myIntent = getIntent();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
processIntent(intent);
}
void processSavedIntent() {
if (myIntent != null) {
processIntent(myIntent);
myIntent = null;
}
}
private void processIntent(Intent intent) {
if (ADD_CATALOG.equals(intent.getAction())) {
final ICustomNetworkLink link = getLinkFromIntent(intent);
if (link != null) {
runOnUiThread(new Runnable() {
public void run() {
final NetworkLibrary library = NetworkLibrary.Instance();
library.addCustomLink(link);
library.synchronize();
NetworkView.Instance().fireModelChangedAsync();
getListView().invalidateViews();
}
});
}
}
}
void prepareView() {
if (myTree == null) {
myTree = NetworkLibrary.Instance().getRootTree();
setListAdapter(new LibraryAdapter());
getListView().invalidateViews();
}
}
@Override
public void onResume() {
super.onResume();
if (!NetworkView.Instance().isInitialized()) {
if (NetworkInitializer.Instance == null) {
new NetworkInitializer(this);
NetworkInitializer.Instance.start();
} else {
NetworkInitializer.Instance.setActivity(this);
}
} else {
prepareView();
if (myIntent != null) {
processIntent(myIntent);
myIntent = null;
}
}
}
@Override
public void onDestroy() {
if (!NetworkView.Instance().isInitialized() && NetworkInitializer.Instance != null) {
NetworkInitializer.Instance.setActivity(null);
}
super.onDestroy();
}
private final class LibraryAdapter extends BaseAdapter {
public final int getCount() {
if (!NetworkView.Instance().isInitialized()) {
return 0;
}
return myTree.subTrees().size();
}
public final NetworkTree getItem(int position) {
return (NetworkTree)myTree.subTrees().get(position);
}
public final long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, final ViewGroup parent) {
final NetworkTree tree = getItem(position);
return setupNetworkTreeItemView(convertView, parent, tree);
}
}
protected MenuItem addMenuItem(Menu menu, int index, String resourceKey, int iconId) {
final String label = myResource.getResource("menu").getResource(resourceKey).getValue();
return menu.add(0, index, Menu.NONE, label).setIcon(iconId);
}
private static final int MENU_SEARCH = 1;
private static final int MENU_REFRESH = 2;
private static final int MENU_ADD_CATALOG = 3;
private static final int MENU_LANGUAGE_FILTER = 4;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
addMenuItem(menu, MENU_SEARCH, "networkSearch", R.drawable.ic_menu_search);
addMenuItem(menu, MENU_ADD_CATALOG, "addCustomCatalog", R.drawable.ic_menu_add);
addMenuItem(menu, MENU_REFRESH, "refreshCatalogsList", R.drawable.ic_menu_refresh);
addMenuItem(menu, MENU_LANGUAGE_FILTER, "languages", R.drawable.ic_menu_languages);
return true;
}
private static boolean searchIsInProgress() {
final NetworkView nView = NetworkView.Instance();
return
nView != null &&
nView.containsItemsLoadingRunnable(
NetworkLibrary.Instance().getSearchItemTree().getUniqueKey()
);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(MENU_SEARCH).setEnabled(!searchIsInProgress());
return true;
}
private void runLanguageFilterDialog() {
final NetworkLibrary library = NetworkLibrary.Instance();
final List<String> allLanguageCodes = library.languageCodes();
Collections.sort(allLanguageCodes, new ZLLanguageUtil.CodeComparator());
final Collection<String> activeLanguageCodes = library.activeLanguageCodes();
final CharSequence[] languageNames = new CharSequence[allLanguageCodes.size()];
final boolean[] checked = new boolean[allLanguageCodes.size()];
for (int i = 0; i < allLanguageCodes.size(); ++i) {
final String code = allLanguageCodes.get(i);
languageNames[i] = ZLLanguageUtil.languageName(code);
checked[i] = activeLanguageCodes.contains(code);
}
final DialogInterface.OnMultiChoiceClickListener listener =
new DialogInterface.OnMultiChoiceClickListener() {
public void onClick(DialogInterface dialog, int which, boolean isChecked) {
checked[which] = isChecked;
}
};
final ZLResource dialogResource = ZLResource.resource("dialog");
final AlertDialog dialog = new AlertDialog.Builder(this)
.setMultiChoiceItems(languageNames, checked, listener)
.setTitle(dialogResource.getResource("languageFilterDialog").getResource("title").getValue())
.setPositiveButton(dialogResource.getResource("button").getResource("ok").getValue(), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final TreeSet<String> newActiveCodes = new TreeSet<String>(new ZLLanguageUtil.CodeComparator());
for (int i = 0; i < checked.length; ++i) {
if (checked[i]) {
newActiveCodes.add(allLanguageCodes.get(i));
}
}
library.setActiveLanguageCodes(newActiveCodes);
library.synchronize();
NetworkView.Instance().fireModelChanged();
}
})
.create();
dialog.show();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_SEARCH:
return onSearchRequested();
case MENU_ADD_CATALOG:
AddCustomCatalogItemActions.addCustomCatalog(this);
return true;
case MENU_REFRESH:
refreshCatalogsList();
return true;
case MENU_LANGUAGE_FILTER:
runLanguageFilterDialog();
return true;
default:
return true;
}
}
@Override
public boolean onSearchRequested() {
if (searchIsInProgress()) {
return false;
}
final NetworkLibrary library = NetworkLibrary.Instance();
startSearch(library.NetworkSearchPatternOption.getValue(), true, null, false);
return true;
}
@Override
public void onModelChanged() {
getListView().invalidateViews();
}
private void refreshCatalogsList() {
final NetworkView view = NetworkView.Instance();
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.obj == null) {
view.finishBackgroundUpdate();
} else {
final ZLResource dialogResource = ZLResource.resource("dialog");
final ZLResource boxResource = dialogResource.getResource("networkError");
final ZLResource buttonResource = dialogResource.getResource("button");
new AlertDialog.Builder(NetworkLibraryActivity.this)
.setTitle(boxResource.getResource("title").getValue())
.setMessage((String) msg.obj)
.setIcon(0)
.setPositiveButton(buttonResource.getResource("ok").getValue(), null)
.create().show();
}
}
};
UIUtil.wait("updatingCatalogsList", new Runnable() {
public void run() {
String error = null;
try {
view.runBackgroundUpdate(true);
} catch (ZLNetworkException e) {
error = e.getMessage();
}
handler.sendMessage(handler.obtainMessage(0, error));
}
}, this);
}
}