/*
* Created by Angel Leon (@gubatron), Alden Torres (aldenml)
* Copyright (c) 2011, 2012, FrostWire(TM). All rights reserved.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package com.frostwire.android.gui.fragments;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import com.frostwire.android.R;
import com.frostwire.android.core.ConfigurationManager;
import com.frostwire.android.gui.adapters.SearchResultListAdapter;
import com.frostwire.android.gui.search.BittorrentSearchEngine;
import com.frostwire.android.gui.search.BittorrentSearchResult;
import com.frostwire.android.gui.search.SearchResult;
import com.frostwire.android.gui.search.SearchResultDisplayer;
import com.frostwire.android.gui.transfers.DownloadTransfer;
import com.frostwire.android.gui.views.AbstractListFragment;
import com.frostwire.android.gui.views.SearchInputView;
import com.frostwire.android.gui.views.SearchInputView.OnSearchListener;
/**
* @author gubatron
* @author aldenml
*
*/
public class SearchFragment extends AbstractListFragment implements
SearchResultDisplayer {
private static final int MAX_EXPECT_COUNT = 5; // tuning constants for hide progress dialog
private SearchInputView searchInput;
private Object lockObj = new Object();
private SearchResultListAdapter adapter;
private BittorrentSearchEngine searchManager;
private int mediaTypeId;
private int expectCount;
private ProgressDialog progressDlg;
public SearchFragment() {
super(R.layout.fragment_search);
mediaTypeId = ConfigurationManager.instance().getLastMediaTypeFilter();
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
}
public void clear() {
synchronized (lockObj) {
if (adapter != null) {
adapter.clear();
}
}
}
public void addResults(final List<SearchResult> results) {
synchronized (lockObj) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (!searchInput.isEmpty()) {
if (adapter == null) {
adapter = new SearchResultListAdapter(
getActivity(), results) {
@Override
protected void onTransferStarted(
DownloadTransfer transfer) {
searchManager.cancelSearch();
}
};
adapter.filter(mediaTypeId);
setListAdapter(adapter);
} else {
List<SearchResult> list = adapter.getList();
list.addAll(results); // heavy use of OO references
adapter.sort(new Comparator<SearchResult>() {
public int compare(SearchResult lhs,
SearchResult rhs) {
if (lhs instanceof BittorrentSearchResult) {
if (rhs instanceof BittorrentSearchResult) {
return ((BittorrentSearchResult) rhs)
.getSeeds()
- ((BittorrentSearchResult) lhs)
.getSeeds();
} else {
return -1;
}
}
return 0;
}
});
adapter.filter(mediaTypeId);
}
}
if (adapter != null) {
if (adapter.getCount() > 0) {
hideProgressDialog();
} else {
if (expectCount > MAX_EXPECT_COUNT) {
hideProgressDialog();
} else {
expectCount++;
}
}
}
}
});
}
}
public void addResult(final SearchResult sr) {
synchronized (lockObj) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
hideProgressDialog();
if (!searchInput.isEmpty() && adapter != null
&& sr instanceof BittorrentSearchResult) {
BittorrentSearchResult bsr = (BittorrentSearchResult) sr;
adapter.addItem(sr, adapter.accept(bsr, mediaTypeId));
}
}
});
}
}
public List<SearchResult> getResults() {
synchronized (lockObj) {
if (adapter != null) {
return new ArrayList<SearchResult>(adapter.getList());
} else {
return Collections.emptyList();
}
}
}
@Override
protected void initComponents(final View view) {
searchInput = findView(view, R.id.fragment_search_input);
searchInput.setOnSearchListener(new OnSearchListener() {
public void onSearch(View v, String query, int mediaTypeId) {
SearchFragment.this.mediaTypeId = mediaTypeId;
switchView(view,android.R.id.list);
showProgressDialog();
searchManager.performSearch(query);
}
public void onMediaTypeSelected(View v, int mediaTypeId) {
SearchFragment.this.mediaTypeId = mediaTypeId;
if (adapter != null) {
adapter.filter(mediaTypeId);
}
}
public void onClear(View v) {
switchView(view,R.id.fragment_search_promos);
searchManager.cancelSearch();
adapter = null;
setListAdapter(null);
}
});
searchManager = new BittorrentSearchEngine(getActivity(), this);
switchView(view,R.id.fragment_search_promos);
}
@Override
protected void dismissDialogs() {
super.dismissDialogs();
searchInput.hideQuickAction();
if (adapter != null) {
adapter.dismissDialogs();
}
}
private void showProgressDialog() {
hideProgressDialog();
expectCount = 0;
progressDlg = new ProgressDialog(getActivity());
progressDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDlg.setMessage(getString(R.string.searching_indeterminate));
progressDlg.setCancelable(false);
trackDialog(progressDlg).show();
}
private void hideProgressDialog() {
if (progressDlg != null) {
try {
progressDlg.dismiss();
} catch (Throwable e) {
// ignore
}
}
}
private void switchView(View v, int id) {
FrameLayout frameLayout = findView(v,
R.id.fragment_search_framelayout);
int childCount = frameLayout.getChildCount();
for (int i = 0; i < childCount; i++) {
View childAt = frameLayout.getChildAt(i);
childAt.setVisibility((childAt.getId() == id) ? View.VISIBLE
: View.INVISIBLE);
}
}
}