/*
* Tweetings - Twitter client for Android
*
* Copyright (C) 2012-2013 RBD Solutions Limited <apps@tweetings.net>
* Copyright (C) 2012 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.dwdesign.tweetings.activity;
import static com.dwdesign.tweetings.util.Utils.getDefaultAccountId;
import static com.dwdesign.tweetings.util.Utils.getTwitterInstance;
import static com.dwdesign.tweetings.util.Utils.openStatus;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.List;
import twitter4j.GeoLocation;
import twitter4j.Paging;
import twitter4j.Query;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Tweet;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import com.dwdesign.tweetings.Constants;
import com.dwdesign.tweetings.R;
import com.dwdesign.tweetings.activity.GalleryActivity.MediaTimelineTask;
import com.dwdesign.tweetings.fragment.NativeNearbyMapFragment;
import com.dwdesign.tweetings.model.ParcelableLocation;
import com.dwdesign.tweetings.model.ParcelableStatus;
import com.dwdesign.tweetings.view.ExtendedMapView;
import com.dwdesign.tweetings.events.PanChangeListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Display;
import android.widget.GridView;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
public class NativeNearbyMapActivity extends MapActivity implements Constants {
private ExtendedMapView mMapView;
private NearbySearchTask mNearbySearchTask;
private static ArrayList<ParcelableStatus> mStatuses;
private long account_id;
private Location mRecentLocation;
public static NativeNearbyMapActivity mActivity;
private LocationManager mLocationManager;
@Override
protected boolean isRouteDisplayed() {
return false;
}
public void setCenter(final Location location) {
final double lat = location.getLatitude();
final double lng = location.getLongitude();
final GeoPoint gp = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
final MapController mc = mMapView.getController();
mc.setZoom(16);
mc.animateTo(gp);
}
protected void getLocationAndCenterMap() {
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
final Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
final String provider = mLocationManager.getBestProvider(criteria, true);
mRecentLocation = null;
if (provider != null) {
mRecentLocation = mLocationManager.getLastKnownLocation(provider);
//mLocationManager.requestLocationUpdates(provider, 1000, 0, locationListener);
} else {
Toast.makeText(this, R.string.cannot_get_location, Toast.LENGTH_SHORT).show();
}
if (mRecentLocation != null) {
setCenter(mRecentLocation);
if (mNearbySearchTask != null) {
mNearbySearchTask.cancel(true);
}
mNearbySearchTask = null;
mNearbySearchTask = new NearbySearchTask(NativeNearbyMapActivity.this, account_id);
if (mNearbySearchTask != null) {
mNearbySearchTask.execute();
}
}
mMapView.invalidate();
}
private final LocationListener locationListener = new LocationListener()
{
@Override
public void onLocationChanged(Location location) {
mRecentLocation = location;
if (mRecentLocation != null) {
setCenter(mRecentLocation);
if (mNearbySearchTask != null) {
mNearbySearchTask.cancel(true);
}
mNearbySearchTask = null;
mNearbySearchTask = new NearbySearchTask(NativeNearbyMapActivity.this, account_id);
if (mNearbySearchTask != null) {
mNearbySearchTask.execute();
}
}
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
@Override
protected void onCreate(final Bundle icicle) {
super.onCreate(icicle);
final Bundle bundle = getIntent().getExtras();
mMapView = new ExtendedMapView(this, MAPS_API_KEY) {
{
setClickable(true);
}
};
mActivity = this;
final MapController mc = mMapView.getController();
mc.setZoom(16);
setContentView(mMapView);
getLocationAndCenterMap();
mMapView.addPanChangeListener(new PanChangeListener() {
@Override
public void onPan(GeoPoint old, GeoPoint current) {
if (mRecentLocation != null) {
mRecentLocation.setLatitude(microDegreesToDegrees(current.getLatitudeE6()));
mRecentLocation.setLongitude(microDegreesToDegrees(current.getLongitudeE6()));
if (mNearbySearchTask != null) {
mNearbySearchTask.cancel(true);
}
mNearbySearchTask = null;
mNearbySearchTask = new NearbySearchTask(NativeNearbyMapActivity.this, account_id);
if (mNearbySearchTask != null) {
mNearbySearchTask.execute();
}
}
}
});
account_id = getDefaultAccountId(this);
}
public static double microDegreesToDegrees(int microDegrees) {
return microDegrees / 1E6;
}
@Override
public void onDestroy() {
mStatuses = null;
if (mNearbySearchTask != null) {
mNearbySearchTask.cancel(true);
}
if (mLocationManager != null) {
//mLocationManager.removeUpdates(locationListener);
}
super.onDestroy();
}
public void setMarkers() {
if (mStatuses != null && mStatuses.size() >= 1) {
final List<Overlay> overlays = mMapView.getOverlays();
for (ParcelableStatus pStatus : mStatuses) {
ParcelableLocation location = pStatus.location;
if (location != null) {
final double lat = location.latitude, lng = location.longitude;
final GeoPoint gp = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
final Drawable d = getResources().getDrawable(R.drawable.ic_map_marker);
final Itemization markers = new Itemization(d);
final OverlayItem overlayitem = new OverlayItem(gp, "", "");
markers.addOverlay(overlayitem);
overlays.add(markers);
}
}
}
mMapView.invalidate();
}
class NearbySearchTask extends AsyncTask<Void, Void, twitter4j.Status[]> {
private final Twitter twitter;
private long account_id;
private NearbySearchTask(final Context context, final long account_id) {
twitter = getTwitterInstance(context, account_id, true);
this.account_id = account_id;
}
@Override
protected twitter4j.Status[] doInBackground(final Void... args) {
twitter4j.Status[] tweets = null;
try {
final Query query = new Query();
GeoLocation location = new GeoLocation(mRecentLocation.getLatitude(), mRecentLocation.getLongitude());
query.setGeoCode(location, 1.5, "km");
query.setRpp(50);
tweets = twitter != null ? twitter.search(query).getStatuses() : null;
} catch (final TwitterException e) {
e.printStackTrace();
}
return tweets;
}
@Override
protected void onCancelled() {
setProgressBarIndeterminateVisibility(false);
super.onCancelled();
}
@Override
protected void onPostExecute(final twitter4j.Status[] tweets) {
if (tweets == null) return;
if (mStatuses == null) {
mStatuses = new ArrayList<ParcelableStatus>();
}
if (tweets != null) {
final int size = tweets.length;
for (int i = 0; i < size; i++) {
final twitter4j.Status tweet = tweets[i];
ParcelableStatus pStatus = new ParcelableStatus(tweet, account_id, false);
if (pStatus != null) {
mStatuses.add(pStatus);
}
}
}
setMarkers();
setProgressBarIndeterminateVisibility(false);
super.onPostExecute(tweets);
}
@Override
protected void onPreExecute() {
setProgressBarIndeterminateVisibility(true);
super.onPreExecute();
}
}
static class Itemization extends ItemizedOverlay<OverlayItem> {
private final ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
public Itemization(final Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
public void addOverlay(final OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
public int size() {
return mOverlays.size();
}
@Override
protected boolean onTap(final int index) {
OverlayItem item = mOverlays.get(index);
GeoPoint geoLocation = item.getPoint();
for (ParcelableStatus pStatus : mStatuses) {
ParcelableLocation statusLocation = pStatus.location;
DecimalFormat twoDForm = new DecimalFormat("#.######");
double latitude = Double.valueOf(twoDForm.format(statusLocation.latitude));
double longitude = Double.valueOf(twoDForm.format(statusLocation.longitude));
double locationLatitude = Double.valueOf(microDegreesToDegrees(geoLocation.getLatitudeE6()));
double locationLongitude = Double.valueOf(microDegreesToDegrees(geoLocation.getLongitudeE6()));
if ((latitude == locationLatitude && longitude == locationLongitude) ||
(statusLocation.latitude == microDegreesToDegrees(geoLocation.getLatitudeE6()) && statusLocation.longitude == microDegreesToDegrees(geoLocation.getLongitudeE6()))) {
openStatus(mActivity, pStatus);
break;
}
}
return true;
}
@Override
protected OverlayItem createItem(final int i) {
return mOverlays.get(i);
}
protected static Drawable boundCenterBottom(final Drawable d) {
d.setBounds(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight(), d.getIntrinsicWidth() / 2, 0);
return d;
}
}
}