package org.ebookdroid.common.cache;
import org.sufficientlysecure.viewer.R;
import org.ebookdroid.common.bitmaps.BitmapManager;
import org.ebookdroid.common.cache.CacheManager.ICacheListener;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import org.emdev.ui.tasks.AsyncTask;
import org.emdev.ui.tasks.AsyncTaskExecutor;
public class ThumbnailFile extends File {
private static final long serialVersionUID = 4540533658351961301L;
private static final AsyncTaskExecutor executor = new AsyncTaskExecutor(256, 1, 5, 1, "ThumbnailLoader");
public final String book;
private static Bitmap defaultImage;
private final AtomicReference<Bitmap> ref = new AtomicReference<Bitmap>();
private ImageLoadingListener listener;
ThumbnailFile(final String book, final File dir, final String name) {
super(dir, name);
this.book = book;
}
public Bitmap getImage() {
Bitmap bitmap = ref.get();
if (bitmap == null || bitmap.isRecycled()) {
try {
bitmap = load(false);
ref.set(bitmap);
} catch (final OutOfMemoryError ex) {
}
}
return bitmap;
}
public synchronized void loadImageAsync(final Bitmap defImage, final ImageLoadingListener l) {
final Bitmap bitmap = ref.get();
if (bitmap != null && !bitmap.isRecycled()) {
l.onImageLoaded(bitmap);
return;
}
l.onImageLoaded(defImage);
listener = l;
executor.execute(new LoadingTask(), "");
}
protected synchronized void onImageLoaded(final Bitmap result) {
ref.set(result);
if (listener != null) {
listener.onImageLoaded(result);
}
}
public Bitmap getRawImage() {
Bitmap bitmap = ref.get();
if (bitmap == null || bitmap.isRecycled()) {
try {
bitmap = load(true);
ref.set(bitmap);
} catch (final OutOfMemoryError ex) {
}
}
return bitmap;
}
public void setImage(final Bitmap image) {
if (image != null) {
ref.set(paint(image));
store(image);
} else {
this.delete();
}
final ICacheListener l = CacheManager.listeners.getListener();
l.onThumbnailChanged(this);
}
private Bitmap load(final boolean raw) {
if (this.exists()) {
final Bitmap stored = BitmapFactory.decodeFile(this.getPath());
if (stored != null) {
return raw ? stored : paint(stored);
}
}
return getDefaultThumbnail();
}
private void store(final Bitmap image) {
FileOutputStream out = null;
try {
out = new FileOutputStream(this);
image.compress(Bitmap.CompressFormat.JPEG, 50, out);
} catch (final IOException e) {
} finally {
if (out != null) {
try {
out.close();
} catch (final IOException ex) {
}
}
}
}
private static Bitmap paint(final Bitmap image) {
final int left = 15;
final int top = 10;
final int width = image.getWidth() + left;
final int height = image.getHeight() + top;
final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
if (bmp == null) {
return null;
}
bmp.eraseColor(Color.TRANSPARENT);
final Canvas c = new Canvas(bmp);
final Bitmap cornerBmp = BitmapManager.getResource(R.drawable.components_thumbnail_corner);
final Bitmap leftBmp = BitmapManager.getResource(R.drawable.components_thumbnail_left);
final Bitmap topBmp = BitmapManager.getResource(R.drawable.components_thumbnail_top);
c.drawBitmap(cornerBmp, null, new Rect(0, 0, left, top), null);
c.drawBitmap(topBmp, null, new Rect(left, 0, width, top), null);
c.drawBitmap(leftBmp, null, new Rect(0, top, left, height), null);
c.drawBitmap(image, null, new Rect(left, top, width, height), null);
return bmp;
}
private static Bitmap getDefaultThumbnail() {
if (defaultImage == null) {
final Bitmap empty = Bitmap.createBitmap(160, 200, Bitmap.Config.ARGB_8888);
if (empty != null) {
empty.eraseColor(Color.WHITE);
defaultImage = paint(empty);
}
}
return defaultImage;
}
public static interface ImageLoadingListener {
void onImageLoaded(Bitmap image);
}
private final class LoadingTask extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... params) {
try {
return load(false);
} catch (final OutOfMemoryError ex) {
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
onImageLoaded(result);
}
}
}