package net.osmand.plus.activities.search;
import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Formatter;
import java.util.List;
import java.util.Locale;
import net.osmand.access.AccessibilityAssistant;
import net.osmand.access.NavigationInfo;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmAndLocationProvider;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.FavoritesListActivity;
import net.osmand.plus.activities.FavoritesListFragment;
import net.osmand.plus.activities.NavigatePointFragment;
import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import net.osmand.util.Algorithms;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar.OnNavigationListener;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
public class SearchActivity extends TabActivity implements OsmAndLocationListener {
public static final int POI_TAB_INDEX = 0;
public static final int ADDRESS_TAB_INDEX = 1;
public static final int LOCATION_TAB_INDEX = 2;
public static final int FAVORITES_TAB_INDEX = 3;
public static final int HISTORY_TAB_INDEX = 4;
protected static final int POSITION_CURRENT_LOCATION = 1;
protected static final int POSITION_LAST_MAP_VIEW = 2;
protected static final int POSITION_FAVORITES = 3;
protected static final int POSITION_ADDRESS = 4;
private static final int REQUEST_FAVORITE_SELECT = 1;
private static final int REQUEST_ADDRESS_SELECT = 2;
public static final String SEARCH_NEARBY = "net.osmand.search_nearby"; //$NON-NLS-1$
public static final String SEARCH_LAT = "net.osmand.search_lat"; //$NON-NLS-1$
public static final String SEARCH_LON = "net.osmand.search_lon"; //$NON-NLS-1$
public static final String SHOW_ONLY_ONE_TAB = "SHOW_ONLY_ONE_TAB"; //$NON-NLS-1$
Button searchPOIButton;
private LatLon searchPoint = null;
private LatLon reqSearchPoint = null;
private boolean searchAroundCurrentLocation = false;
private static boolean searchOnLine = false;
private ArrayAdapter<String> spinnerAdapter;
private OsmandSettings settings;
List<WeakReference<Fragment>> fragList = new ArrayList<WeakReference<Fragment>>();
private boolean showOnlyOneTab;
private AccessibilityAssistant accessibilityAssistant;
private NavigationInfo navigationInfo;
private View spinnerView;
public interface SearchActivityChild {
public void locationUpdate(LatLon l);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
((OsmandApplication) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
long t = System.currentTimeMillis();
setContentView(R.layout.tab_content);
settings = ((OsmandApplication) getApplication()).getSettings();
accessibilityAssistant = new AccessibilityAssistant(this);
navigationInfo = new NavigationInfo((OsmandApplication)getApplication());
showOnlyOneTab = getIntent() != null && getIntent().getBooleanExtra(SHOW_ONLY_ONE_TAB, false);
getSupportActionBar().setTitle("");
getSupportActionBar().setElevation(0);
Integer tab = settings.SEARCH_TAB.get();
if (!showOnlyOneTab) {
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
PagerSlidingTabStrip mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tabs);
List<TabItem> mTabs = new ArrayList<TabItem>();
mTabs.add(getTabIndicator(R.string.poi, getFragment(POI_TAB_INDEX)));
mTabs.add(getTabIndicator(R.string.address, getFragment(ADDRESS_TAB_INDEX)));
mTabs.add(getTabIndicator(R.string.shared_string_location, getFragment(LOCATION_TAB_INDEX)));
mTabs.add(getTabIndicator(R.string.favorite, getFragment(FAVORITES_TAB_INDEX)));
mTabs.add(getTabIndicator(R.string.shared_string_history, getFragment(HISTORY_TAB_INDEX)));
setViewPagerAdapter(mViewPager, mTabs);
mSlidingTabLayout.setViewPager(mViewPager);
mViewPager.setCurrentItem(Math.min(tab, HISTORY_TAB_INDEX));
mSlidingTabLayout.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
settings.SEARCH_TAB.set(arg0);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
} else {
setContentView(R.layout.search_activity_single);
Class<?> cl = getFragment(tab);
try {
getSupportFragmentManager().beginTransaction().replace(R.id.layout, (Fragment) cl.newInstance()).commit();
} catch (InstantiationException e) {
throw new IllegalStateException(e);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
setTopSpinner();
Log.i("net.osmand", "Start on create " + (System.currentTimeMillis() - t ));
Intent intent = getIntent();
OsmandSettings settings = ((OsmandApplication) getApplication()).getSettings();
LatLon last = settings.getLastKnownMapLocation();
if (intent != null) {
double lat = intent.getDoubleExtra(SEARCH_LAT, 0);
double lon = intent.getDoubleExtra(SEARCH_LON, 0);
if (lat != 0 || lon != 0) {
LatLon l = new LatLon(lat, lon);
if(!Algorithms.objectEquals(reqSearchPoint, l)){
reqSearchPoint = l;
if ((Math.abs(lat - last.getLatitude()) < 0.00001) && (Math.abs(lon - last.getLongitude()) < 0.00001)) {
updateSearchPoint(reqSearchPoint, getString(R.string.select_search_position) + " " + getString(R.string.search_position_map_view), false);
} else {
updateSearchPoint(reqSearchPoint, getString(R.string.select_search_position) + " ", true);
}
}
}
}
if(searchPoint == null){
if(!Algorithms.objectEquals(reqSearchPoint, last)){
reqSearchPoint = last;
updateSearchPoint(last, getString(R.string.select_search_position) + " " + getString(R.string.search_position_map_view), false);
}
}
}
protected Class<?> getFragment(int tab) {
if(tab == POI_TAB_INDEX) {
return SearchPoiFilterFragment.class;
} else if(tab == ADDRESS_TAB_INDEX) {
// return searchOnLine ? SearchAddressOnlineFragment.class : SearchAddressFragment.class;
return SearchAddressFragment.class;
} else if(tab == LOCATION_TAB_INDEX) {
return NavigatePointFragment.class;
} else if(tab == HISTORY_TAB_INDEX) {
return SearchHistoryFragment.class;
} else if(tab == FAVORITES_TAB_INDEX) {
return FavoritesListFragment.class;
}
return SearchPoiFilterFragment.class;
}
public AccessibilityAssistant getAccessibilityAssistant() {
return accessibilityAssistant;
}
public NavigationInfo getNavigationInfo() {
return navigationInfo;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
finish();
return true;
}
return false;
}
private void setTopSpinner() {
spinnerAdapter = new ArrayAdapter<String>(getSupportActionBar().getThemedContext(), R.layout.spinner_item,
new ArrayList<String>(Arrays.asList(new String[]{
getString(R.string.search_position_undefined),
getString(R.string.shared_string_my_location) + getString(R.string.shared_string_ellipsis),
getString(R.string.search_position_map_view),
getString(R.string.search_position_favorites),
getString(R.string.search_position_address)
}))
) {
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View itemView = super.getDropDownView(position, convertView, parent);
ViewCompat.setAccessibilityDelegate(itemView, accessibilityAssistant);
return itemView;
}
};
spinnerAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinnerView = LayoutInflater.from(spinnerAdapter.getContext()).inflate(R.layout.spinner_item, null);
getSupportActionBar().setListNavigationCallbacks(spinnerAdapter, new OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int position, long itemId) {
if (position != 0) {
if (position == POSITION_CURRENT_LOCATION) {
net.osmand.Location loc = getLocationProvider().getLastKnownLocation();
searchAroundCurrentLocation = true;
if(loc != null && System.currentTimeMillis() - loc.getTime() < 10000) {
updateLocation(loc);
}
startSearchCurrentLocation();
} else {
searchAroundCurrentLocation = false;
endSearchCurrentLocation();
if (position == POSITION_LAST_MAP_VIEW) {
updateSearchPoint(settings.getLastKnownMapLocation(), getString(R.string.select_search_position) + " " + getString(R.string.search_position_map_view), false);
} else if (position == POSITION_FAVORITES) {
Intent intent = new Intent(SearchActivity.this, FavoritesListActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(FavoritesListFragment.SELECT_FAVORITE_POINT_INTENT_KEY, (Serializable) null);
startActivityForResult(intent, REQUEST_FAVORITE_SELECT);
getSupportActionBar().setSelectedNavigationItem(0);
} else if (position == POSITION_ADDRESS) {
Intent intent = new Intent(SearchActivity.this, SearchAddressActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.putExtra(SearchAddressFragment.SELECT_ADDRESS_POINT_INTENT_KEY, (String) null);
startActivityForResult(intent, REQUEST_ADDRESS_SELECT);
getSupportActionBar().setSelectedNavigationItem(0);
}
}
}
return true;
}
});
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_FAVORITE_SELECT && resultCode == FavoritesListFragment.SELECT_FAVORITE_POINT_RESULT_OK){
FavouritePoint p = (FavouritePoint) data.getSerializableExtra(FavoritesListFragment.SELECT_FAVORITE_POINT_INTENT_KEY);
if (p != null) {
LatLon latLon = new LatLon(p.getLatitude(), p.getLongitude());
updateSearchPoint(latLon, getString(R.string.select_search_position) + " " + p.getName(), false);
}
} else if(requestCode == REQUEST_ADDRESS_SELECT && resultCode == SearchAddressFragment.SELECT_ADDRESS_POINT_RESULT_OK){
String name = data.getStringExtra(SearchAddressFragment.SELECT_ADDRESS_POINT_INTENT_KEY);
LatLon latLon = new LatLon(
data.getDoubleExtra(SearchAddressFragment.SELECT_ADDRESS_POINT_LAT, 0),
data.getDoubleExtra(SearchAddressFragment.SELECT_ADDRESS_POINT_LON, 0));
if(name != null){
updateSearchPoint(latLon, getString(R.string.select_search_position) + " " + name, false);
} else {
updateSearchPoint(latLon, getString(R.string.select_search_position) + " ", true);
}
}
}
public Toolbar getClearToolbar(boolean visible) {
final Toolbar tb = (Toolbar) findViewById(R.id.bottomControls);
tb.setTitle(null);
tb.getMenu().clear();
tb.setVisibility(visible? View.VISIBLE : View.GONE);
return tb;
}
public void updateLocation(net.osmand.Location location){
if (location != null) {
navigationInfo.updateLocation(location);
updateSearchPoint(new LatLon(location.getLatitude(), location.getLongitude()),
getString(R.string.select_search_position) + " " + getString(R.string.search_position_current_location_found), false);
// don't stop in case we want to see updates
// if (location.getAccuracy() < 20) {
// endSearchCurrentLocation();
// }
}
}
public void startSearchCurrentLocation(){
getLocationProvider().resumeAllUpdates();
getLocationProvider().addLocationListener(this);
updateSearchPoint(null,
getString(R.string.search_position_current_location_search), false);
}
private OsmAndLocationProvider getLocationProvider() {
return ((OsmandApplication) getApplication()).getLocationProvider();
}
public void endSearchCurrentLocation(){
getLocationProvider().pauseAllUpdates();
getLocationProvider().removeLocationListener(this);
}
@Override
protected void onResume() {
super.onResume();
if (!showOnlyOneTab) {
Integer tab = settings.SEARCH_TAB.get();
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setCurrentItem(Math.min(tab, HISTORY_TAB_INDEX));
}
}
@Override
protected void onPause() {
super.onPause();
endSearchCurrentLocation();
}
private String formatLatLon(LatLon searchPoint){
return new Formatter(Locale.US).format(" %.2f;%.2f", searchPoint.getLatitude(), searchPoint.getLongitude()).toString();
}
@Override
public void onAttachFragment (Fragment fragment) {
fragList.add(new WeakReference<Fragment>(fragment));
}
public void updateSearchPoint(LatLon searchPoint, String message, boolean showLoc){
String oldState = spinnerAdapter.getItem(0);
String newState = message;
if(showLoc && searchPoint != null){
newState += formatLatLon(searchPoint);
}
accessibilityAssistant.lockEvents();
if (!oldState.equals(newState)) {
spinnerAdapter.remove(oldState);
spinnerAdapter.insert(newState, 0);
}
this.searchPoint = searchPoint;
for(WeakReference<Fragment> ref : fragList) {
Fragment f = ref.get();
if(f instanceof SearchActivityChild) {
if(!f.isDetached()) {
((SearchActivityChild) f).locationUpdate(searchPoint);
}
}
}
getSupportActionBar().setSelectedNavigationItem(0);
accessibilityAssistant.unlockEvents();
}
public LatLon getSearchPoint() {
return searchPoint;
}
public boolean isSearchAroundCurrentLocation() {
return searchAroundCurrentLocation;
}
public void startSearchAddressOffline(){
searchOnLine = false;
setAddressSpecContent();
}
public void startSearchAddressOnline(){
searchOnLine = true;
setAddressSpecContent();
}
public void setAddressSpecContent() {
Intent intent = getIntent();
finish();
startActivity(intent);
}
}