package com.mozu.mozuandroidinstoreassistant.app.category;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.SearchManager;
import android.content.Context;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;
import com.mozu.api.contracts.productruntime.Category;
import com.mozu.api.contracts.productruntime.Product;
import com.mozu.api.contracts.productruntime.ProductCollection;
import com.mozu.mozuandroidinstoreassistant.app.BuildConfig;
import com.mozu.mozuandroidinstoreassistant.app.MainActivity;
import com.mozu.mozuandroidinstoreassistant.app.R;
import com.mozu.mozuandroidinstoreassistant.app.adapters.SearchSuggestionsCursorAdapter;
import com.mozu.mozuandroidinstoreassistant.app.category.adapters.CategoryProductAdapter;
import com.mozu.mozuandroidinstoreassistant.app.category.loaders.CategoryFetcher;
import com.mozu.mozuandroidinstoreassistant.app.data.IData;
import com.mozu.mozuandroidinstoreassistant.app.data.category.CategoryDataItem;
import com.mozu.mozuandroidinstoreassistant.app.data.product.ProductDataItem;
import com.mozu.mozuandroidinstoreassistant.app.models.RecentSearch;
import com.mozu.mozuandroidinstoreassistant.app.models.UserPreferences;
import com.mozu.mozuandroidinstoreassistant.app.models.authentication.UserAuthenticationStateMachine;
import com.mozu.mozuandroidinstoreassistant.app.models.authentication.UserAuthenticationStateMachineProducer;
import com.mozu.mozuandroidinstoreassistant.app.product.ProductDetailInventoryFragment;
import com.mozu.mozuandroidinstoreassistant.app.tasks.CategoryImageUpdateListener;
import com.mozu.mozuandroidinstoreassistant.app.tasks.CategoryImageUpdateTask;
import com.mozu.mozuandroidinstoreassistant.app.tasks.InventoryButtonClickListener;
import java.util.ArrayList;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import rx.Observable;
import rx.Observer;
import rx.android.observables.AndroidObservable;
import rx.functions.Func1;
import rx.schedulers.Schedulers;
public class CategoryProductFragment extends Fragment implements AdapterView.OnItemClickListener, AbsListView.OnScrollListener, SearchView.OnQueryTextListener, SearchView.OnSuggestionListener, SwipeRefreshLayout.OnRefreshListener, InventoryButtonClickListener {
private static final int MAX_NUMBER_OF_SEARCHES = 5;
private static final int CATEGORY_IMAGELOADER_MENU_ID = 100;
private static final String CURRENT_CATEGORY = "currentCategory";
private final static String PRODUCT_INVENTORY_DIALOG_TAG = "product_inventory_tag";
@InjectView(R.id.category_grid)
GridView mGridOfCategories;
@InjectView(R.id.category_list)
ListView mListOfCategories;
private UserAuthenticationStateMachine mUserState;
private CategoryProductAdapter mCategoryProductAdapter;
private Category mCategory;
private CategoryFragmentListener mListener = sCategoryListener;
private boolean mIsGridVisible = true;
private MenuItem mToggleGridItem;
private SearchView mSearchView;
private MenuItem mSearchMenuItem;
private rx.Observable<List<Category>> mCategoryObservable;
private rx.Observable<ProductCollection> mProductObservable;
@InjectView(R.id.empty_list)
TextView mEmptyListMessageView;
@InjectView(R.id.category_container)
SwipeRefreshLayout mCategoryPullToRefresh;
private CategoryFetcher mCategoryFetcher;
private int mCurrentPage = 0;
private Integer mProductCount = 0;
public static CategoryProductFragment getInstance(Category category) {
CategoryProductFragment fragment = new CategoryProductFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(CURRENT_CATEGORY, category);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mListener = (CategoryFragmentListener) activity;
}
@Override
public void onDetach() {
mListener = sCategoryListener;
super.onDetach();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(CURRENT_CATEGORY, mCategory);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCurrentPage = 0;
Bundle b = getArguments();
mCategory = (Category) b.getSerializable(CURRENT_CATEGORY);
mUserState = UserAuthenticationStateMachineProducer.getInstance(getActivity());
mCategoryFetcher = new CategoryFetcher();
mCategoryObservable = AndroidObservable.bindFragment(this, mCategoryFetcher.getCategoryInformation(mUserState.getTenantId(), mUserState.getSiteId()));
mProductObservable = AndroidObservable.bindFragment(this, mCategoryFetcher.getProductInformation(mUserState.getTenantId(), mUserState.getSiteId()));
setRetainInstance(true);
setHasOptionsMenu(true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mCategory = (Category) savedInstanceState.getSerializable(CURRENT_CATEGORY);
}
if (mCategory == null || mCategory.getChildrenCategories().size() < 1) {
reloadData();
} else {
loadProductInformation(true);
}
}
private void loadProductInformation(final boolean reset) {
mCategoryPullToRefresh.setRefreshing(true);
if (!reset && mCategoryProductAdapter != null) {
mCategoryProductAdapter.setLoadingData();
mCategoryProductAdapter.notifyDataSetChanged();
}
mCategoryFetcher.setCategoryId(mCategory.getCategoryId());
mCategoryFetcher.setCurrentPage(mCurrentPage);
mProductObservable.subscribeOn(Schedulers.io())
.subscribe(new Observer<ProductCollection>() {
List<IData> dataList = new ArrayList<>();
@Override
public void onCompleted() {
mCategoryPullToRefresh.setRefreshing(false);
if (reset || mCategoryProductAdapter == null || mCategoryProductAdapter.getCount() == 0) {
for (Category category : mCategory.getChildrenCategories()) {
CategoryDataItem categoryDataItem = new CategoryDataItem(category);
dataList.add(0, categoryDataItem);
}
updateListGridsToCategory(dataList, false);
} else {
mCategoryProductAdapter.removeLoadingData();
updateListGridsToCategory(dataList, true);
}
}
@Override
public void onError(Throwable e) {
if (mCategoryPullToRefresh.isRefreshing()) {
mCategoryPullToRefresh.setRefreshing(false);
}
if (mCategoryProductAdapter != null) {
mCategoryProductAdapter.removeLoadingData();
mCategoryProductAdapter.notifyDataSetChanged();
}
}
@Override
public void onNext(ProductCollection productCollection) {
if (productCollection.getItems() != null && !productCollection.getItems().isEmpty()) {
dataList.clear();
mProductCount = productCollection.getTotalCount();
for (Product product : productCollection.getItems()) {
ProductDataItem dataItem = new ProductDataItem(product);
dataList.add(dataItem);
}
}
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_category_product_grid, container, false);
ButterKnife.inject(this, fragmentView);
mCurrentPage = 0;
mGridOfCategories.setOnItemClickListener(this);
mListOfCategories.setOnItemClickListener(this);
mGridOfCategories.setOnScrollListener(this);
mListOfCategories.setOnScrollListener(this);
mListOfCategories.setDivider(null);
mEmptyListMessageView.setVisibility(View.GONE);
mCategoryPullToRefresh.setOnRefreshListener(this);
mCategoryPullToRefresh.setEnabled(false);
mCategoryPullToRefresh.setColorScheme(R.color.first_color_swipe_refresh,
R.color.second_color_swipe_refresh,
R.color.third_color_swipe_refresh,
R.color.fourth_color_swipe_refresh);
return fragmentView;
}
void reloadData() {
mCategoryPullToRefresh.setRefreshing(true);
mCategoryObservable.subscribeOn(Schedulers.io())
.flatMap(new Func1<List<Category>, Observable<Category>>() {
@Override
public Observable<Category> call(List<Category> categories) {
return Observable.from(categories);
}
}).filter(new Func1<Category, Boolean>() {
@Override
public Boolean call(Category category) {
if (mCategory == null) {
return true;
}
return mCategory.getCategoryId().equals(category.getCategoryId());
}
})
.subscribe(new CategorySubscriber());
}
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
((MainActivity) getActivity()).setProductSelected();
}
}
@Override
public void onRefresh() {
loadProductInformation(true);
}
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (visibleItemCount > 0 && firstVisibleItem + visibleItemCount > (int) totalItemCount / 2 && totalItemCount < mProductCount && !mCategoryPullToRefresh.isRefreshing()) {
mCurrentPage++;
loadProductInformation(false);
}
}
private class CategorySubscriber implements rx.Observer<Category> {
List<IData> dataList = new ArrayList<IData>();
@Override
public void onCompleted() {
if (mCategoryPullToRefresh.isRefreshing()) {
mCategoryPullToRefresh.setRefreshing(false);
}
updateListGridsToCategory(dataList, false);
}
@Override
public void onError(Throwable e) {
mCategoryPullToRefresh.setRefreshing(false);
mGridOfCategories.setVisibility(View.GONE);
mListOfCategories.setVisibility(View.GONE);
mEmptyListMessageView.setVisibility(View.VISIBLE);
}
@Override
public void onNext(Category category) {
CategoryDataItem categoryDataItem = new CategoryDataItem(category);
dataList.add(categoryDataItem);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
inflater.inflate(R.menu.product, menu);
mToggleGridItem = menu.findItem(R.id.toggle_view);
mIsGridVisible = prefs.getShowAsGrids();
if (mIsGridVisible) {
mToggleGridItem.setIcon(R.drawable.actionbar_icon_list_button);
mToggleGridItem.setTitle(getString(R.string.view_as_list_menu_item_text));
} else {
mToggleGridItem.setIcon(R.drawable.actionbar_icon_grid_button);
mToggleGridItem.setTitle(getString(R.string.view_as_grid_menu_item_text));
}
if (BuildConfig.DEBUG) {
// menu.add(0, CATEGORY_IMAGELOADER_MENU_ID, Menu.NONE, "Load Category Images");
}
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) mSearchMenuItem.getActionView();
mSearchView.setBackgroundResource(R.drawable.mozu_edit_text_holo_light);
mSearchView.setQueryHint(getString(R.string.product_search_hint));
mSearchView.setMaxWidth(1500);
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
mSearchView.setOnQueryTextListener(this);
}
private void showSuggestions() {
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
List<RecentSearch> recentProductSearches = prefs.getRecentProductSearches();
// Load data from list to cursor
String[] columns = new String[]{"_id", "text"};
Object[] temp = new Object[]{0, "default"};
MatrixCursor cursor = new MatrixCursor(columns);
if (recentProductSearches == null || recentProductSearches.size() < 1) {
return;
}
for (int i = 0; i < recentProductSearches.size(); i++) {
temp[0] = i;
temp[1] = recentProductSearches.get(i);
cursor.addRow(temp);
}
mSearchView.setSuggestionsAdapter(new SearchSuggestionsCursorAdapter(getActivity(), cursor, recentProductSearches));
mSearchView.setOnSuggestionListener(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
if (item.getItemId() == R.id.toggle_view) {
if (mCategoryProductAdapter == null) {
return false;
}
if (!mIsGridVisible) {
mIsGridVisible = true;
mListOfCategories.setVisibility(View.GONE);
mGridOfCategories.setVisibility(View.VISIBLE);
mCategoryProductAdapter.setIsGrid(true);
mCategoryProductAdapter.notifyDataSetChanged();
prefs.setShowAsGrids(true);
mUserState.updateUserPreferences();
mToggleGridItem.setIcon(R.drawable.actionbar_icon_list_button);
mToggleGridItem.setTitle(getString(R.string.view_as_list_menu_item_text));
return true;
} else {
mIsGridVisible = false;
mListOfCategories.setVisibility(View.VISIBLE);
mGridOfCategories.setVisibility(View.GONE);
mCategoryProductAdapter.setIsGrid(false);
mCategoryProductAdapter.notifyDataSetChanged();
prefs.setShowAsGrids(false);
mUserState.updateUserPreferences();
mToggleGridItem.setIcon(R.drawable.actionbar_icon_grid_button);
mToggleGridItem.setTitle(getString(R.string.view_as_grid_menu_item_text));
return true;
}
} else if (item.getItemId() == R.id.action_search) {
showSuggestions();
} else if (item.getItemId() == CATEGORY_IMAGELOADER_MENU_ID) {
/*
List<Category> categories = new ArrayList<Category>();
if (mCategoryProductAdapter != null) {
for (int i = 0; i < mCategoryProductAdapter.getCount(); i++) {
categories.add(mCategoryProductAdapter.getItem(i));
}
}
loadCategoryImages(categories);
*/
} else if (item.getItemId() == R.id.refresh_product) {
onRefresh();
}
return super.onOptionsItemSelected(item);
}
private void loadCategoryImages(List<Category> mCategories) {
for (Category category : mCategories) {
if (category.getContent().getCategoryImages() == null || category.getContent().getCategoryImages().size() <= 0) {
CategoryImageUpdateTask task = new CategoryImageUpdateTask(mCategoryImageUpdateListener, mUserState.getTenantId(), mUserState.getSiteId(), 5);
task.execute();
}
}
}
private CategoryImageUpdateListener mCategoryImageUpdateListener = new CategoryImageUpdateListener() {
@Override
public void onImageUpdateSucces(String categoryName, String categoryId) {
Toast.makeText(getActivity(), "Done updating image for " + categoryName, Toast.LENGTH_SHORT).show();
}
@Override
public void onImageUpdateFailure(String message) {
Toast.makeText(getActivity(), "Failed to update image for ", Toast.LENGTH_SHORT).show();
}
};
private void updateListGridsToCategory(List<IData> dataList, boolean addData) {
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
if (dataList == null || dataList.size() < 1) {
mGridOfCategories.setVisibility(View.GONE);
mListOfCategories.setVisibility(View.GONE);
mEmptyListMessageView.setVisibility(View.VISIBLE);
return;
} else {
mEmptyListMessageView.setVisibility(View.GONE);
}
if (mCategoryProductAdapter == null) {
mCategoryProductAdapter = new CategoryProductAdapter(getActivity(), mUserState.getTenantId(), mUserState.getSiteId(), mUserState.getSiteDomain(), this);
}
if (addData) {
mCategoryProductAdapter.addData(dataList);
} else {
mCategoryProductAdapter.setData(dataList);
}
int firstGridPosition = mGridOfCategories.getFirstVisiblePosition();
mGridOfCategories.setAdapter(mCategoryProductAdapter);
mGridOfCategories.setSelection(firstGridPosition);
int firstListPosition = mListOfCategories.getFirstVisiblePosition();
mListOfCategories.setAdapter(mCategoryProductAdapter);
mListOfCategories.setSelection(firstListPosition);
if (prefs.getShowAsGrids()) {
mGridOfCategories.setVisibility(View.VISIBLE);
mListOfCategories.setVisibility(View.GONE);
mCategoryProductAdapter.setIsGrid(true);
} else {
mGridOfCategories.setVisibility(View.GONE);
mListOfCategories.setVisibility(View.VISIBLE);
mCategoryProductAdapter.setIsGrid(false);
}
mCategoryProductAdapter.notifyDataSetChanged();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
IData itemAtPosition = mCategoryProductAdapter.getItem(position);
if (itemAtPosition instanceof CategoryDataItem) {
CategoryDataItem categoryDataItem = (CategoryDataItem) itemAtPosition;
mListener.onCategoryChosen(categoryDataItem.getCategory());
} else if (itemAtPosition instanceof ProductDataItem) {
ProductDataItem productDataItem = (ProductDataItem) itemAtPosition;
((MainActivity) getActivity()).onProductChoosentFromProuct(productDataItem.getProduct().getProductCode());
}
}
private static CategoryFragmentListener sCategoryListener = new CategoryFragmentListener() {
@Override
public void onCategoryChosen(Category category) {
Log.e("TAG", "not implemented");
}
@Override
public void onSearchPerformedFromCategory(int currentCategory, String query) {
Log.e("TAG", "not implemented");
}
};
@Override
public boolean onQueryTextSubmit(String query) {
mSearchMenuItem.collapseActionView();
int categoryId = -1;
if (mCategory != null) {
categoryId = mCategory.getCategoryId();
}
mListener.onSearchPerformedFromCategory(categoryId, query);
//save search to list
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
List<RecentSearch> recentProductSearches = prefs.getRecentProductSearches();
if (recentProductSearches == null) {
recentProductSearches = new ArrayList<RecentSearch>();
}
//if search already exists then dont add it again
for (int i = 0; i < recentProductSearches.size(); i++) {
if (recentProductSearches.get(i).getSearchTerm().equalsIgnoreCase(query)) {
recentProductSearches.remove(i);
break;
}
}
RecentSearch search = new RecentSearch();
search.setSearchTerm(query);
recentProductSearches.add(0, search);
if (recentProductSearches.size() > MAX_NUMBER_OF_SEARCHES) {
recentProductSearches.remove(recentProductSearches.size() - 1);
}
prefs.setRecentProductSearchs(recentProductSearches);
mUserState.updateUserPreferences();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
UserPreferences prefs = mUserState.getCurrentUsersPreferences();
List<RecentSearch> recentProductSearches = prefs.getRecentProductSearches();
onQueryTextSubmit(recentProductSearches.get(position).getSearchTerm());
return true;
}
@Override
public void onClick(Product product) {
FragmentManager manager = getFragmentManager();
ProductDetailInventoryFragment inventoryFragment = (ProductDetailInventoryFragment) manager.findFragmentByTag(PRODUCT_INVENTORY_DIALOG_TAG);
if (inventoryFragment == null) {
inventoryFragment = new ProductDetailInventoryFragment();
inventoryFragment.setProduct(product);
inventoryFragment.setTenantId(mUserState.getTenantId());
inventoryFragment.setSiteId(mUserState.getSiteId());
}
inventoryFragment.show(manager, PRODUCT_INVENTORY_DIALOG_TAG);
}
}