/******************************************************************************* * Copyright 2011 Antti Havanko * * This file is part of Motiver.fi. * Motiver.fi is licensed under one open source license and one commercial license. * * Commercial license: This is the appropriate option if you want to use Motiver.fi in * commercial purposes. Contact license@motiver.fi for licensing options. * * Open source license: This is the appropriate option if you are creating an open source * application with a license compatible with the GNU GPL license v3. Although the GPLv3 has * many terms, the most important is that you must provide the source code of your application * to your users so they can be free to modify your application for their own needs. ******************************************************************************/ package com.delect.motiver.client.presenter.nutrition; import java.util.ArrayList; import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.http.client.Request; import com.google.gwt.user.client.Window; import com.delect.motiver.client.AppController; import com.delect.motiver.client.Motiver; import com.delect.motiver.client.MyAsyncCallback; import com.delect.motiver.client.event.MealCreatedEvent; import com.delect.motiver.client.event.MealRemovedEvent; import com.delect.motiver.client.event.MealSelectedEvent; import com.delect.motiver.client.event.MealShowEvent; import com.delect.motiver.client.event.MealsSelectCancelledEvent; import com.delect.motiver.client.event.UserSelectedEvent; import com.delect.motiver.client.event.handler.MealCreatedEventHandler; import com.delect.motiver.client.event.handler.MealRemovedEventHandler; import com.delect.motiver.client.event.handler.MealSelectedEventHandler; import com.delect.motiver.client.event.handler.MealShowEventHandler; import com.delect.motiver.client.event.handler.UserSelectedEventHandler; import com.delect.motiver.client.presenter.Presenter; import com.delect.motiver.client.presenter.nutrition.MealPresenter.MealDisplay; import com.delect.motiver.client.presenter.nutrition.MealsListSearchPresenter.MealsListSearchDisplay; import com.delect.motiver.client.presenter.nutrition.MealsListSubPresenter.MealsListSubDisplay; import com.delect.motiver.client.service.MyServiceAsync; import com.delect.motiver.client.view.Display; import com.delect.motiver.client.view.nutrition.MealView; import com.delect.motiver.client.view.nutrition.MealsListSearchView; import com.delect.motiver.client.view.nutrition.MealsListSubView; import com.delect.motiver.shared.MealModel; import com.delect.motiver.shared.TimeModel; import com.extjs.gxt.ui.client.widget.LayoutContainer; /** * 3 "pages": (with search box on top) * <br>- main page (shows user's meals, most popular) * <br>- search results * <br>- single meal (when individual meal is selected) * <br>- Fires meal created event when meal is selected and stops itself * @author Antti * */ public class MealsListPresenter extends Presenter { /** * Abstract class for view to extend */ public abstract static class MealsListDisplay extends Display { public abstract LayoutContainer getDataContainer(); public abstract void setBackButtonVisible(boolean b); public abstract void setCancelButtonVisible(boolean b); public abstract void setCopyButtonVisible(boolean b); public abstract void setHandler(MealsListHandler mealsListHandler); public abstract void setMoveToTimeButtonVisible(boolean visible, TimeModel time); public abstract void setQuickSelectionButtonVisible(boolean visible, TimeModel time); } public interface MealsListHandler { void onBackButtonClicked(); void onCancelButtonClicked(); void onCopyButtonClicked(); void onMoveToTimeButtonClicked(); void onQuickSelectionButtonClicked(); void search(String query); } private MealsListDisplay display; private String lastQuery = ""; private int lastView = 0; private long mealId = 0; private MealsListSearchPresenter mealsListSearchPresenter; //child presenters private MealsListSubPresenter mealsListSubPresenter; private List<MealModel> quickSelectionMeals = new ArrayList<MealModel>(); //meals which are selected private MealPresenter singleMealPresenter; private TimeModel time; /** * * @param rpcService * @param eventBus * @param display * @param date * @param mealId : if some meal is open as default */ public MealsListPresenter(MyServiceAsync rpcService, SimpleEventBus eventBus, MealsListDisplay display, TimeModel time, long mealId) { super(rpcService, eventBus); this.display = display; this.time = time; this.mealId = mealId; boolean quickSelectionEnabled = (time != null); mealsListSubPresenter = new MealsListSubPresenter(rpcService, eventBus, (MealsListSubDisplay)GWT.create(MealsListSubView.class), quickSelectionEnabled); } @Override public Display getView() { return display; } @Override public void onBind() { display.setHandler(new MealsListHandler() { @Override public void onBackButtonClicked() { //coming back from search results if(singleMealPresenter == null) { showMainView(); } //if coming back from single exercise else { //unbind meal singleMealPresenter.stop(); singleMealPresenter = null; //last view was search results if(lastView == 1) { loadSearch(lastQuery); } //last view was main menu else { showMainView(); } } } @Override public void onCancelButtonClicked() { //unbind this stop(); //fire cancel event eventBus.fireEvent(new MealsSelectCancelledEvent(time)); } @Override public void onCopyButtonClicked() { copyMeals(); } @Override public void onMoveToTimeButtonClicked() { //get meal from single presenter List<MealModel> meals = new ArrayList<MealModel>(); meals.add(singleMealPresenter.meal); moveMealToTime(meals); } @Override public void onQuickSelectionButtonClicked() { //get meals from quick selection moveMealToTime(quickSelectionMeals); quickSelectionMeals.clear(); } @Override public void search(String query) { loadSearch(query); } }); //EVENT: meal created -> open meal addEventHandler(MealCreatedEvent.TYPE, new MealCreatedEventHandler() { @Override public void onMealCreated(MealCreatedEvent event) { //if no date if(event.getMeal() != null) { if(event.getMeal().getTimeId() == 0) { showSingleMeal(event.getMeal()); } } } }); //EVENT: meal removed -> show main view addEventHandler(MealRemovedEvent.TYPE, new MealRemovedEventHandler() { @Override public void onMealRemoved(MealRemovedEvent event) { //if meal in list if(event.getMeal() != null && event.getMeal().getTimeId() == 0) { showMainView(); } } }); //EVENT: show meal addEventHandler(MealShowEvent.TYPE, new MealShowEventHandler() { @Override public void selectMeal(MealShowEvent event) { showSingleMeal(event.getMeal()); } }); //EVENT: meal selected (quick select) addEventHandler(MealSelectedEvent.TYPE, new MealSelectedEventHandler() { @Override public void mealSelected(MealSelectedEvent event) { setQuickSelection(event.getMeal(), event.isSelected()); } }); //EVENT: user selected -> show blog addEventHandler(UserSelectedEvent.TYPE, new UserSelectedEventHandler() { @Override public void userSelected(UserSelectedEvent event) { //open blog in new window Window.open(event.getUser().getBlogUrl(), "_blank", "status=1,toolbar=1,location=1,menubar=1,directories=1,resizable=1,scrollbars=1"); } }); //if date -> show inner title if(time != null) { //info text display.setTitle(AppController.Lang.SelectMeal()); display.setCancelButtonVisible(true); } } @Override public void onRefresh() { super.onRefresh(); //highlight and scroll highlight(); } @Override public void onRun() { //show single meal if(mealId != 0) { final Request req = rpcService.getMeal(mealId, new MyAsyncCallback<MealModel>() { @Override public void onSuccess(MealModel result) { showSingleMeal(result); } }); addRequest(req); } else { showMainView(); } //highlight and scroll highlight(); } @Override public void onStop() { if(mealsListSubPresenter != null) { mealsListSubPresenter.stop(); } if(singleMealPresenter != null) { singleMealPresenter.stop(); } if(mealsListSearchPresenter != null) { mealsListSearchPresenter.stop(); } } /** * Copies meal to our meals */ protected void copyMeals() { try { display.setContentEnabled(false); //get meal from single presenter MealModel model = singleMealPresenter.meal; //reset dates model.setDate(null); //add meal final Request req = rpcService.addMeal(model, 0L, new MyAsyncCallback<MealModel>() { @Override public void onSuccess(MealModel result) { display.setContentEnabled(true); //fire events eventBus.fireEvent(new MealCreatedEvent(result)); } }); addRequest(req); } catch (Exception e) { Motiver.showException(e); } } /** * Moves meal to date */ protected void moveMealToTime(List<MealModel> meals) { try { display.setContentEnabled(false); for(MealModel model : meals) model.setTimeId(time.getId()); //add meal final Request req = rpcService.addMeals(meals, time.getId(), new MyAsyncCallback<List<MealModel>>() { @Override public void onSuccess(List<MealModel> result) { display.setContentEnabled(true); List<MealModel> meals = result; //fire event for(MealModel meal : meals) { meal.setTimeId(time.getId()); eventBus.fireEvent(new MealCreatedEvent(meal)); } } }); addRequest(req); } catch (Exception e) { Motiver.showException(e); } } /** * Called when meals is selected (or selection is set off) * <br>Shows button to quick select meals * @param meal * @param selected */ protected void setQuickSelection(MealModel meal, boolean selected) { //if new meal if(selected) { quickSelectionMeals.add(meal); } else { quickSelectionMeals.remove(meal); } //only if models selected and time not null display.setQuickSelectionButtonVisible(quickSelectionMeals.size() > 0 && time != null, time); } /** * Shows main view * - my meals * - most popular */ protected void showMainView() { lastView = 0; //show/hide buttons display.setBackButtonVisible(false); display.setCopyButtonVisible(false); display.setMoveToTimeButtonVisible(false, null); display.setQuickSelectionButtonVisible(false, null); if(singleMealPresenter != null) { singleMealPresenter.stop(); } singleMealPresenter = null; if(mealsListSearchPresenter != null) { mealsListSearchPresenter.hide(); } //run main view mealsListSubPresenter.run(display.getDataContainer()); } /* * VIEW 3 (single meal */ protected void showSingleMeal(MealModel m) { try { if(singleMealPresenter != null) { singleMealPresenter.stop(); } //hide main page if(mealsListSubPresenter != null) { mealsListSubPresenter.hide(); } if(mealsListSearchPresenter != null) { mealsListSearchPresenter.hide(); } //show single meal singleMealPresenter = new MealPresenter(rpcService, eventBus, (MealDisplay)GWT.create(MealView.class), m); singleMealPresenter.run(display.getDataContainer()); //buttons display.setBackButtonVisible(true); display.setCopyButtonVisible(false); display.setMoveToTimeButtonVisible(false, null); display.setQuickSelectionButtonVisible(false, null); //show buttons only if meal's id set if(m.getId() > 0) { //if date set if(time != null) { display.setMoveToTimeButtonVisible(true, time); } else { //copy to our meals if(!m.getUser().getUid().equals(AppController.User.getUid())) { display.setCopyButtonVisible(true); } } } } catch (Exception e) { Motiver.showException(e); } } /** * Loads meals */ void loadSearch(final String query) { lastView = 1; //show/hide buttons display.setBackButtonVisible(true); display.setCopyButtonVisible(false); display.setMoveToTimeButtonVisible(false, null); display.setQuickSelectionButtonVisible(false, null); if(singleMealPresenter != null) { singleMealPresenter.stop(); } singleMealPresenter = null; if(mealsListSubPresenter != null) { mealsListSubPresenter.hide(); } //if not already loaded if(mealsListSearchPresenter == null || !query.equals(lastQuery)) { lastQuery = query; if(mealsListSearchPresenter != null) { mealsListSearchPresenter.stop(); } boolean quickSelectionEnabled = (time != null); mealsListSearchPresenter = new MealsListSearchPresenter(rpcService, eventBus, (MealsListSearchDisplay)GWT.create(MealsListSearchView.class), query, quickSelectionEnabled); mealsListSearchPresenter.run(display.getDataContainer()); } else { mealsListSearchPresenter.run(display.getDataContainer()); } } }