package com.iambookmaster.client.iphone;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ErrorEvent;
import com.google.gwt.event.dom.client.ErrorHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.iambookmaster.client.common.AbsolutePanelSpan;
import com.iambookmaster.client.iphone.common.IPhoneScrollPanel;
import com.iambookmaster.client.iphone.common.IPhoneTouchProvider;
import com.iambookmaster.client.iphone.data.IPhoneDataService;
import com.iambookmaster.client.iphone.images.IPhoneImages;
import com.iambookmaster.client.iphone.images.IPhoneStyles;
import com.iambookmaster.client.model.Model;
import com.iambookmaster.client.player.PlayerState;
public class IPhoneViewerBook implements EntryPoint {
static final IPhoneStyles css = IPhoneImages.INSTANCE.css();
// private static final IPhoneTouchSimulator simulator = GWT.create(IPhoneTouchSimulator.class);
private static final int BUTTON_SIZE = 40;
private static final int BUTTON_SPACE = 50;
static final String BUTTON_SIZE_PX = toPixels(BUTTON_SIZE);
static final String BUTTON_SPACE_PX = toPixels(BUTTON_SPACE);
protected static final int CANVAS_TOP = 10;
private static final int MIN_FONT_SIZE = 8;
private static final int MAX_FONT_SIZE = 30;
private AbsolutePanel canvas;
private IPhoneScrollPanel scrollPanel;
private FlowPanel mainPanel;
private IPhoneCanvasImpl viewCanvas;
// private Panel rootPanel;
private Widget background;
private Image mainImage;
private LoadHandler verticalMainImageHandler;
boolean verticalOrientation;
private IPhoneViewListener listener;
private int xCorrection;
private AbsolutePanel layout;
private int clientWidth;
private int clientHight;
private Timer animation;
private boolean loadHandlerStarted;
// protected boolean pageOrientation;
private ErrorHandler verticalMainImageErrprHandler;
private IPhonePlayer player;
private HandlerRegistration resizeRegistration;
private int fontSize;
public AbsolutePanel getLayout() {
return layout;
}
public void onModuleLoad() {
load();
}
public void load() {
RootPanel rootPanel = RootPanel.get();
rootPanel.setSize("100%", "100%");
// IPhoneTouchListener phoneTouchListener = new IPhoneTouchListener() {
// @Override
// public boolean event(JavaScriptObject source, String name, int[] x, int[] y, JavaScriptObject target) {
// return superEvent(source, name, x, y, target);
// }
// };
// phoneTouchListener.addListener(rootPanel.getElement(),IPhoneTouchListener.TOUCHSTART,false);
// phoneTouchListener.addListener(rootPanel.getElement(),IPhoneTouchListener.TOUCHMOVE,false);
if (GWT.isScript()) {
GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler(){
public void onUncaughtException(Throwable e) {
IPhoneConsole.showError(e);
}
});
}
load(true);
rootPanel.add(layout);
}
public void init() {
load(false);
}
private void load(boolean showIntro) {
css.ensureInjected();
resizeRegistration = Window.addResizeHandler(new ResizeHandler(){
public void onResize(ResizeEvent event) {
IPhoneViewerBook.this.onResize();
}
});
layout = new AbsolutePanel();
layout.setSize("100%", "100%");
layout.getElement().getStyle().setBackgroundColor("#474541");
initialize(showIntro);
}
private void initialize(boolean showIntro) {
initScrollPanel();
layout.add(scrollPanel,10,10);
initListeners();
verticalOrientation = !getOrientaton();
onResize();
if (showIntro) {
loadPlayer();
}
}
public void loadPlayer(Model model,IPhoneDataService dataService,IPhonePlayerListener listener) {
redrawScreen();
player = new IPhonePlayer(viewCanvas,model,dataService,listener) {
@Override
protected void showIntroScreen(boolean hasContinue) {
super.showIntroScreen(hasContinue);
}
};
}
protected void loadPlayer() {
redrawScreen();
//disable overlay
player = new IPhonePlayer(viewCanvas);
}
private void initScrollPanel() {
scrollPanel = new IPhoneScrollPanel() {
//
@Override
public void scrollHorizontal(int delta) {
stopAnimation();
if (listener != null) {
if (delta>clientWidth/3) {
//back gesture
cleanEvent();
listener.back();
} else if (delta < clientWidth/-3 ) {
//forward gesture
cleanEvent();
listener.forward();
}
}
}
@Override
public void scrollUp() {
stopAnimation();
super.scrollUp();
}
@Override
public void scrollDown() {
stopAnimation();
super.scrollDown();
}
@Override
protected void makeBigger() {
fontSize = fontSize + 2;
applyFontSize();
}
@Override
protected void makeSmaller() {
fontSize = fontSize - 2;
applyFontSize();
}
@Override
protected void scrollVertical(int delta) {
stopAnimation();
}
};
scrollPanel.setScrollDelay(true);
mainPanel = new FlowPanel();
mainPanel.setWidth("100%");
applyFontSize();
applyOrientation();
scrollPanel.setWidget(mainPanel);
}
protected void applyFontSize() {
if (fontSize<MIN_FONT_SIZE) {
fontSize = MIN_FONT_SIZE;
} else if (fontSize>MAX_FONT_SIZE) {
fontSize = MAX_FONT_SIZE;
}
mainPanel.getElement().getStyle().setFontSize(fontSize, Unit.PX);
}
private void applyOrientation() {
mainPanel.setHeight(toPixels(getClientHeight()-50));
mainPanel.setStyleName(css.mainStyleIPad());
Style style = mainPanel.getElement().getStyle();
/*
column-width: 300px;
-webkit-column-width: 300px;
-moz-column-width: 300px;
column-gap: 20px;
-webkit-column-gap: 20px;
-moz-column-gap: 20px;
*/
int w = (getClientWidth()-206)/2;//1024-840
if (verticalOrientation) {
style.clearProperty("MozColumnWidth");
style.clearProperty("MozColumnGap");
style.clearProperty("ColumnWidth");
style.clearProperty("ColumnGap");
style.clearProperty("WebkitColumnWidth");
style.clearProperty("WebkitColumnGap");
} else {
style.setProperty("MozColumnWidth",toPixels(w));
style.setProperty("MozColumnGap","40px");
style.setProperty("ColumnWidth",toPixels(w));
style.setProperty("ColumnGap","40px");
style.setProperty("WebkitColumnWidth",toPixels(w));
style.setProperty("WebkitColumnGap","40px");
}
style.setFontSize(30, Unit.PX);
}
private void initListeners() {
verticalMainImageErrprHandler = new ErrorHandler() {
public void onError(ErrorEvent event) {
loadHandlerStarted = false;
scrollPanel.setVisible(true);
viewCanvas.performDone();
// scrollPanel.setVisible(true);
}
};
verticalMainImageHandler = new LoadHandler(){
private Command performDoneCanvas = new Command() {
public void execute() {
viewCanvas.performDone();
}
};
public void onLoad(LoadEvent event) {
loadHandlerStarted = false;
int hMax = getClientHeight();
int wMax = getClientWidth();
int max = Math.max(hMax,wMax);
if (verticalOrientation) {
int w = mainImage.getWidth();
int h = mainImage.getHeight();
if (w>=wMax-10) {
xCorrection = 0;
} else {
xCorrection = wMax / 2 - 5 - w / 2;
}
if (h>max) {
h = max;
}
canvas.setHeight(toPixels(h+5));
canvas.setWidth("100%");
canvas.setWidgetPosition(mainImage, xCorrection, 0);
} else {
int w = mainImage.getWidth();
int h = mainImage.getHeight();
if (w>max) {
w = max;
}
canvas.setSize(toPixels(w+5), toPixels(h+5));
}
DeferredCommand.addCommand(performDoneCanvas);
scrollPanel.setVisible(true);
}
};
viewCanvas = new IPhoneCanvasImpl();
}
private void applyPageOrientation(boolean vert) {
int h = getClientHeight();
int w = getClientWidth();
//true - we are on big screen
//TODO iPhone retina support
if (h>w) {
//vertical
if (h==1024 && w==768) {
//iPad, 1 page
checkIfBackgroundIsImage(h,w,false);
return;
} else if (h==480 && w==320) {
//iPhone,
checkIfBackgroundIsImage(h,w,false);
return;
}
//horizontal
} else if (w==1024 && h==768) {
//iPad
checkIfBackgroundIsImage(h,w,true);
return;
} else if (w==480 && h==320) {
//iPhone
checkIfBackgroundIsImage(h,w,false);
return;
}
//unknown device, use flexible design
if ((background instanceof HTML)==false) {
if (background != null) {
layout.remove(background);
}
background = new HTML(IPhoneDataService.getInstance().getBackground());
layout.insert(background,0,0,0);
}
// if (Math.max(h,w)>=800 && Math.min(h,w)>=600) {
// //big screen
// } else {
//
// }
//right page
layout.setWidgetPosition(background, 10-clientWidth, 0);
layout.setWidgetPosition(scrollPanel, 10, 10);
if (vert) {
scrollPanel.setSize(toPixels(clientWidth-25), toPixels(clientHight-20));
background.setSize(toPixels(clientWidth*2-10), toPixels(clientHight));
} else {
background.setSize(toPixels(clientWidth*2-10), toPixels(clientHight));
scrollPanel.setSize(toPixels(clientWidth-25), toPixels(clientHight-20));
}
//TODO 1-2 pages
}
private void checkIfBackgroundIsImage(int height, int width, boolean twoPages) {
String url = new StringBuilder(IPhoneTouchProvider.noImagesPath() ? "b" : "images/b").append(width).append('x').append(height).append(".png").toString();
if (background instanceof Image) {
Image image = (Image) background;
if (image.getUrl().endsWith(url)==false) {
image.setUrl(url);
}
} else {
if (background != null) {
layout.remove(background);
}
background = new Image(url);
layout.insert(background, 0, 0, 0);
}
if (height>width) {
layout.setWidgetPosition(scrollPanel, 25, 20);
scrollPanel.setSize(toPixels(clientWidth-70), toPixels(clientHight-30));
} else {
layout.setWidgetPosition(scrollPanel, 30, 30);
scrollPanel.setSize(toPixels(clientWidth-50), toPixels(clientHight-40));
}
}
public void onResize() {
stopAnimation();
viewCanvas.cancelAnimation();
boolean vert = getOrientaton();
clientWidth = getClientWidth();
clientHight = getClientHeight();
applyPageOrientation(vert);
if (vert != verticalOrientation) {
redrawScreen();
}
}
private void stopAnimation() {
if (animation != null) {
animation.cancel();
animation = null;
}
}
private void redrawScreen() {
verticalOrientation = getOrientaton();
mainPanel.clear();
applyOrientation();
initCanvas();
if (listener != null) {
listener.redraw(viewCanvas);
}
scrollPanel.resetPosition();
}
private void initCanvas() {
canvas = verticalOrientation ? new AbsolutePanel() : new AbsolutePanelSpan();
if (verticalOrientation) {
canvas.setStyleName(css.canvasVertical());
} else {
canvas.setStyleName(css.canvasHorizontal());
}
mainPanel.add(canvas);
}
public static String toPixels(int size) {
return String.valueOf(size)+"px";
}
private boolean getOrientaton() {
return getClientHeight()>getClientWidth();
}
protected int getClientWidth() {
return Window.getClientWidth();
}
protected int getClientHeight() {
return Window.getClientHeight();
}
public class IPhoneCanvasImpl implements IPhoneCanvas {
private IPhoneScrollPanel oldScrollPanel;
private boolean leftToRight;
private int startPosition;
private int endPosition;
private boolean firstCancel;
private Command checkScrolling = new Command() {
public void execute() {
if (scrollPanel.isBottomArrow()) {
//TODO
// scrollAnimation = new IPhoneScrollAnimation(scrollPanel);
}
}
};
public void add(Widget widget) {
mainPanel.add(widget);
}
private void cancelAnimation() {
oldScrollPanel = null;
}
public void addSprite(String url, int x, int y) {
checkImage(true);
}
public void addSprite(ImageResource resource, int x, int y) {
checkImage(true);
}
public void clearWithAnimation(boolean l2r) {
stopAnimation();
if (oldScrollPanel != null && layout.getWidgetIndex(oldScrollPanel)>0) {
layout.remove(oldScrollPanel);
}
oldScrollPanel = scrollPanel;
leftToRight = l2r;
initScrollPanel();
initCanvas();
//set initial size and position
int w = oldScrollPanel.getOffsetWidth();
int h = oldScrollPanel.getOffsetHeight();
scrollPanel.setSize(toPixels(w), toPixels(h));
endPosition = layout.getWidgetLeft(oldScrollPanel);
if (l2r) {
startPosition = endPosition-w;
} else {
startPosition = endPosition+w;
}
layout.add(scrollPanel,startPosition,CANVAS_TOP);
_clear();
}
public void clear() {
stopAnimation();
if (oldScrollPanel != null && layout.getWidgetIndex(oldScrollPanel)>0) {
layout.remove(oldScrollPanel);
}
oldScrollPanel = null;
_clear();
}
private void _clear() {
loadHandlerStarted = false;
scrollPanel.resetHandlers();
int l = mainPanel.getWidgetCount();
//keep just canvas
while (l>1) {
l--;
mainPanel.remove(l);
}
canvas.clear();
canvas.setSize("1px", "1px");
//disable events
scrollPanel.setEventsEnabled(false);
}
public void setImage(String url) {
resetImage();
mainImage.setUrl(url);
}
public void setImage(ImageResource resource) {
resetImage();
mainImage.setResource(resource);
}
private void resetImage() {
checkImage(false);
if (oldScrollPanel != null) {
scrollPanel.setVisible(false);
}
mainImage = new Image();
loadHandlerStarted=true;
mainImage.addLoadHandler(verticalMainImageHandler);
mainImage.addErrorHandler(verticalMainImageErrprHandler);
canvas.add(mainImage, 0, 0);
}
private void checkImage(boolean set) {
if (set) {
} else if (mainPanel.getWidgetCount()>1) {
//not set but some widgets were added
throw new IllegalStateException("Image must be the first");
}
}
public void setListener(IPhoneViewListener listener) {
IPhoneViewerBook.this.listener = listener;
}
private void performDone() {
if (oldScrollPanel != null) {
//animation
animation = new Timer() {
private int offset;
@Override
public void run() {
offset = offset + 100;
int pos;
if (leftToRight) {
pos = offset+startPosition;
if (pos >= endPosition) {
//done
cancel();
return;
}
layout.setWidgetPosition(oldScrollPanel, endPosition+offset, CANVAS_TOP);
} else {
pos = startPosition-offset;
if (pos <= endPosition) {
//done
cancel();
return;
}
layout.setWidgetPosition(oldScrollPanel, endPosition-offset, CANVAS_TOP);
}
layout.setWidgetPosition(scrollPanel, pos, CANVAS_TOP);
}
@Override
public void cancel() {
super.cancel();
if (firstCancel==false) {
layout.setWidgetPosition(scrollPanel, endPosition, CANVAS_TOP);
layout.remove(oldScrollPanel);
animation = null;
performDoneEnd();
}
}
};
//cancel() is fired on scheduleRepeating()
firstCancel = true;
animation.scheduleRepeating(verticalOrientation ? 100:50);
firstCancel = false;
} else {
performDoneEnd();
}
}
private void performDoneEnd() {
//enable events
scrollPanel.setEventsEnabled(true);
listener.drawn();
DeferredCommand.addCommand(checkScrolling);
}
public void done() {
if (loadHandlerStarted==false) {
performDone();
}
}
public void setBackgroundImage(String url) {
}
public void disableAudio() {
// audioDisabled=true;
// if (audioEnabled) {
// listener.audio(false);
// }
// audioEnabled = false;
// audioIcon.setStyleName(css.buttonDisabled());
// applyAudio();
}
public void setAudio(boolean allowAudio) {
// if (audioDisabled==false) {
// audioEnabled = allowAudio;
// applyAudio();
// }
}
public HandlerRegistration addClickHandler(Widget widget, ClickHandler handler) {
return scrollPanel.addClickHandler(widget, handler);
}
public void setPageOrientation(boolean leftPage) {
}
public void changePageOrientation() {
}
public void removeWidget(Widget widget) {
mainPanel.remove(widget);
}
public boolean isVertical() {
return verticalOrientation;
}
public boolean isBottomVisible() {
return scrollPanel.isBottomArrow()==false;
}
public void scrollPageDown() {
DeferredCommand.addCommand(checkScrolling);
}
public int getClientWidth() {
return IPhoneViewerBook.this.getClientWidth();
}
}
public void close() {
resizeRegistration.removeHandler();
}
public IPhonePlayer getPlayer() {
return player;
}
public PlayerState getPlayerState() {
return player.getPlayerState();
}
public void scrollDown() {
scrollPanel.scrollDown();
}
public void scrollUp() {
scrollPanel.scrollUp();
}
public void setStyleName(String style) {
layout.setStyleName(style);
}
}