/*
* Orion Viewer - pdf, djvu, xps and cbz file viewer for android devices
*
* Copyright (C) 2011-2013 Michael Bogdanov & Co
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
package universe.constellation.orion.viewer;
import android.graphics.Point;
import universe.constellation.orion.viewer.document.DocumentWithCaching;
import universe.constellation.orion.viewer.outline.OutlineItem;
import universe.constellation.orion.viewer.prefs.GlobalOptions;
import universe.constellation.orion.viewer.util.ColorUtil;
import universe.constellation.orion.viewer.view.Renderer;
import universe.constellation.orion.viewer.view.ViewDimensionAware;
/**
* User: mike
* Date: 15.10.11
* Time: 18:48
*/
public class Controller implements ViewDimensionAware {
private LayoutPosition layoutInfo;
private DocumentWrapper doc;
private LayoutStrategy layout;
private OrionViewerActivity activity;
private Renderer renderer;
private int lastPage = -1;
private DocumentViewAdapter listener;
private String screenOrientation;
private Point lastScreenSize;
private int contrast;
private int threshold;
private boolean hasPendingEvents = false;
public Controller(OrionViewerActivity activity, DocumentWrapper doc, LayoutStrategy layout, Renderer renderer) {
Common.d("Creating controller...");
this.activity = activity;
this.doc = doc;
this.layout = layout;
this.renderer = renderer;
renderer.startRenreder();
listener = new DocumentViewAdapter() {
public void viewParametersChanged() {
if (Controller.this.activity.isResumed) {
Controller.this.renderer.invalidateCache();
drawPage(layoutInfo);
hasPendingEvents = false;
} else {
hasPendingEvents = true;
}
}
};
//activity.getOrionContext().getOptions().subscribe(prefListener);
activity.getSubscriptionManager().addDocListeners(listener);
Common.d("Controller was created successfully");
}
public void drawPage(int page) {
layout.reset(layoutInfo, page);
drawPage(layoutInfo);
}
public void drawPage() {
drawPage(layoutInfo);
}
public void drawPage(LayoutPosition info) {
layoutInfo = info;
sendPageChangedNotification();
renderer.render(info);
}
public void processPendingEvents() {
if (hasPendingEvents) {
Common.d("Processing pending updates...");
sendViewChangeNotification();
}
}
public void onDimensionChanged(int newWidth, int newHeight) {
if (newWidth > 0 && newHeight > 0) {
Common.d("New screen size " + newWidth + "x" + newHeight);
layout.setDimension(newWidth, newHeight);
GlobalOptions options = getActivity().getGlobalOptions();
layout.changeOverlapping(options.getHorizontalOverlapping(), options.getVerticalOverlapping());
int offsetX = layoutInfo.x.offset;
int offsetY = layoutInfo.y.offset;
layout.reset(layoutInfo, layoutInfo.pageNumber);
if (lastScreenSize != null) {
if (newWidth == lastScreenSize.x && newHeight == lastScreenSize.y) {
layoutInfo.x.offset = offsetX;
layoutInfo.y.offset = offsetY;
}
lastScreenSize = null;
}
sendViewChangeNotification();
renderer.onResume();
//HACK
activity.myprocessOnActivityVisible();
}
}
public void drawNext() {
layout.nextPage(layoutInfo);
drawPage(layoutInfo);
}
public void drawPrev() {
layout.prevPage(layoutInfo);
drawPage(layoutInfo);
}
public void translateAndZoom(boolean changeZoom, float zoomScaling, float deltaX, float deltaY) {
Common.d("zoomscaling " + changeZoom + " " + zoomScaling + " " + deltaX + " " + deltaY );
int oldOffsetX = layoutInfo.x.offset;
int oldOffsetY = layoutInfo.y.offset;
System.out.println("oldZoom " + layoutInfo.docZoom + " " + layoutInfo.x.offset + " x " + layoutInfo.y.offset);
if (changeZoom) {
layout.changeZoom((int) (10000f * zoomScaling * layoutInfo.docZoom));
layout.reset(layoutInfo, layoutInfo.pageNumber);
}
layoutInfo.x.offset = (int) (zoomScaling * oldOffsetX + deltaX);
layoutInfo.y.offset = (int) (zoomScaling * oldOffsetY + deltaY);
System.out.println("newZoom " + layoutInfo.docZoom + " " + layoutInfo.x.offset + " x " + layoutInfo.y.offset);
sendViewChangeNotification();
}
public void changeZoom(int zoom) {
if (layout.changeZoom(zoom)) {
layout.reset(layoutInfo, layoutInfo.pageNumber);
sendViewChangeNotification();
}
}
public int getZoom10000Factor() {
return layout.getZoom();
}
public double getCurrentPageZoom() {
return layoutInfo.docZoom;
}
public void changeCropMargins(CropMargins cropMargins) {
if (layout.changeCropMargins(cropMargins)) {
layout.reset(layoutInfo, layoutInfo.pageNumber);
if (doc instanceof DocumentWithCaching) {
((DocumentWithCaching) doc).resetCache();
}
sendViewChangeNotification();
}
}
public CropMargins getMargins() {
return layout.getMargins();
}
public void destroy() {
Common.d("Destroying controller...");
activity.getSubscriptionManager().unSubscribe(listener);
//activity.getOrionContext().getOptions().unsubscribe(prefListener);
if (renderer != null) {
renderer.stopRenderer();
renderer = null;
}
if (doc != null) {
doc.destroy();
doc = null;
}
System.gc();
}
// public void onResume() {
// Common.d("Controller onResume" + view.getWidth() + "x" + view.getHeight());
// int oldX = layoutInfo.cellX;
// int oldY = layoutInfo.cellY;
// layout.setDimension(view.getWidth(), view.getHeight());
// layout.reset(layoutInfo, layoutInfo.pageNumber);
//
// //reset position on changing screen size
// if (lastScreenSize.x == view.getWidth() && lastScreenSize.y == view.getHeight()) {
// layoutInfo.cellX = oldX;
// layoutInfo.cellY = oldY;
// }
// drawPage();
// renderer.onResume();
// renderer.start();
// }
public void onPause() {
renderer.onPause();
}
public void setRotation(int rotation) {
if (layout.changeRotation(rotation)) {
layout.reset(layoutInfo, layoutInfo.pageNumber);
sendViewChangeNotification();
}
}
public void changeOverlap(int horizontal, int vertical) {
if (layout.changeOverlapping(horizontal, vertical)) {
layout.reset(layoutInfo, layoutInfo.pageNumber);
sendViewChangeNotification();
}
}
public int getRotation() {
return layout.getRotation();
}
public int getCurrentPage() {
return layoutInfo.pageNumber;
}
public int getPageCount() {
return doc.getPageCount();
}
public void init(LastPageInfo info, Point dimension) {
int width = dimension.x;
int height = dimension.y;
Common.d("Init controller...");
doc.setContrast(info.contrast);
doc.setThreshold(info.threshold);
layout.init(info, getActivity().getGlobalOptions());
layoutInfo = new LayoutPosition();
layout.reset(layoutInfo, info.pageNumber);
layoutInfo.x.offset = info.newOffsetX;
layoutInfo.y.offset = info.newOffsetY;
lastScreenSize = new Point(info.screenWidth, info.screenHeight);
screenOrientation = info.screenOrientation;
changeOrinatation(screenOrientation);
changeColorMode(info.colorMode, false);
onDimensionChanged(width, height);
Common.d("Controller inited");
}
public void serialize(LastPageInfo info) {
layout.serialize(info);
info.newOffsetX = layoutInfo.x.offset;
info.newOffsetY = layoutInfo.y.offset;
info.pageNumber = layoutInfo.pageNumber;
info.screenOrientation = screenOrientation;
}
public void sendViewChangeNotification() {
activity.getSubscriptionManager().sendViewChangeNotification();
}
public void sendPageChangedNotification() {
if (lastPage != layoutInfo.pageNumber) {
lastPage = layoutInfo.pageNumber;
activity.getSubscriptionManager().sendPageChangedNotification(lastPage, doc.getPageCount());
}
}
public String getDirection() {
return layout.getWalkOrder();
}
public int getLayout() {
return layout.getLayout();
}
public void setDirectionAndLayout(String walkOrder, int pageLayout) {
if (layout.changeNavigation(walkOrder) | layout.changePageLayout(pageLayout)) {
sendViewChangeNotification();
}
}
public void changetWalkOrder(String walkOrder) {
if (layout.changeNavigation(walkOrder)) {
sendViewChangeNotification();
}
}
public void changetPageLayout(int pageLayout) {
if (layout.changePageLayout(pageLayout)) {
sendViewChangeNotification();
}
}
public void changeContrast(int contrast) {
if (this.contrast != contrast) {
this.contrast = contrast;
doc.setContrast(contrast);
sendViewChangeNotification();
}
}
public void changeThreshhold(int threshold) {
if (this.threshold != threshold) {
this.threshold = threshold;
doc.setThreshold(threshold);
sendViewChangeNotification();
}
}
public OrionViewerActivity getActivity() {
return activity;
}
public boolean isEvenPage() {
//zero based
return (getCurrentPage() + 1) % 2 == 0;
}
public void changeOrinatation(String orientationId) {
screenOrientation = orientationId;
System.out.println("New orientation " + screenOrientation);
String realOrintationId = orientationId;
if ("DEFAULT".equals(orientationId)) {
realOrintationId = activity.getApplicationDefaultOrientation();
}
activity.changeOrientation(activity.getScreenOrientation(realOrintationId));
}
public void changeColorMode(String colorMode, boolean invalidate) {
activity.getFullScene().setColorMatrix(ColorUtil.getColorMode(colorMode));
if (invalidate) {
activity.getView().invalidate();
}
}
public OutlineItem[] getOutline() {
return doc.getOutline();
}
public String getScreenOrientation() {
return screenOrientation;
}
public String selectText(int startX, int startY, int widht, int height, boolean isSingleWord) {
Point leftTopCorner = layout.convertToPoint(layoutInfo);
if (widht < 0) {
startX += widht;
widht = -widht;
}
if (height < 0) {
startY += height;
height = - height;
}
String text = doc.getText(
layoutInfo.pageNumber,
(int) ((leftTopCorner.x + startX) / layoutInfo.docZoom),
(int) ((leftTopCorner.y +startY) / layoutInfo.docZoom),
(int) (widht / layoutInfo.docZoom),
(int) (height / layoutInfo.docZoom),
isSingleWord
);
if (text != null) {
text = text.trim();
}
return text;
}
public boolean needPassword() {
return doc.needPassword();
}
public boolean authentificate(String password) {
boolean result = doc.authentificate(password);
if (result) {
sendViewChangeNotification();
}
return result;
}
public DocumentWrapper getDocument() {
return doc;
}
public LayoutStrategy getLayoutStrategy() {
return layout;
}
}