/*
* Copyright (C) 2010-2013 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.covers;
import java.util.concurrent.Future;
import org.geometerplus.fbreader.tree.FBTree;
import org.geometerplus.zlibrary.core.image.ZLLoadableImage;
import android.graphics.Bitmap;
import android.widget.ImageView;
class CoverHolder {
private final CoverManager myManager;
final ImageView CoverView;
volatile FBTree.Key Key;
private CoverSyncRunnable coverSyncRunnable;
Future<?> coverBitmapTask;
private Runnable coverBitmapRunnable;
CoverHolder(CoverManager manager, ImageView coverView, FBTree.Key key) {
myManager = manager;
manager.setupCoverView(coverView);
CoverView = coverView;
Key = key;
myManager.Cache.HoldersCounter++;
}
synchronized void setKey(FBTree.Key key) {
if (!Key.equals(key)) {
if (coverBitmapTask != null) {
coverBitmapTask.cancel(true);
coverBitmapTask = null;
}
coverBitmapRunnable = null;
}
Key = key;
}
class CoverSyncRunnable implements Runnable {
private final ZLLoadableImage myImage;
private final FBTree.Key myKey;
CoverSyncRunnable(ZLLoadableImage image) {
myImage = image;
synchronized (CoverHolder.this) {
myKey = Key;
coverSyncRunnable = this;
}
}
public void run() {
synchronized (CoverHolder.this) {
try {
if (coverSyncRunnable != this) {
return;
}
if (!Key.equals(myKey)) {
return;
}
if (!myImage.isSynchronized()) {
return;
}
myManager.runOnUiThread(new Runnable() {
@Override
public void run() {
synchronized (CoverHolder.this) {
if (Key.equals(myKey)) {
myManager.setCoverForView(CoverHolder.this, myImage);
}
}
}
});
} finally {
if (coverSyncRunnable == this) {
coverSyncRunnable = null;
}
}
}
}
}
class CoverBitmapRunnable implements Runnable {
private final ZLLoadableImage myImage;
private final FBTree.Key myKey;
CoverBitmapRunnable(ZLLoadableImage image) {
myImage = image;
synchronized (CoverHolder.this) {
myKey = Key;
coverBitmapRunnable = this;
}
}
public void run() {
synchronized (CoverHolder.this) {
if (coverBitmapRunnable != this) {
return;
}
}
try {
if (!myImage.isSynchronized()) {
return;
}
final Bitmap coverBitmap = myManager.getBitmap(myImage);
if (coverBitmap == null) {
// If bitmap is null, then there's no image
// and CoverView already has a stock image
myManager.Cache.putBitmap(myKey, null);
return;
}
if (Thread.currentThread().isInterrupted()) {
// We have been cancelled
return;
}
/*
synchronized (CoverHolder.this) {
// I'm not sure why, but cover bitmaps disappear all the time
// So if by the time bitmap is generated holder has switched
// to another key/tree, just scrap it, will retry later
if (!Key.equals(myKey)) {
return;
}
}
*/
myManager.Cache.putBitmap(myKey, coverBitmap);
myManager.runOnUiThread(new Runnable() {
@Override
public void run() {
synchronized (CoverHolder.this) {
if (Key.equals(myKey)) {
CoverView.setImageBitmap(coverBitmap);
}
}
}
});
} finally {
synchronized (CoverHolder.this) {
if (coverBitmapRunnable == this) {
coverBitmapRunnable = null;
coverBitmapTask = null;
}
}
}
}
}
}