package com.mozu.mozuandroidinstoreassistant.app.search; import android.app.Fragment; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.database.MatrixCursor; import android.os.Bundle; import android.text.TextUtils; import android.view.KeyEvent; 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.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SearchView; import android.widget.TextView; import com.mozu.api.contracts.commerceruntime.orders.Order; import com.mozu.api.contracts.commerceruntime.orders.OrderCollection; import com.mozu.api.contracts.customer.CustomerAccount; import com.mozu.api.contracts.customer.CustomerAccountCollection; import com.mozu.api.contracts.productruntime.ProductSearchResult; import com.mozu.mozuandroidinstoreassistant.app.CustomerDetailActivity; import com.mozu.mozuandroidinstoreassistant.app.MainActivity; import com.mozu.mozuandroidinstoreassistant.app.OrderDetailActivity; import com.mozu.mozuandroidinstoreassistant.app.ProductDetailActivity; import com.mozu.mozuandroidinstoreassistant.app.R; import com.mozu.mozuandroidinstoreassistant.app.adapters.SearchSuggestionsCursorAdapter; 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.search.adapters.GlobalSearchCustomerAdapter; import com.mozu.mozuandroidinstoreassistant.app.search.adapters.GlobalSearchOrderAdapter; import com.mozu.mozuandroidinstoreassistant.app.search.adapters.GlobalSearchProductAdapter; import com.mozu.mozuandroidinstoreassistant.app.search.loaders.SearchFetcher; import com.mozu.mozuandroidinstoreassistant.app.views.LoadingView; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import rx.Observable; import rx.Observer; import rx.Subscription; import rx.android.observables.AndroidObservable; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; import rx.subscriptions.Subscriptions; public class SearchFragment extends Fragment implements SearchView.OnSuggestionListener{ public static final int MAX_NUMBER_OF_SEARCHES = 50; private View mView; private ListView mOrdersSearchView; private ListView mProductsSearchView; private ListView mCustomersSearchView; private Observable<OrderCollection> mOrderObservable; private Observable<ProductSearchResult> mProductObservable; private Observable<CustomerAccountCollection> mCustomerObservable; private LoadingView mOrderLoadingView; private LoadingView mProductLoadingView; private LoadingView mCustomerLoadingView; private LinearLayout mOrderLayout; private LinearLayout mProductLayout; private LinearLayout mCustomerLayout; private EditText mSearchEditText; private ImageView mSearchImageView; private Button mOrdersViewButton; private Button mProductsViewButton; private Button mCustomersViewButton; private String mCustomerSearchString; private String mOrderSearchString; private String mProductSearchString; private static String TENANT_ID = "tenantId"; private static String SITE_ID = "siteId"; private Integer mTenantId; private Integer mSiteId; Subscription mSubscription = Subscriptions.empty(); private SearchFetcher mSearchFetcher; private GlobalSearchOrderAdapter mOrderAdapter; private GlobalSearchProductAdapter mProductAdapter; private GlobalSearchCustomerAdapter mCustomerAdapter; private SearchView mSearchView; private UserAuthenticationStateMachine mUserState; private MenuItem mSearchMenuItem; private TextView mCustomersResultCount; private TextView mOrdersResultCount; private TextView mProductsResultCount; public static SearchFragment getInstance(Integer tenantId,Integer siteId){ SearchFragment fragment = new SearchFragment(); Bundle bundle = new Bundle(); bundle.putInt(TENANT_ID, tenantId); bundle.putInt(SITE_ID, siteId); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle b = getArguments(); mTenantId = b.getInt(TENANT_ID); mSiteId = b.getInt(SITE_ID); mUserState = UserAuthenticationStateMachineProducer.getInstance(getActivity()); mSearchFetcher = new SearchFetcher(); mOrderObservable = AndroidObservable.bindFragment(this, mSearchFetcher.searchOrder(mTenantId, mSiteId)); mProductObservable = AndroidObservable.bindFragment(this, mSearchFetcher.searchProduct(mTenantId,mSiteId)); mCustomerObservable = AndroidObservable.bindFragment(this, mSearchFetcher.searchCustomer(mTenantId, mSiteId)); setRetainInstance(true); } private void showSuggestions() { UserPreferences prefs = mUserState.getCurrentUsersPreferences(); List<RecentSearch> recentGlobalSearchs= prefs.getRecentGlobalSearchs(); // Load data from list to cursor String[] columns = new String[] { "_id", "text" }; Object[] temp = new Object[] { 0, "default" }; MatrixCursor cursor = new MatrixCursor(columns); if (recentGlobalSearchs == null || recentGlobalSearchs.size() < 1) { return; } for(int i = 0; i < recentGlobalSearchs.size(); i++) { temp[0] = i; temp[1] = recentGlobalSearchs.get(i); cursor.addRow(temp); } mSearchView.setSuggestionsAdapter(new SearchSuggestionsCursorAdapter(getActivity(), cursor, recentGlobalSearchs)); mSearchView.setOnSuggestionListener(this); } private List<RecentSearch> removeDuplicateSearchItem(List<RecentSearch> searchItems, String query) { Iterator<RecentSearch> i = searchItems.iterator(); while (i.hasNext()) { RecentSearch item = i.next(); if (item.getSearchTerm().equalsIgnoreCase(query)) { i.remove(); } } return searchItems; } private void saveSearchToList(String query) { //save search to list UserPreferences prefs = mUserState.getCurrentUsersPreferences(); List<RecentSearch> recentGlobalSearchs = prefs.getRecentGlobalSearchs(); if (recentGlobalSearchs == null) { recentGlobalSearchs = new ArrayList<RecentSearch>(); } recentGlobalSearchs = removeDuplicateSearchItem(recentGlobalSearchs,query); RecentSearch search = new RecentSearch(); search.setSearchTerm(query); recentGlobalSearchs.add(0, search); if (recentGlobalSearchs.size() > MAX_NUMBER_OF_SEARCHES) { recentGlobalSearchs.remove(recentGlobalSearchs.size() - 1); } prefs.setRecentGlobalSearchs(recentGlobalSearchs); mUserState.updateUserPreferences(); } @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); if (!hidden) { ((MainActivity) getActivity()).setSearchSelected(); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_search, container, false); mOrderLoadingView = (LoadingView) mView.findViewById(R.id.order_loading_view); mProductLoadingView = (LoadingView) mView.findViewById(R.id.product_loading_view); mCustomerLoadingView = (LoadingView) mView.findViewById(R.id.customer_loading_view); mSearchEditText = (EditText) mView.findViewById(R.id.global_search); mOrdersViewButton = (Button) mView.findViewById(R.id.order_view_all); mOrdersResultCount = (TextView)mView.findViewById(R.id.order_result_count); mOrdersViewButton.setOnClickListener(new OrderViewListener()); mProductsViewButton = (Button) mView.findViewById(R.id.product_view_all); mProductsResultCount = (TextView)mView.findViewById(R.id.product_result_count); mProductsViewButton.setOnClickListener(new ProductViewListener()); mCustomersViewButton = (Button) mView.findViewById(R.id.customer_view_all); mCustomersResultCount = (TextView)mView.findViewById(R.id.customer_result_count); mCustomersViewButton.setOnClickListener(new CustomerViewListener()); mSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { String s = mSearchEditText.getText().toString(); performSearch(s); } return false; } }); mSearchImageView = (ImageView) mView.findViewById(R.id.global_search_button); mSearchImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String s = mSearchEditText.getText().toString(); performSearch(s); } }); mOrderLayout = (LinearLayout) mView.findViewById(R.id.order_layout_view); mProductLayout = (LinearLayout) mView.findViewById(R.id.product_layout_view); mCustomerLayout = (LinearLayout) mView.findViewById(R.id.customer_layout_view); mOrdersSearchView = (ListView) mView.findViewById(R.id.orders_search_list); mProductsSearchView = (ListView) mView.findViewById(R.id.products_search_list); mCustomersSearchView = (ListView) mView.findViewById(R.id.customers_search_list); mOrderAdapter = new GlobalSearchOrderAdapter(new OrderCollection()); mOrdersSearchView.setAdapter(mOrderAdapter); mOrdersSearchView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { Order order = mOrderAdapter.getItem(position); UserAuthenticationStateMachine userAuthenticationStateMachine = UserAuthenticationStateMachineProducer.getInstance(getActivity()); Intent intent = new Intent(getActivity(), OrderDetailActivity.class); intent.putExtra(OrderDetailActivity.ORDER_NUMBER_EXTRA_KEY, order.getId()); intent.putExtra(OrderDetailActivity.CURRENT_TENANT_ID, userAuthenticationStateMachine.getTenantId()); intent.putExtra(OrderDetailActivity.CURRENT_SITE_ID, userAuthenticationStateMachine.getSiteId()); startActivity(intent); } }); mProductAdapter = new GlobalSearchProductAdapter(new ProductSearchResult()); mProductsSearchView.setAdapter(mProductAdapter); mProductsSearchView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { String productCode = mProductAdapter.getItem(position).getProductCode(); Intent intent = new Intent(getActivity(), ProductDetailActivity.class); UserAuthenticationStateMachine userAuthenticationStateMachine = UserAuthenticationStateMachineProducer.getInstance(getActivity()); intent.putExtra(ProductDetailActivity.PRODUCT_CODE_EXTRA_KEY, productCode); intent.putExtra(ProductDetailActivity.CURRENT_TENANT_ID, userAuthenticationStateMachine.getTenantId()); intent.putExtra(ProductDetailActivity.CURRENT_SITE_ID, userAuthenticationStateMachine.getSiteId()); intent.putExtra(ProductDetailActivity.CURRENT_SITE_DOMAIN, userAuthenticationStateMachine.getSiteDomain()); startActivity(intent); } }); mCustomerAdapter = new GlobalSearchCustomerAdapter(new CustomerAccountCollection()); mCustomersSearchView.setAdapter(mCustomerAdapter); mCustomersSearchView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) { CustomerAccount customerAccount = mCustomerAdapter.getItem(position); Intent intent = new Intent(getActivity(), CustomerDetailActivity.class); intent.putExtra(CustomerDetailActivity.CUSTOMER_ID, customerAccount.getId()); startActivity(intent); } }); setHasOptionsMenu(true); return mView; } @Override public boolean onSuggestionSelect(int position) { return false; } @Override public boolean onSuggestionClick(int position) { UserPreferences prefs = mUserState.getCurrentUsersPreferences(); List<RecentSearch> recentGlobalSearchs = prefs.getRecentGlobalSearchs(); String selectedStr = recentGlobalSearchs.get(position).getSearchTerm(); performSearch(selectedStr); mSearchView.setQuery(selectedStr,false); return true; } public void onBackPressed() { if (TextUtils.isEmpty(mSearchView.getQuery()) && mOrderLayout.getVisibility() == View.INVISIBLE && mCustomerLayout.getVisibility() == View.INVISIBLE && mProductLayout.getVisibility() == View.INVISIBLE) { getFragmentManager().popBackStack(); } } private class OrderViewListener implements View.OnClickListener{ @Override public void onClick(View view) { if (!TextUtils.isEmpty(mOrderSearchString)) { ((GlobalSearchListener) getActivity()).onOrderLaunch(mOrderSearchString); } } } private class ProductViewListener implements View.OnClickListener{ @Override public void onClick(View view) { if(!TextUtils.isEmpty(mProductSearchString)){ mSearchMenuItem.collapseActionView(); ((GlobalSearchListener) getActivity()).launchProductSearch(mProductSearchString); } } } private class CustomerViewListener implements View.OnClickListener{ @Override public void onClick(View view) { if(!TextUtils.isEmpty(mCustomerSearchString)){ mSearchMenuItem.collapseActionView(); ((GlobalSearchListener) getActivity()).launchCustomerSearch(mCustomerSearchString); } } } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.search, menu); // Get the SearchView and set the searchable configuration SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); mSearchMenuItem = menu.findItem(R.id.search); mSearchMenuItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem menuItem) { return true; } @Override public boolean onMenuItemActionCollapse(MenuItem menuItem) { onBackPressed(); return true; } }); mSearchView = (SearchView) mSearchMenuItem.getActionView(); mSearchView.setQueryHint(getString(R.string.global_search_hint)); mSearchView.setMaxWidth(1500); mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { performSearch(s); return true; } @Override public boolean onQueryTextChange(String s) { return false; } }); mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); mSearchMenuItem.expandActionView(); showSuggestions(); mSearchView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int keyCode, KeyEvent keyEvent) { if (keyCode == KeyEvent.KEYCODE_BACK) { onBackPressed(); } return true; } }); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.search) { showSuggestions(); } return super.onOptionsItemSelected(item); } @Override public void onDestroyView() { mSubscription.unsubscribe(); super.onDestroyView(); } private void hideKeyboard() { InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); } public void performSearch(final String s){ mSearchView.clearFocus(); saveSearchToList(s); hideKeyboard(); mSearchFetcher.setQueryString(s); mOrderLayout.setVisibility(View.VISIBLE); mOrderLoadingView.setLoading(); mOrdersViewButton.setVisibility(View.INVISIBLE); mOrdersResultCount.setVisibility(View.INVISIBLE); mOrderObservable.subscribeOn(Schedulers.io()) .subscribe(new Observer<OrderCollection>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { mOrderLoadingView.setError("Failed to fetch Orders"); mOrdersViewButton.setVisibility(View.INVISIBLE); } @Override public void onNext(OrderCollection orderCollection) { if (orderCollection.getItems() != null && !orderCollection.getItems().isEmpty()) { mOrderLoadingView.success(); mOrderAdapter.setData(orderCollection); mOrderAdapter.notifyDataSetChanged(); if (orderCollection.getTotalCount() > 3) { mOrdersViewButton.setVisibility(View.VISIBLE); } else { mOrdersViewButton.setVisibility(View.INVISIBLE); } mOrderSearchString = s; mOrdersResultCount.setVisibility(View.VISIBLE); mOrdersResultCount.setText("(" + orderCollection.getTotalCount() + " items found) "); } else { mOrderLoadingView.setError("No Results found"); mOrdersViewButton.setVisibility(View.INVISIBLE); mOrdersResultCount.setVisibility(View.INVISIBLE); } } }); mProductLayout.setVisibility(View.VISIBLE); mProductLoadingView.setLoading(); mProductsViewButton.setVisibility(View.INVISIBLE); mProductsResultCount.setVisibility(View.INVISIBLE); mProductObservable. subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()). subscribe(new Observer<ProductSearchResult>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { mOrderLoadingView.setError("Failed to fetch Product"); mProductsViewButton.setVisibility(View.INVISIBLE); } @Override public void onNext(ProductSearchResult productSearchResult) { if (productSearchResult.getItems() != null && !productSearchResult.getItems().isEmpty()) { mProductLoadingView.success(); mProductAdapter.setData(productSearchResult); mProductAdapter.notifyDataSetChanged(); if (productSearchResult.getTotalCount() > 3) { mProductsViewButton.setVisibility(View.VISIBLE); } else { mProductsViewButton.setVisibility(View.INVISIBLE); } mProductSearchString = s; mProductsResultCount.setVisibility(View.VISIBLE); mProductsResultCount.setText("(" + productSearchResult.getTotalCount() + " items found) "); } else { mProductLoadingView.setError("No Results found"); mProductsViewButton.setVisibility(View.INVISIBLE); mProductsResultCount.setVisibility(View.INVISIBLE); } } }); mCustomerLayout.setVisibility(View.VISIBLE); mCustomerLoadingView.setLoading(); mCustomersViewButton.setVisibility(View.INVISIBLE); mCustomersResultCount.setVisibility(View.INVISIBLE); mCustomerObservable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()). subscribe(new Observer<CustomerAccountCollection>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { mCustomerLoadingView.setError("Failed to fetch Customers"); mCustomersViewButton.setVisibility(View.INVISIBLE); } @Override public void onNext(CustomerAccountCollection customerAccountCollection) { if (customerAccountCollection.getItems() != null && !customerAccountCollection.getItems().isEmpty()) { mCustomerLoadingView.success(); mCustomerAdapter.setData(customerAccountCollection); mCustomerAdapter.notifyDataSetChanged(); if (customerAccountCollection.getTotalCount() > 3) { mCustomersViewButton.setVisibility(View.VISIBLE); } else { mCustomersViewButton.setVisibility(View.INVISIBLE); } mCustomerSearchString = s; mCustomersResultCount.setVisibility(View.VISIBLE); mCustomersResultCount.setText("(" + customerAccountCollection.getTotalCount() + " items found) "); } else { mCustomerLoadingView.setError("No Results found"); mCustomersViewButton.setVisibility(View.INVISIBLE); mCustomersResultCount.setVisibility(View.INVISIBLE); } } }); } public interface GlobalSearchListener { public void onOrderLaunch(String searchQuery); public void launchProductSearch(String searchQuery); public void launchCustomerSearch(String searchQuery); } }