package kornell.gui.client.sequence; import java.util.logging.Logger; import com.google.gwt.user.client.ui.FlowPanel; import com.google.web.bindery.event.shared.EventBus; import kornell.api.client.KornellSession; import kornell.core.lom.Actom; import kornell.core.lom.Contents; import kornell.core.lom.ContentsOps; import kornell.gui.client.event.ProgressEvent; import kornell.gui.client.event.ViewReadyEvent; import kornell.gui.client.event.ViewReadyEventHandler; import kornell.gui.client.presentation.classroom.ClassroomPlace; import kornell.gui.client.uidget.Uidget; public class PrefetchSequencer extends SimpleSequencer implements Sequencer { Logger logger = Logger.getLogger(PrefetchSequencer.class.getName()); private FlowPanel contentPanel; private String enrollmentUUID; private Actom nextActom; private Uidget nextUidget; private Uidget currentUidget; private Actom prevActom; private Uidget prevUidget; private boolean isActive; public PrefetchSequencer(EventBus bus, KornellSession session) { super(bus,session); } @Override public void onContinue(NavigationRequest event) { if (!isActive || doesntHaveNext()) return; removePrevious(); makeCurrentPrevious(); makeNextCurrent(); currentIndex++; preloadNext(); makeCurrentVisible(); dropBreadcrumb(); debug("CONTINUED"); } @Override public void onPrevious(NavigationRequest event) { if (!isActive || doesntHavePrevious()) return; removeNext(); makeCurrentNext(); makePrevCurrent(); currentIndex--; preloadPrevious(); makeCurrentVisible(); dropBreadcrumb(); debug("PREVED"); } @Override public void onDirect(NavigationRequest event){ if(isActive){ stop(); orientateAndSail(event.getDestination()); } } private void debug(String event) { String prevString = prevKey() + prevVis(); String currString = currentKey() + currVis(); String nextString = nextKey() + nextVis(); logger.finer(event + " " + currentIndex + " [" + prevString + " | " + currString + " | " + nextString + "]"); } private String nextVis() { return " " + (nextUidget != null ? nextUidget.isVisible() : "-"); } private String currVis() { return " " + (currentUidget != null ? currentUidget.isVisible() : "-"); } private String prevVis() { return " " + (prevUidget != null ? prevUidget.isVisible() : "-"); } private String prevKey() { return prevActom != null ? prevActom.getKey() : ""; } private String nextKey() { return nextActom != null ? nextActom.getKey() : ""; } private boolean doesntHaveNext() { return actoms != null && currentIndex >= actoms.size() - 1; } private boolean doesntHavePrevious() { return actoms != null && currentIndex <= 0; } private void makeCurrentPrevious() { prevActom = currentActom; prevUidget = currentUidget; } private void makeNextCurrent() { currentActom = nextActom; currentUidget = nextUidget; } private void makeCurrentVisible() { if (currentUidget != null) currentUidget.setVisible(true); else logger.warning("CURRENT UIDGET IS NULL. HOW COME?"); if (nextUidget != null) nextUidget.setVisible(false); if (prevUidget != null) prevUidget.setVisible(false); } private void makeCurrentNext() { nextUidget = currentUidget; nextActom = currentActom; } private void removePrevious() { if(prevUidget != null) contentPanel.remove(prevUidget); prevUidget = null; prevActom = null; } private void removeNext() { if(nextUidget != null) contentPanel.remove(nextUidget); nextUidget = null; nextActom = null; } private void removeCurrent() { if(currentUidget != null) contentPanel.remove(currentUidget); currentUidget = null; currentActom = null; } private void makePrevCurrent() { currentActom = prevActom; currentUidget = prevUidget; } @Override public Sequencer withPanel(FlowPanel contentPanel) { this.contentPanel = contentPanel; return this; } @Override public Sequencer withPlace(ClassroomPlace place) { setEnrollmentUUID(place.getEnrollmentUUID()); return this; } @Override public void go(Contents contents) { setContents(contents); orientateAndSail(); } private void orientateAndSail() { orientateAndSail(session.getItem(getBreadcrumbKey())); } private void orientateAndSail(String key) { currentIndex = lookupCurrentIndex(key); currentActom = actoms.get(currentIndex); initialLoad(); } class ShowWhenReady implements ViewReadyEventHandler { private Uidget uidget; public ShowWhenReady(Uidget uidget) { this.uidget = uidget; } @Override public void onViewReady(ViewReadyEvent evt) { uidget.setVisible(true); } } private void initialLoad() { isActive = true; showCurrentASAP(); preloadNext(); preloadPrevious(); makeCurrentVisible(); debug("INITIAL"); } private void preloadNext() { if (!isActive || doesntHaveNext()) { nextActom = null; nextUidget = null; } else { int nextIndex = currentIndex + 1; nextActom = actoms.get(nextIndex); nextUidget = Uidget.forActom(nextActom); contentPanel.add(nextUidget); } } private void preloadPrevious() { if (!isActive || doesntHavePrevious()) { prevActom = null; prevUidget = null; } else { int previousIndex = currentIndex - 1; prevActom = actoms.get(previousIndex); prevUidget = Uidget.forActom(prevActom); contentPanel.add(prevUidget); } } private void showCurrentASAP() { if (!isActive) { currentActom = null; currentUidget = null; } else { currentUidget = Uidget.forActom(currentActom); currentUidget.setVisible(false); currentUidget.onViewReady(new ShowWhenReady(currentUidget)); contentPanel.add(currentUidget); dropBreadcrumb(); makeCurrentVisible(); } } private void setContents(Contents contents) { this.actoms = ContentsOps.collectActoms(contents); } //TODO: Smells... progress acct may be different per ContentSpec @Override public void fireProgressEvent() { if(actoms == null) return; int pagesVisitedCount = 0; int totalPages = actoms.size(); for (Actom actom : actoms) { if (actom.isVisited()) { pagesVisitedCount++; continue; } break; } ProgressEvent progressEvent = new ProgressEvent(); progressEvent.setCurrentPage(currentIndex + 1); progressEvent.setTotalPages(totalPages); progressEvent.setPagesVisitedCount(pagesVisitedCount); progressEvent.setEnrollmentUUID(enrollmentUUID); bus.fireEvent(progressEvent); } @Override public void stop() { isActive = false; removeCurrent(); removeNext(); removePrevious(); contentPanel.clear(); } }