/******************************************************************************* * 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.admin; 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.json.client.JSONArray; import com.google.gwt.json.client.JSONObject; import com.delect.motiver.client.AppController; import com.delect.motiver.client.Motiver; import com.delect.motiver.client.MyAsyncCallback; import com.delect.motiver.client.ServerConnection; import com.delect.motiver.client.ServerConnection.ResponseHandler; import com.delect.motiver.client.event.ConnectionErrorEvent; 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.Constants; import com.delect.motiver.shared.FoodNameModel; import com.extjs.gxt.ui.client.widget.LayoutContainer; /** * * Shows foods names in list where admins can edit/delete those */ public class FoodNamesPresenter extends Presenter { /** * Abstract class for view to extend */ public abstract static class FoodNamesDisplay extends Display { public abstract void clearQuickAdd(); public abstract LayoutContainer getBodyContainer(); public abstract void hideProgress(); public abstract void setFoods(List<FoodNameModel> foods); public abstract void setHandler(FoodNamesHandler handler); public abstract void showCompleted(boolean successful, String string); public abstract void showProgress(String text, int count, int total); } public interface FoodNamesHandler { /** * Combines names together * @param firstId : where other IDs are combined * @param ids : other IDs */ void combineNames(Long firstId, Long[] ids); void fetchFoods(); void quickAdd(String value); void saveName(FoodNameModel model); void search(String query); void updateModel(FoodNameModel model); } private FoodNamesDisplay display; //child presenters private EmptyPresenter emptyPresenter; private String lastQuery = ""; /** * Shows foods names in list where admins can edit/delete those * @param rpcService * @param eventBus * @param display */ public FoodNamesPresenter(MyServiceAsync rpcService, SimpleEventBus eventBus, FoodNamesDisplay display) { super(rpcService, eventBus); this.display = display; } @Override public Display getView() { return display; } @Override public void onBind() { display.setHandler(new FoodNamesHandler() { @Override public void combineNames(Long firstId, Long[] ids) { final Request req = rpcService.combineFoodNames(firstId, ids, new MyAsyncCallback<Boolean>() { @Override public void onSuccess(Boolean result) { //refresh onRun(); } }); addRequest(req); } @Override public void fetchFoods() { fetchFoodsFromServer(0); } @Override public void quickAdd(String value) { addMultipleNames(value); } @SuppressWarnings("unchecked") @Override public void saveName(FoodNameModel model) { final Request req = rpcService.updateFoodName(model, MyAsyncCallback.EmptyCallback); addRequest(req); } @Override public void search(String query) { searchFoods(query); } @SuppressWarnings("unchecked") @Override public void updateModel(FoodNameModel model) { final Request req = rpcService.updateFoodName(model, MyAsyncCallback.EmptyCallback); addRequest(req); } }); } @Override public void onRun() { //add empty presenter emptyPresenter = new EmptyPresenter(rpcService, eventBus, (EmptyDisplay)GWT.create(EmptyView.class), EmptyPresenter.EMPTY_LOADING); emptyPresenter.run(display.getBodyContainer()); } @Override public void onStop() { if(emptyPresenter != null) { emptyPresenter.stop(); } } /** * Fetchs foods * @param index */ private void fetchFoodsFromServer(int index) { if(index == 0) { display.showProgress("Fetching foods", 0, 0); } //TEMP fetch data final ServerConnection con = new ServerConnection(); //workouts try { con.connect("http://www.xlgain.com/feed_jsonp/get_all_foods.php?t=3&m=1&i=" + index + "&user=justerr&pass=c8e04ea27e565adbdebdb4f84574474a", new ResponseHandler() { @Override public void loadError(Throwable throwable) { final ConnectionErrorEvent event = new ConnectionErrorEvent(Constants.ERROR_CANT_CONNECT_XLGAIN); eventBus.fireEvent(event); } @Override public void loadOk(JSONObject json) { final JSONArray foods; try { foods = json.get("foods").isArray(); final int indexNew = (int)json.get("index").isNumber().doubleValue(); final int total = (int)json.get("total").isNumber().doubleValue(); final List<FoodNameModel> arrFoods = new ArrayList<FoodNameModel>(); for(int i=0; i < foods.size(); i++) { try { JSONObject obj = foods.get(i).isObject(); FoodNameModel model = new FoodNameModel(); model.setName(obj.get("n").isString().stringValue()); model.setEnergy(obj.get("e").isNumber().doubleValue()); model.setProtein(obj.get("p").isNumber().doubleValue()); model.setCarb(obj.get("c").isNumber().doubleValue()); model.setFet(obj.get("f").isNumber().doubleValue()); model.setPortion(obj.get("po").isNumber().doubleValue()); arrFoods.add(model); } catch (Exception e) { Motiver.showException(e); } } display.showProgress("Fetching foods", (indexNew != 0)? indexNew : total, total); //add to server final Request req = rpcService.fetchSaveFoodNames(arrFoods, new MyAsyncCallback<Boolean>() { @Override public void onSuccess(Boolean result) { if(indexNew != 0) { fetchFoodsFromServer(indexNew); } else { showCompleted(true); } } }); addRequest(req); } catch (Exception e) { Motiver.showException(e); } } }); } catch (Exception e) { final ConnectionErrorEvent event = new ConnectionErrorEvent(Constants.ERROR_CANT_CONNECT_XLGAIN); eventBus.fireEvent(event); } } /** * Adds multiple names from excel "string" * <br>name -tab- protein -tab- carb -tab- fet -tab- portion * @param value */ protected void addMultipleNames(String value) { display.setContentEnabled(false); //split final String[] rows = value.split("\\r?\\n"); List<FoodNameModel> list = new ArrayList<FoodNameModel>(); for(String row : rows) { try { String[] data = (row + " ").split("\\t"); //if all data if(data.length == 6) { String name = data[0]; double e=0, p=0, c=0, f=0, po=0; if(data[1].replace(",", ".").trim().length() > 0) { //if format joule/kcal if(data[1].contains("/")) { String[] arr = data[1].replace(",", ".").trim().split("/"); e = Double.parseDouble(arr[1]); } else { e = Double.parseDouble(data[1].replace(",", ".").trim()); } } if(data[2].replace(",", ".").trim().length() > 0) { p = Double.parseDouble(data[2].replace(",", ".").trim()); } if(data[3].replace(",", ".").trim().length() > 0) { c = Double.parseDouble(data[3].replace(",", ".").trim()); } if(data[4].replace(",", ".").trim().length() > 0) { f = Double.parseDouble(data[4].replace(",", ".").trim()); } if(data[5].replace(",", ".").trim().length() > 0) { po = Double.parseDouble(data[5].replace(",", ".").trim()); } FoodNameModel model = new FoodNameModel(0L, name); model.setEnergy(e); model.setProtein(p); model.setCarb(c); model.setFet(f); model.setPortion(po); //if admin -> set trusted if(AppController.User.isAdmin()) { model.setTrusted(100); } list.add(model); } } catch (Exception e) { Motiver.showException(e); } } //send to server if(list.size() > 0) { final Request req = rpcService.addFoodname(list, new MyAsyncCallback<List<FoodNameModel>>() { @Override public void onSuccess(List<FoodNameModel> result) { display.clearQuickAdd(); display.setContentEnabled(true); } }); addRequest(req); } else { display.setContentEnabled(true); } } protected void searchFoods(String query) { if(query == null) { query = ""; } if(lastQuery.equals(query)) { return; } lastQuery = query; //fetch foods final Request req = rpcService.searchFoodNames(query, 200, new MyAsyncCallback<List<FoodNameModel>>() { @Override public void onSuccess(List<FoodNameModel> result) { if(emptyPresenter != null) { emptyPresenter.stop(); } display.setFoods(result); } }); addRequest(req); } /** * Shows if data is fetched correctly or not * @param successful */ void showCompleted(boolean successful) { display.showCompleted(successful, "" ); } }