package com.eleybourn.bookcatalogue;
import java.util.ArrayList;
import java.util.Date;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.eleybourn.bookcatalogue.Fields.Field;
import com.eleybourn.bookcatalogue.Fields.FieldFormatter;
import com.eleybourn.bookcatalogue.debug.Tracker;
import com.eleybourn.bookcatalogue.utils.HintManager;
import com.eleybourn.bookcatalogue.utils.Logger;
import com.eleybourn.bookcatalogue.utils.Utils;
/**
* Class for representing read-only book details.
* @author n.silin
*/
public class BookDetailsReadOnly extends BookDetailsAbstract {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Tracker.enterOnCreateView(this);
final View rootView = inflater.inflate(R.layout.book_details, null);
Tracker.exitOnCreateView(this);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
/* In superclass onCreate method we initialize fields, background,
* display metrics and other. So see superclass onCreate method. */
// Set additional (non book details) fields before their populating
addFields();
/*
* We have to override this value to initialize book thumb with right size.
* You have to see in book_details.xml to get dividing coefficient
*/
mThumbEditSize = Math.min(mMetrics.widthPixels, mMetrics.heightPixels) / 3;
if (savedInstanceState == null) {
HintManager.displayHint(getActivity(), R.string.hint_view_only_help, null);
}
// Just format a binary value as yes/no/blank
mFields.getField(R.id.signed).formatter = new BinaryYesNoEmptyFormatter();
}
/**
* This is a straight passthrough
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode) {
case UniqueId.ACTIVITY_EDIT_BOOK:
// Update fields of read-only book after editing
// --- onResume() calls through to restoreBookData() which will do this now
//if (resultCode == Activity.RESULT_OK) {
// updateFields(mEditManager.getBookData());
//}
break;
}
}
@Override
/* The only difference from super class method is initializing of additional
* fields needed for read-only mode (user notes, loaned, etc.) */
protected void populateFieldsFromBook(BookData book) {
try {
//BookData book = mEditManager.getBookData();
populateBookDetailsFields(book);
// Set maximum aspect ratio width : height = 1 : 2
setBookThumbnail(book.getRowId(), mThumbEditSize, mThumbEditSize * 2);
// Additional fields for read-only mode which are not initialized automatically
showReadStatus(book);
// XXX: Use the data!
showLoanedInfo(book.getRowId());
showSignedStatus(book);
formatFormatSection(book);
formatPublishingSection(book);
// Restore default visibility and hide unused/unwanted and empty fields
showHideFields(true);
// Hide the fields that we never use...
getView().findViewById(R.id.anthology).setVisibility(View.GONE);
} catch (Exception e) {
Logger.logError(e);
} finally {
}
// Populate bookshelves and hide the field if bookshelves are not set.
if (!populateBookshelvesField(mFields, book)) {
getView().findViewById(R.id.lbl_bookshelves).setVisibility(View.GONE);
//getView().findViewById(R.id.bookshelf_text).setVisibility(View.GONE);
}
}
@Override
/* Override populating author field. Hide the field if author not set or
* shows author (or authors through ',') with 'by' at the beginning. */
protected void populateAuthorListField() {
ArrayList<Author> authors = mEditManager.getBookData().getAuthorList();
int authorsCount = authors.size();
if (authorsCount == 0) {
// Hide author field if it is not set
getView().findViewById(R.id.author).setVisibility(View.GONE);
} else {
StringBuilder builder = new StringBuilder();
builder.append(getResources().getString(R.string.book_details_readonly_by));
builder.append(" ");
for (int i = 0; i < authorsCount; i++) {
builder.append(authors.get(i).getDisplayName());
if (i != authorsCount - 1) {
builder.append(", ");
}
}
mFields.getField(R.id.author).setValue(builder.toString());
}
}
@Override
protected void populateSeriesListField() {
ArrayList<Series> series = mEditManager.getBookData().getSeriesList();
int size = 0;
try {
size = series.size();
} catch (NullPointerException e) {
size = 0;
}
if (size == 0 || !mFields.getField(R.id.series).visible) {
// Hide 'Series' label and data
getView().findViewById(R.id.lbl_series).setVisibility(View.GONE);
getView().findViewById(R.id.series).setVisibility(View.GONE);
return;
} else {
// Show 'Series' label and data
getView().findViewById(R.id.lbl_series).setVisibility(View.VISIBLE);
getView().findViewById(R.id.series).setVisibility(View.VISIBLE);
String newText = null;
Utils.pruneSeriesList(series);
Utils.pruneList(mDbHelper, series);
int seriesCount = series.size();
if (seriesCount > 0) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < seriesCount; i++) {
builder.append(" " + series.get(i).getDisplayName());
if (i != seriesCount - 1) {
builder.append("<br/>");
}
}
newText = builder.toString();
}
mFields.getField(R.id.series)
.setShowHtml(true)
.setValue(newText);
}
}
/**
* Add other fields of book to details fields. We need this method to automatically
* populate some fields during populating. See {@link #populateFieldsFromDb(Long)}.
* Note that it should be performed before populating.
*/
private void addFields() {
// From 'My comments' tab
mFields.add(R.id.rating, CatalogueDBAdapter.KEY_RATING, null);
mFields.add(R.id.notes, CatalogueDBAdapter.KEY_NOTES, null)
.setShowHtml(true);
mFields.add(R.id.read_start, CatalogueDBAdapter.KEY_READ_START, null, new Fields.DateFieldFormatter());
mFields.add(R.id.read_end, CatalogueDBAdapter.KEY_READ_END, null, new Fields.DateFieldFormatter());
mFields.add(R.id.location, CatalogueDBAdapter.KEY_LOCATION, null);
// Make sure the label is hidden when the ISBN is
mFields.add(R.id.isbn_label, "", CatalogueDBAdapter.KEY_ISBN, null);
mFields.add(R.id.publishing_details, "", CatalogueDBAdapter.KEY_PUBLISHER, null);
}
/**
* Formats 'format' section of the book depending on values
* of 'pages' and 'format' fields.
*/
private void formatFormatSection(BookData book){
Field field = mFields.getField(R.id.pages);
String value = book.getString(CatalogueDBAdapter.KEY_PAGES);
boolean isExist = value != null && !value.equals("");
if (isExist) { //If 'pages' field is set format it
field.setValue(getString(R.string.book_details_readonly_pages, value));
}
// Format 'format' field
field = mFields.getField(R.id.format);
value = book.getString(CatalogueDBAdapter.KEY_FORMAT);
if(isExist && value != null && !value.equals("")){
/* Surround 'format' field with braces if 'pages' field is set
* and 'format' field is not empty */
field.setValue(getString(R.string.brackets, value));
}
}
/**
* Formats 'Publishing' section of the book depending on values
* of 'publisher' and 'date published' fields.
*/
private void formatPublishingSection(BookData book){
String date = book.getString(CatalogueDBAdapter.KEY_DATE_PUBLISHED);
boolean hasDate = date != null && !date.equals("");
String pub = book.getString(CatalogueDBAdapter.KEY_PUBLISHER);
boolean hasPub = pub != null && !pub.equals("");
String value;
if (hasDate) {
try {
Date d = Utils.parseDate(date);
date = Utils.toPrettyDate(d);
} catch (Exception e) {
// Ignore; just use what we have
}
}
if (hasPub) {
if (hasDate) {
value = pub + "; " + date;
} else {
value = pub;
}
} else {
if (hasDate) {
value = date;
} else {
value = "";
}
}
mFields.getField(R.id.publishing_details).setValue(value);
}
/**
* Inflates 'Loaned' field showing a person the book loaned to.
* If book is not loaned field is invisible.
* @param rowId Database row _id of the loaned book
*/
private void showLoanedInfo(Long rowId) {
String personLoanedTo = mDbHelper.fetchLoanByBook(rowId);
TextView textView = (TextView) getView().findViewById(R.id.who);
if (personLoanedTo != null) {
textView.setVisibility(View.VISIBLE);
String resultText = getString(R.string.book_details_readonly_loaned_to, personLoanedTo);
textView.setText(resultText);
} else {
textView.setVisibility(View.GONE);
}
}
/**
* Sets read status of the book if needed. Shows green tick if book is read.
* @param book Cursor containing information of the book from database
*/
private void showReadStatus(BookData book) {
if (FieldVisibility.isVisible(CatalogueDBAdapter.KEY_READ)) {
ImageView image = (ImageView) getView().findViewById(R.id.read);
if (book.isRead()) {
image.setVisibility(View.VISIBLE);
image.setImageResource(R.drawable.btn_check_buttonless_on);
} else {
image.setVisibility(View.GONE);
}
} else {
ImageView image = (ImageView) getView().findViewById(R.id.read);
image.setVisibility(View.GONE);
}
}
/**
* Show signed status of the book. Set text 'yes' if signed. Otherwise it is 'No'.
* @param book Cursor containing information of the book from database
*/
private void showSignedStatus(BookData book) {
if (book.isSigned()) {
((TextView) getView().findViewById(R.id.signed)).setText(getResources().getString(R.string.yes));
}
}
/**
* Updates all fields of book from database.
*/
private void updateFields(BookData book){
populateFieldsFromBook(book);
// Populate author and series fields
populateAuthorListField();
populateSeriesListField();
}
@Override
protected void onLoadBookDetails(BookData book, boolean setAllDone) {
if (!setAllDone)
mFields.setAll(book);
updateFields(book);
}
@Override
protected void onSaveBookDetails(BookData book) {
// Override to Do nothing because we modify the fields to make them look pretty.
}
public void onResume() {
// If we are read-only, returning here from somewhere else and have an
// ID...reload!
BookData book = mEditManager.getBookData();
if (book.getRowId() != 0) {
book.reload();
}
super.onResume();
}
/**
* Formatter for date fields. On failure just return the raw string.
*
* @author Philip Warner
*
*/
static private class BinaryYesNoEmptyFormatter implements FieldFormatter {
/**
* Display as a human-friendly date
*/
public String format(Field f, String source) {
try {
boolean val = Utils.stringToBoolean(source, false);
return BookCatalogueApp.getResourceString( val ? R.string.yes : R.string.no);
} catch (Exception e) {
return source;
}
}
/**
* Extract as an SQL date.
*/
public String extract(Field f, String source) {
try {
return Utils.stringToBoolean(source, false) ? "1" : "0";
} catch (Exception e) {
return source;
}
}
}
}