/*
* Copyright (C) 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.errai.demo.grocery.client.local;
import static java.util.Collections.sort;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.event.Observes;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.jboss.errai.demo.grocery.client.local.producer.StoreListProducer;
import org.jboss.errai.demo.grocery.client.shared.Department;
import org.jboss.errai.demo.grocery.client.shared.GroceryList;
import org.jboss.errai.demo.grocery.client.shared.Item;
import org.jboss.errai.demo.grocery.client.shared.Store;
import org.jboss.errai.demo.grocery.client.shared.qual.New;
import org.jboss.errai.demo.grocery.client.shared.qual.Removed;
import org.jboss.errai.demo.grocery.client.shared.qual.Updated;
import org.jboss.errai.ui.client.widget.ListWidget;
import org.jboss.errai.ui.cordova.geofencing.GeoFencingEvent;
import org.jboss.errai.ui.nav.client.local.TransitionTo;
@Singleton
public class GroceryListWidget extends ListWidget<Item, GroceryItemWidget> {
@Inject
EntityManager entityManager;
@Inject
GroceryList groceryList;
@Inject
ItemStoreDistanceComparator distanceComparator;
@Inject
TransitionTo<ItemListPage> itemsTab;
private SortBy sortField = SortBy.NAME;
public enum SortBy {
NAME(new Comparator<Item>() {
@Override
public int compare(Item one, Item two) {
return one.getName().compareTo(two.getName());
}
}), RECENTLY_ADDED(new Comparator<Item>() {
@Override
public int compare(Item one, Item two) {
return two.getAddedOn().compareTo(one.getAddedOn());
}
}), DEPARTMENT(new Comparator<Item>() {
@Override
public int compare(Item one, Item two) {
return one.getDepartment().getName().compareTo(two.getDepartment().getName());
}
}), STORE_LOCATION(null);
private final Comparator<Item> itemComparator;
SortBy(Comparator<Item> itemComparator) {
this.itemComparator = itemComparator;
}
}
@SuppressWarnings("unused")
private void onNewItem(@Observes @New Item item) {
/*
* XXX This is imprecise. We don't even know if the affected item is in the grocery list this widget wraps. This
* should be finer-grained (different cases for new, updated, removed) or the GroceryList class could do something
* fancy.
*/
System.out.println("Observed new item");
this.getValue().add(item);
}
@SuppressWarnings("unused")
private void onEditItem(@Observes @Updated Item item) {
System.out.println("Observed updated item");
}
@SuppressWarnings("unused")
private void onDeleteItem(@Observes @Removed Item item) {
System.out.println("Observed deleted item");
this.getValue().remove(item);
}
public void refreshListWidget() {
List<Item> itemList = getAllSortedItems();
setItems(itemList);
}
private List<Item> getAllSortedItems() {
List<Item> itemList = getAllItems();
if (sortField != SortBy.STORE_LOCATION) {
sort(itemList, sortField.itemComparator);
}
else {
sort(itemList, distanceComparator);
}
return itemList;
}
@PostConstruct
private void onInit() {
List<Item> itemList = getAllSortedItems();
groceryList.getItems().addAll(itemList);
setItems(groceryList.getItems());
}
private List<Item> getAllItems() {
TypedQuery<Item> query = entityManager.createNamedQuery("allItems", Item.class);
return query.getResultList();
}
@Override
public Class<GroceryItemWidget> getItemComponentType() {
return GroceryItemWidget.class;
}
public void sortBy(SortBy field) {
this.sortField = field;
}
public void filterOn(Store store) {
List<Item> itemList = getAllItems();
List<Item> filtered = new ArrayList<Item>(itemList.size());
for (Department department : store.getDepartments()) {
for (Item item : itemList) {
if (item.getDepartment().getName().equals(department.getName())) {
filtered.add(item);
}
}
}
setItems(filtered);
}
public void closeToStore(@Observes GeoFencingEvent event) {
itemsTab.go();
Store store = entityManager.find(Store.class, event.getRegionId());
if (store != null) {
filterOn(store);
}
}
public static class ItemStoreDistanceComparator implements Comparator<Item> {
@Inject
StoreListProducer storeListProducer;
@Override
public int compare(Item one, Item two) {
int itemOneIndex = 0;
int itemTwoIndex = 0;
List<Store> stores = storeListProducer.getStoresSortedOnDistance();
for (int i = 0, storesSize = stores.size(); i < storesSize; i++) {
Store store = stores.get(i);
for (Department department : store.getDepartments()) {
if (department.getName().equals(one.getDepartment().getName())) {
itemOneIndex = i;
}
if (department.getName().equals(two.getDepartment().getName())) {
itemTwoIndex = i;
}
}
}
return (itemOneIndex < itemTwoIndex ? -1 : (itemOneIndex == itemTwoIndex ? 0 : 1));
}
}
}