/*
* @copyright 2012 Philip Warner
* @license GNU General Public License
*
* This file is part of Book Catalogue.
*
* Book Catalogue 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.
*
* Book Catalogue 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 Book Catalogue. If not, see <http://www.gnu.org/licenses/>.
*/
package com.eleybourn.bookcatalogue.goodreads;
import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.eleybourn.bookcatalogue.CatalogueDBAdapter;
import com.eleybourn.bookcatalogue.R;
import com.eleybourn.bookcatalogue.compat.BookCatalogueListActivity;
import com.eleybourn.bookcatalogue.goodreads.api.SearchBooksApiHandler;
import com.eleybourn.bookcatalogue.utils.Logger;
import com.eleybourn.bookcatalogue.utils.SimpleTaskQueue;
import com.eleybourn.bookcatalogue.utils.Utils;
import com.eleybourn.bookcatalogue.utils.ViewTagger;
/**
* Search goodreads for a book and display the list of results. Use background tasks to get thumbnails and update when retrieved.
*
* @author Philip Warner
*/
public class GoodreadsSearchResults extends BookCatalogueListActivity {
//private static Integer mIdCounter = 0;
//private int mId = 0;
public static final String SEARCH_CRITERIA = "criteria";
private CatalogueDBAdapter mDbHelper;
private ArrayList<GoodreadsWork> mList = new ArrayList<GoodreadsWork>();
private ArrayAdapter<GoodreadsWork> mAdapter = null;
private String mCriteria;
private SimpleTaskQueue mTaskQueue = new SimpleTaskQueue("gr-covers");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//synchronized(mIdCounter) {
// mId = ++mIdCounter;
//}
// Basic setup
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
setContentView(R.layout.goodreads_work_list);
// Look for search criteria
Bundle extras = this.getIntent().getExtras();
if (extras != null && extras.containsKey(SEARCH_CRITERIA)) {
mCriteria = extras.getString(SEARCH_CRITERIA).trim();
}
// If we have criteria, do a search. Otherwise complain and finish.
if (!mCriteria.equals("")) {
doSearch();
} else {
Toast.makeText(this, getString(R.string.please_enter_search_criteria), Toast.LENGTH_LONG).show();
finish();
return;
}
Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
}
/**
* Fix background
*/
@Override
public void onResume() {
super.onResume();
Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
}
/**
* Perform the search.
*/
private void doSearch() {
// Get the GR stuff we need
GoodreadsManager grMgr = new GoodreadsManager();
SearchBooksApiHandler searcher = new SearchBooksApiHandler(grMgr);
// Run the search
ArrayList<GoodreadsWork> works = null;
try {
works = searcher.search(mCriteria);
} catch (Exception e) {
Logger.logError(e, "Failed when searching goodreads");
Toast.makeText(this, getString(R.string.error_while_searching) + " " + getString(R.string.if_the_problem_persists), Toast.LENGTH_LONG).show();
finish();
return;
}
// Finish if no results, otherwise display them
if (works == null || works.size() == 0) {
Toast.makeText(this, getString(R.string.no_matching_book_found), Toast.LENGTH_LONG).show();
finish();
return;
}
mList = works;
mAdapter = new ResultsAdapter();
setListAdapter(mAdapter);
}
/**
* Class used in implementing holder pattern for search results.
*
* @author Philip Warner
*/
private class ListHolder {
GoodreadsWork work;
TextView title;
TextView author;
ImageView cover;
}
/**
* Handle user clicking on a book. This should show editions and allow the user to select a specific edition.
* Waiting on approval for API access.
*
* @param v View that was clicked.
*/
private void doItemClick(View v) {
ListHolder holder = (ListHolder)ViewTagger.getTag(v);
// TODO: Implement edition lookup - requires access to work.editions API from GR
Toast.makeText(this, "Not implemented: see " + holder.title + " by " + holder.author, Toast.LENGTH_LONG).show();
//Intent i = new Intent(this, GoodreadsW)
}
/**
* ArrayAdapter that uses holder pattern to display goodreads books and allows for background image retrieval.
*
* @author Philip Warner
*
*/
private class ResultsAdapter extends ArrayAdapter<GoodreadsWork> {
/** Used in building views when needed */
LayoutInflater mInflater;
public ResultsAdapter() {
super(GoodreadsSearchResults.this, 0, mList);
// Save Inflater for later use
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
ListHolder holder;
if(convertView == null) {
// Not recycling
try {
// Get a new View and make the holder for it.
convertView = mInflater.inflate(R.layout.goodreads_work_item, parent, false);
holder = new ListHolder();
holder.author = (TextView)convertView.findViewById(R.id.author);
holder.title = (TextView)convertView.findViewById(R.id.title);
holder.cover = (ImageView)convertView.findViewById(R.id.cover);
// Save the holder
ViewTagger.setTag(convertView, holder);
// Set the click listener
convertView.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
doItemClick(v);
}});
} catch (Exception e) {
System.out.println(e.getMessage());
throw new RuntimeException(e);
}
} else {
// Recycling: just get the holder
holder = (ListHolder)ViewTagger.getTag(convertView);
}
synchronized(convertView){
synchronized(holder.cover) {
// Save the work details
holder.work = mList.get(position);
// get the cover (or put it in background task)
holder.work.fillImageView(mTaskQueue, holder.cover);
// Update the views based on the work
holder.author.setText(holder.work.authorName);
holder.title.setText(holder.work.title);
}
}
return convertView;
}
}
/**
* Cleanup
*/
@Override
public void onDestroy() {
super.onDestroy();
if (mDbHelper != null)
mDbHelper.close();
}
}