package com.gettingmobile.goodnews.itemlist;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteDatabase;
import android.text.Html;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.ToggleButton;
import com.gettingmobile.android.app.DialogFactory;
import com.gettingmobile.goodnews.Application;
import com.gettingmobile.goodnews.R;
import com.gettingmobile.goodnews.itemview.ClassicItemUrlSharer;
import com.gettingmobile.goodnews.itemview.ItemUrlSharer;
import com.gettingmobile.goodnews.settings.SettingsIntentFactory;
import com.gettingmobile.goodnews.tip.TipDialogHandler;
import com.gettingmobile.goodnews.util.*;
import com.gettingmobile.google.reader.ElementId;
import com.gettingmobile.google.reader.Item;
import com.gettingmobile.google.reader.ItemState;
import com.gettingmobile.google.reader.ItemTeaserSource;
import com.gettingmobile.google.reader.db.ItemDatabaseAdapter;
import com.gettingmobile.google.reader.db.ItemTagChangeListener;
import com.gettingmobile.text.HtmlUtil;
import com.google.inject.Inject;
import roboguice.RoboGuice;
import java.text.DecimalFormat;
import java.text.NumberFormat;
final class ItemRowViewHandler implements View.OnClickListener, OnCheckedChangeListener, ItemTagChangeListener {
private static final NumberFormat MBYTE_FORMAT = new DecimalFormat("#,##0");
private final ItemTimestampFormat timestampFormat;
private final ItemListActivity activity;
private final Application app;
private final ItemUrlSharer itemUrlSharer;
private View view = null;
private TextView titleView = null;
private TextView feedTitleView = null;
private TextView timestampView = null;
private TextView labelView = null;
private TextView teaserView = null;
private Button offlineIndicator = null;
private ToggleButton readButton = null;
private ToggleButton starredButton = null;
private ToggleButton readListButton = null;
private Item item = null;
@Inject
private SettingsIntentFactory settingsIntentFactory = null;
public static ItemRowViewHandler getByView(View view) {
return (ItemRowViewHandler) (view != null ? view.getTag() : null);
}
public ItemRowViewHandler(ItemListActivity activity) {
this.activity = activity;
activity.itemTagChangeAdapter.addListener(this);
app = activity.getApp();
timestampFormat = new ItemTimestampFormat(app, false);
itemUrlSharer = new ClassicItemUrlSharer(activity);
RoboGuice.getInjector(activity).injectMembers(this);
}
public void init(View view, Item item) {
if (this.view != view) {
this.view = view;
titleView = (TextView) view.findViewById(R.id.item_row_title);
feedTitleView = (TextView) view.findViewById(R.id.item_row_feed_title);
timestampView = (TextView) view.findViewById(R.id.timestamp);
labelView = (TextView) view.findViewById(R.id.labels);
labelView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showTagSelectionDialog();
}
});
offlineIndicator = (Button) view.findViewById(R.id.indicator_offline);
readButton = (ToggleButton) view.findViewById(R.id.button_read);
starredButton = (ToggleButton) view.findViewById(R.id.button_starred);
readListButton = (ToggleButton) view.findViewById(R.id.button_readlist);
teaserView = (TextView) view.findViewById(R.id.teaser);
/*
* handle offline indicator
*/
offlineIndicator.setOnClickListener(this);
/*
* handle read state
*/
readButton.setOnCheckedChangeListener(this);
/*
* handle starred state
*/
starredButton.setOnCheckedChangeListener(this);
/*
* handle read list
*/
readListButton.setOnCheckedChangeListener(this);
}
view.setTag(this);
this.item = item;
itemUrlSharer.setItemInfo(item.getAlternate() != null ? item.getAlternate().getHref() : null, item.getTitle());
/*
* item title
*/
titleView.setText(Html.fromHtml(ItemTextUtil.getUnformattedItemTitle(app, item)));
/*
* feed title
*/
if (!activity.getGroupByFeeds() && !activity.isFeedsList()) {
String feedTitleText = ItemTextUtil.getItemSpecialFeedTitle(app, item);
if (feedTitleText == null) {
feedTitleText = item.getFeedTitle();
}
feedTitleView.setText(feedTitleText != null ? HtmlUtil.removeTags(feedTitleText) : "");
feedTitleView.setVisibility(View.VISIBLE);
} else {
feedTitleView.setVisibility(View.GONE);
}
/*
* item time
*/
timestampView.setText(timestampFormat.format(item.getTimestamp()));
/*
* teaser
*/
final int maxTeaserWordCount = app.getSettings().getTeaserWordCount();
final String teaser = maxTeaserWordCount > 0 && item.hasTeaser() &&
app.getSettings().getFeedTeaserSource(item.getFeedId()) != ItemTeaserSource.NONE ?
item.getTeaser(maxTeaserWordCount) : null;
if (teaser != null && teaser.length() > 0) {
teaserView.setVisibility(View.VISIBLE);
teaserView.setText(Html.fromHtml(teaser));
} else {
teaserView.setVisibility(View.GONE);
}
/*
* choose adequate list button
*/
starredButton.setVisibility(app.getSettings().shouldShowStarredTag() ? View.VISIBLE : View.GONE);
readListButton.setVisibility(app.getSettings().shouldShowReadListTag() ? View.VISIBLE : View.GONE);
updateView();
}
public Item getItem() {
return item;
}
public void updateView() {
activity.itemListAdapter.adjustItem(item);
updateOfflineIndicator();
updateViewReadState(item.isRead());
updateToggleButton(starredButton, item.hasTag(ItemState.STARRED.getId()));
updateToggleButton(readListButton, item.hasTag(app.getSettings().getLabelReadListId()));
updateLabelView();
}
private void updateToggleButton(ToggleButton btn, boolean state) {
btn.setOnCheckedChangeListener(null);
btn.setChecked(state);
btn.setOnCheckedChangeListener(this);
}
private void updateLabelView() {
TagListViewController.setTags(labelView,
TagFilter.filterSpecialTagIds(app.getSettings(), item.getTagIds()),
app.getResources().getColor(R.color.highlight));
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.indicator_offline) {
onOfflineIndicatorClicked();
}
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.getId() == R.id.button_read) {
setRead(isChecked);
} else if (buttonView.getId() == R.id.button_starred) {
onStarredCheckedChanged(isChecked);
} else if (buttonView.getId() == R.id.button_readlist) {
onReadListCheckedChanged(isChecked);
}
}
private void updateViewReadState(boolean isRead) {
item.setRead(isRead);
updateToggleButton(readButton, isRead);
setTitleViewAppearance(isRead);
if (isRead) {
activity.onMarkedItemRead();
}
}
private void setTitleViewAppearance(boolean isRead) {
titleView.setTextAppearance(view.getContext(), app.getThemeUtil().getThemeResource(view,
isRead ? R.attr.textAppearanceListItem : R.attr.textAppearanceListItemEmphasized));
switch (app.getSettings().getItemListTitleTextSize()) {
case SMALLEST:
setTitleViewSize(R.dimen.title_text_smallest);
break;
case SMALLER:
setTitleViewSize(R.dimen.title_text_smaller);
break;
default:
// no explicit change
}
}
private void setTitleViewSize(int dimensionId) {
titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, app.getResources().getDimension(dimensionId));
}
private void implicitlyUpdateViewReadState() {
if (app.getSettings().markReadOnTag()) {
updateViewReadState(true);
}
}
private void implicitlyMarkRead() {
if (app.getSettings().markReadOnTag()) {
markRead(true);
}
}
private void markRead(boolean isRead) {
activity.itemTagChangeAdapter.markItemRead(item, isRead);
}
private void setRead(boolean isRead) {
markRead(isRead);
updateViewReadState(isRead);
}
private void onLabelCheckedChanged(final ElementId labelId, ToggleButton btn, final boolean isChecked) {
/*
* at first update controls to give quick visual feedback
*/
if (isChecked) {
item.getTagIds().add(labelId);
} else {
item.getTagIds().remove(labelId);
}
updateToggleButton(btn, isChecked);
if (isChecked) {
implicitlyUpdateViewReadState();
}
/*
* now adjust the database
*/
activity.itemTagChangeAdapter.changeItemTag(item, labelId, isChecked);
if (isChecked) {
implicitlyMarkRead();
}
}
private void onStarredCheckedChanged(boolean isStarred) {
onLabelCheckedChanged(ItemState.STARRED.getId(), starredButton, isStarred);
}
private void onReadListCheckedChanged(boolean isOnReadList) {
onLabelCheckedChanged(app.getSettings().getLabelReadListId(), readListButton, isOnReadList);
}
private void onOfflineIndicatorClicked() {
if (app.getSettings().offlineIndicatorTogglesReadState()) {
setRead(!item.isRead());
} else {
TipDialogHandler.start(activity, app.getTipManager(), "offline_indicator");
}
}
private void updateOfflineIndicator() {
final int offlineIndicatorDrawableId;
if (item != null && item.hasContent()) {
offlineIndicatorDrawableId = app.getThemeUtil().getThemeResource(
offlineIndicator, R.attr.offlineContentFullIcon);
} else if (item != null && item.hasSummary()) {
offlineIndicatorDrawableId = app.getThemeUtil().getThemeResource(
offlineIndicator, R.attr.offlineContentSummaryIcon);
} else {
offlineIndicatorDrawableId = app.getThemeUtil().getThemeResource(
offlineIndicator, R.attr.offlineContentNoneIcon);
}
offlineIndicator.setCompoundDrawablesWithIntrinsicBounds(offlineIndicatorDrawableId, 0, 0, 0);
}
/*
* Context menu handling
*/
public void onPrepareContextMenu(ContextMenu menu) {
if (item != null) {
final String url = item.getAlternate() != null ? item.getAlternate().getHref() : null;
menu.findItem(R.id.menu_item_browser).setEnabled(url != null && url.length() > 0);
/*
* provide delete option is this is a label list
*/
menu.findItem(R.id.menu_item_blacklist).setVisible(activity.getIntentElementIsStateOrLabel());
} else {
menu.clear();
}
}
public boolean onContextItemSelected(int itemId) {
if (itemId == R.id.menu_item_open) {
activity.openItem(item);
} else if (itemId == R.id.menu_item_browser) {
activity.openItemInBrowser(item);
} else if (itemId == R.id.menu_item_tags) {
showTagSelectionDialog();
} else if (itemId == R.id.menu_item_share) {
shareItemUrl();
} else if (itemId == R.id.menu_item_feed_preferences) {
if (item.getFeedId() != null) {
activity.startActivity(settingsIntentFactory.createFeedSettingsIntent(item.getFeedId()));
}
} else if (itemId == R.id.menu_item_blacklist) {
blacklistItem();
} else {
return false;
}
return true;
}
protected void showTagSelectionDialog() {
new TagSelectionDialogBuilder(activity, item, activity.itemTagChangeAdapter).show();
}
protected void shareItemUrl() {
itemUrlSharer.handleAction();
}
protected void blacklistItem() {
DialogFactory.showYesNoDialog(activity, R.string.blacklist_title, R.string.blacklist_message, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
final SQLiteDatabase db = app.getDbHelper().getDatabase();
db.beginTransaction();
try {
new ItemDatabaseAdapter().blacklistItem(db, item);
db.setTransactionSuccessful();
activity.loadView();
} finally {
db.endTransaction();
}
}
});
}
/*
* ItemTagChangeListener implementation
*/
@Override
public void onItemReadStateChanged(long itemKey, boolean read) {
if (item != null && item.getKey() == itemKey) {
updateView();
}
}
@Override
public void onItemTagChanged(long itemKey, ElementId tag, boolean added) {
if (item != null && item.getKey() == itemKey) {
updateView();
}
}
}