package com.github.donkirkby.vograbulary.client; import java.util.Arrays; import com.github.donkirkby.vograbulary.russian.Controller; import com.github.donkirkby.vograbulary.russian.Puzzle; import com.github.donkirkby.vograbulary.russian.PuzzleDisplay; import com.github.donkirkby.vograbulary.russian.RussianDollsScreen; import com.github.donkirkby.vograbulary.ultraghost.WordList; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.ParagraphElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseMoveEvent; import com.google.gwt.event.dom.client.MouseMoveHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.event.dom.client.MouseUpHandler; import com.google.gwt.event.dom.client.TouchEndEvent; import com.google.gwt.event.dom.client.TouchEndHandler; import com.google.gwt.event.dom.client.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchMoveHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; public class RussianDollsPresenter extends VograbularyPresenter implements RussianDollsScreen { public static final String HISTORY_TOKEN = "russian"; private static final int INSERT_BUTTON_TOP_MARGIN = 4; private PuzzleDisplay puzzleDisplay = new PuzzleDisplay(); private Controller controller = new Controller(); private Dragger dragger; private GwtScheduler scheduler = new GwtScheduler(); interface RussianDollsCompositeUiBinder extends UiBinder<Widget, RussianDollsPresenter> { } @UiField AbsolutePanel insertPanel; @UiField AbsolutePanel targetPanel; @UiField Image insertButton; @UiField ParagraphElement clue; @UiField Image dragButton1; @UiField Image dragButton2; @UiField Button nextButton; @UiField ParagraphElement scoreDisplay; @UiField ParagraphElement totalDisplay; private static RussianDollsCompositeUiBinder uiBinder = GWT.create(RussianDollsCompositeUiBinder.class); private GwtTargetDisplay targetDisplay1; private GwtTargetDisplay targetDisplay2; public RussianDollsPresenter() { initWidget(uiBinder.createAndBindUi(this)); dragger = new Dragger(insertButton); insertButton.addMouseDownHandler(dragger); insertButton.addMouseMoveHandler(dragger); insertButton.addMouseUpHandler(dragger); insertButton.addTouchStartHandler(dragger); insertButton.addTouchMoveHandler(dragger); insertButton.addTouchEndHandler(dragger); targetDisplay1 = new GwtTargetDisplay(insertButton, dragButton1, targetPanel); targetDisplay2 = new GwtTargetDisplay(insertButton, dragButton2, targetPanel); targetDisplay1.setOther(targetDisplay2); targetDisplay1.setDragVisible(false); targetDisplay2.setDragVisible(false); String puzzleText = Assets.INSTANCE.russianDolls().getText(); String wordListText = Assets.INSTANCE.wordList().getText(); WordList wordList = new WordList(); wordList.read(Arrays.asList(wordListText.split("\\n"))); controller.setScreen(this); controller.setWordList(wordList); controller.loadPuzzles(Arrays.asList(puzzleText.split("\\n"))); final int periodMilliseconds = 100; final float periodSeconds = periodMilliseconds / 1000.0f; scheduler.scheduleRepeating( new Runnable() { @Override public void run() { String score = controller.adjustScore(periodSeconds); Puzzle puzzle = puzzleDisplay.getPuzzle(); String total = puzzle.getTotalScoreDisplay(); scoreDisplay.setInnerText("Score: " + score); totalDisplay.setInnerText("Total: " + total); boolean shouldShow = ! targetDisplay1.isDragVisible() && ! targetDisplay2.isDragVisible() && puzzle.getScore().intValue() < 50; if (shouldShow) { targetDisplay1.setDragVisible(true); targetDisplay2.setDragVisible(true); } } }, periodMilliseconds); } @UiHandler("nextButton") void next(ClickEvent e) { Puzzle puzzle = getPuzzle(); if (puzzle.isSolved()) { controller.next(); } else { controller.solve(); if (puzzle.isSolved()) { nextButton.setText("Next"); targetDisplay1.setText(puzzle.getCombination()); targetDisplay2.setText(""); scheduler.scheduleDeferred(new Runnable() { @Override public void run() { targetDisplay1.layout(); } }); } } } private class Dragger implements MouseDownHandler, MouseMoveHandler, MouseUpHandler, TouchStartHandler, TouchMoveHandler, TouchEndHandler { private UIObject target; private int startX; private boolean isDragging; public Dragger(UIObject target) { this.target = target; } @Override public void onMouseDown(MouseDownEvent event) { event.preventDefault(); onStart(event.getClientX()); } @Override public void onTouchStart(TouchStartEvent event) { event.preventDefault(); onStart(event.getTouches().get(0).getClientX()); } private void onStart(int x) { Event.setCapture(target.getElement()); startX = x - insertPanel.getWidgetLeft(insertButton); puzzleDisplay.setTargetPositions( targetDisplay1.getLettersLeft(), targetDisplay1.getLettersWidth(), targetDisplay2.getLettersLeft(), targetDisplay2.getLettersWidth()); isDragging = true; } @Override public void onMouseMove(MouseMoveEvent event) { onMove(event.getClientX()); } @Override public void onTouchMove(TouchMoveEvent event) { onMove(event.getTouches().get(0).getClientX()); } private void onMove(int x) { if (isDragging) { insertPanel.setWidgetPosition( insertButton, x - startX, INSERT_BUTTON_TOP_MARGIN); int insertX = insertPanel.getWidgetLeft(insertButton) + insertButton.getOffsetWidth() * 24/64; puzzleDisplay.calculateInsertion(insertX); } } @Override public void onMouseUp(MouseUpEvent event) { onStop(); } @Override public void onTouchEnd(TouchEndEvent event) { onStop(); } private void onStop() { Event.releaseCapture(target.getElement()); isDragging = false; } } @Override public Puzzle getPuzzle() { return puzzleDisplay.getPuzzle(); } @Override public void setPuzzle(Puzzle puzzle) { clue.setInnerText(puzzle.getClue()); targetDisplay1.setPuzzle(puzzle); nextButton.setText("Solve"); puzzleDisplay.setPuzzle(puzzle); scheduler.scheduleDeferred(new Runnable() { @Override public void run() { targetDisplay1.setScreenWidth(targetPanel.getOffsetWidth()); targetDisplay1.layout(); insertPanel.setWidgetPosition( insertButton, targetDisplay1.getLettersRight(), INSERT_BUTTON_TOP_MARGIN); } }); } }