/******************************************************************************* * 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.Date; 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.Timer; import com.delect.motiver.client.AppController; import com.delect.motiver.client.Motiver; import com.delect.motiver.client.MyAsyncCallback; import com.delect.motiver.client.event.GuideValueCreatedEvent; import com.delect.motiver.client.event.GuideValueRemovedEvent; import com.delect.motiver.client.event.TimeCreatedEvent; import com.delect.motiver.client.event.TimeRemovedEvent; import com.delect.motiver.client.event.TimeUpdatedEvent; import com.delect.motiver.client.event.handler.GuideValueCreatedEventHandler; import com.delect.motiver.client.event.handler.GuideValueRemovedEventHandler; import com.delect.motiver.client.event.handler.TimeCreatedEventHandler; import com.delect.motiver.client.event.handler.TimeRemovedEventHandler; import com.delect.motiver.client.event.handler.TimeUpdatedEventHandler; import com.delect.motiver.client.presenter.EmptyPresenter; import com.delect.motiver.client.presenter.EmptyPresenter.EmptyDisplay; import com.delect.motiver.client.presenter.Presenter; import com.delect.motiver.client.service.MyServiceAsync; import com.delect.motiver.client.view.Display; import com.delect.motiver.client.view.EmptyView; import com.delect.motiver.shared.GuideValueModel; import com.delect.motiver.shared.NutritionDayModel; import com.delect.motiver.shared.TimeModel; import com.delect.motiver.shared.util.CommonUtils; import com.extjs.gxt.ui.client.widget.LayoutContainer; /** * Shows single day's total calories etc * @author Antti * */ public class TotalsContainerPresenter extends Presenter { /** * Abstract class for view to extend */ public abstract static class TotalsContainerDisplay extends Display { public abstract LayoutContainer getTotalsContainer(); public abstract void setCurrentGuideValue(GuideValueModel guide); public abstract void setData(double energy, double protein, double carb, double fet); public abstract void showTotals(); } private Date date; private TotalsContainerDisplay display; //child presenters private EmptyPresenter emptyPresenter; private GuideValueModel guide; private Timer timer; private List<TimeModel> times; private String uid = null; public TotalsContainerPresenter(MyServiceAsync rpcService, SimpleEventBus eventBus, TotalsContainerDisplay display, String uid, Date date) { super(rpcService, eventBus); this.display = display; this.uid = uid; this.date = date; //reset guide guide = null; if(this.date == null) { return; } } @Override public Display getView() { return display; } @Override public void onBind() { //EVENT: time added addEventHandler(TimeCreatedEvent.TYPE, new TimeCreatedEventHandler() { @Override public void onTimeCreated(TimeCreatedEvent event) { if(times == null) { return; } times.add(event.getTime()); calculateTotals(false); } }); //EVENT: time updated addEventHandler(TimeUpdatedEvent.TYPE, new TimeUpdatedEventHandler() { @Override public void onTimeUpdated(TimeUpdatedEvent event) { if(times == null) { return; } final TimeModel mUpdated = event.getTime(); for(TimeModel m : times) { if(m.getId() == mUpdated.getId()) { m.setEnergy(mUpdated.getEnergy()); m.setProtein(mUpdated.getProtein()); m.setCarb(mUpdated.getCarb()); m.setFet(mUpdated.getFet()); m.setMeals(mUpdated.getMeals()); m.setFoods(mUpdated.getFoods()); break; } } calculateTotals(false); } }); //EVENT: time removed addEventHandler(TimeRemovedEvent.TYPE, new TimeRemovedEventHandler() { @Override public void onTimeRemoved(TimeRemovedEvent event) { if(times == null) { return; } final TimeModel mRemoved = event.getTime(); for(TimeModel m : times) { if(m.getId() == mRemoved.getId()) { times.remove(m); break; } } calculateTotals(false); } }); //EVENT: guide value added addEventHandler(GuideValueCreatedEvent.TYPE, new GuideValueCreatedEventHandler() { @Override public void onGuideValueCreated(GuideValueCreatedEvent event) { //reload guide values loadGuideValues(); } }); //EVENT: guide value removed addEventHandler(GuideValueRemovedEvent.TYPE, new GuideValueRemovedEventHandler() { @Override public void onGuideValueRemoved(GuideValueRemovedEvent event) { //reload guide values if this guide was removed if(event.getGuideValue() != null && guide != null && event.getGuideValue().getId() == guide.getId()) { loadGuideValues(); } } }); // TODO Auto-generated method stub } @Override public void onRun() { //show loading text until data is set emptyPresenter = new EmptyPresenter(rpcService, eventBus, (EmptyDisplay)GWT.create(EmptyView.class), EmptyPresenter.EMPTY_LOADING_SMALL); emptyPresenter.run(display.getTotalsContainer()); } @Override public void onStop() { if(timer != null) { timer.cancel(); } if(emptyPresenter != null) { emptyPresenter.stop(); } } /** * Sets date and time so presenter can calculate totals from there * @param date * @param times */ public void setData(Date date, List<TimeModel> times) { this.date = date; this.times = times; if(emptyPresenter != null) { emptyPresenter.stop(); } calculateTotals(true); } /** * Sets date and nutritionDayModel so presenter can calculate totals from there * @param date * @param nutritionDayModel */ public void setData(Date date, NutritionDayModel nutritionDayModel) { this.date = date; if(emptyPresenter != null) { emptyPresenter.stop(); } display.setData(nutritionDayModel.getEnergy(), nutritionDayModel.getProtein(), nutritionDayModel.getCarb(), nutritionDayModel.getFet()); } /** * Calculates totals */ private void calculateTotals(boolean refreshGuideValues) { double e = 0, p = 0, c = 0, f = 0; for(TimeModel t : times) { e += t.getEnergy(); p += t.getProtein(); c += t.getCarb(); f += t.getFet(); } display.setData(e, p, c, f); //reload guide values if(refreshGuideValues) { loadGuideValues(); } } /** * Loads current days guide values (after 3 sec delay) * <br>Uses timer so when times are updated often -> values are fetched only once */ private void loadGuideValues() { //only if our foods and not blog if(!uid.equals(AppController.User.getUid()) || AppController.BLOG_UID != null) { return; } if(timer != null) { timer.cancel(); } //clear old guide values display.setCurrentGuideValue(null); timer = new Timer() { @Override public void run() { Motiver.setNextCallCacheable(true); final Request req = rpcService.getGuideValues(uid, 0, CommonUtils.trimDateToDatabase(date, true), new MyAsyncCallback<List<GuideValueModel>>() { @Override public void onSuccess(List<GuideValueModel> result) { List<GuideValueModel> list = result; //get first value if(list != null) { if(list.size() > 0) { guide = list.get(0); display.setCurrentGuideValue(guide); } } } }); addRequest(req); } }; timer.schedule(1000); } }