package org.ebookdroid.core;
import org.ebookdroid.common.bitmaps.GLBitmaps;
import org.ebookdroid.common.bitmaps.ByteBufferManager;
import android.graphics.RectF;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.emdev.common.log.LogContext;
import org.emdev.common.log.LogManager;
public abstract class AbstractEvent implements IEvent {
public final LogContext LCTX = LogManager.root().lctx(getClass().getSimpleName(), false);
protected final List<PageTreeNode> nodesToDecode = new ArrayList<PageTreeNode>();
protected final List<GLBitmaps> bitmapsToRecycle = new ArrayList<GLBitmaps>();
public AbstractViewController ctrl;
protected ViewState viewState;
protected AbstractEvent() {
}
/**
* {@inheritDoc}
*
* @see org.ebookdroid.core.IEvent#process()
*/
@Override
public ViewState process() {
calculatePageVisibility();
ctrl.firstVisiblePage = viewState.pages.firstVisible;
ctrl.lastVisiblePage = viewState.pages.lastVisible;
for (final Page page : ctrl.model.getPages()) {
process(page);
}
ByteBufferManager.release(bitmapsToRecycle);
if (!nodesToDecode.isEmpty()) {
ctrl.base.getDecodingProgressModel().increase(nodesToDecode.size());
decodePageTreeNodes(viewState, nodesToDecode);
if (LCTX.isDebugEnabled()) {
LCTX.d(viewState + " => " + nodesToDecode.size());
}
}
return viewState;
}
/**
* {@inheritDoc}
*
* @see org.ebookdroid.core.IEvent#process(org.ebookdroid.core.ViewState, org.ebookdroid.core.Page)
*/
@Override
public final boolean process(final Page page) {
if (page.recycled) {
return false;
}
if (viewState.isPageKeptInMemory(page) || viewState.isPageVisible(page)) {
return process(page.nodes);
}
recyclePage(viewState, page);
return false;
}
/**
* {@inheritDoc}
*
* @see org.ebookdroid.core.IEvent#process(org.ebookdroid.core.ViewState, org.ebookdroid.core.PageTree,
* org.ebookdroid.core.PageTreeLevel)
*/
@Override
public boolean process(final PageTree nodes, final PageTreeLevel level) {
return nodes.process(this, level, true);
}
protected void calculatePageVisibility() {
int firstVisiblePage = -1;
int lastVisiblePage = -1;
final RectF bounds = new RectF();
for (final Page page : ctrl.model.getPages()) {
if (ctrl.isPageVisible(page, viewState, bounds)) {
if (firstVisiblePage == -1) {
firstVisiblePage = page.index.viewIndex;
}
lastVisiblePage = page.index.viewIndex;
} else if (firstVisiblePage != -1) {
break;
}
}
viewState.update(firstVisiblePage, lastVisiblePage);
}
protected final void decodePageTreeNodes(final ViewState viewState, final List<PageTreeNode> nodesToDecode) {
final PageTreeNode best = Collections.min(nodesToDecode, new PageTreeNodeComparator(viewState));
final DecodeService ds = ctrl.getBase().getDecodeService();
if (ds != null) {
ds.decodePage(viewState, best);
for (final PageTreeNode node : nodesToDecode) {
if (node != best) {
ds.decodePage(viewState, node);
}
}
}
}
protected final void recyclePage(final ViewState viewState, final Page page) {
final int oldSize = bitmapsToRecycle.size();
final boolean res = page.nodes.recycleAll(bitmapsToRecycle, true);
if (res) {
if (LCTX.isDebugEnabled()) {
LCTX.d("Recycle page " + page.index + " " + viewState.pages + " = " + (bitmapsToRecycle.size() - oldSize));
}
}
}
}