/***************************************************************************
* Copyright 2005-2009 Last.fm Ltd. *
* Portions contributed by Casey Link, Lukasz Wisniewski, *
* Mike Jennings, and Michael Novak Jr. *
* *
* 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 2 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
package fm.last.android.activity;
import java.io.IOException;
import java.util.Stack;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import fm.last.android.utils.AsyncTaskEx;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.ViewFlipper;
import android.widget.AdapterView.OnItemClickListener;
import fm.last.android.AndroidLastFmServerFactory;
import fm.last.android.LastFMApplication;
import fm.last.android.R;
import fm.last.android.activity.Event.EventActivityResult;
import fm.last.android.adapter.EventListAdapter;
import fm.last.android.adapter.ListAdapter;
import fm.last.api.Event;
import fm.last.api.LastFmServer;
import fm.last.api.WSError;
public class Profile_EventsTab extends ListActivity implements LocationListener {
// Java doesn't let you treat enums as ints easily, so we have to have this
// mess
private static final int EVENTS_MYEVENTS = 0;
private static final int EVENTS_RECOMMENDED = 1;
private static final int EVENTS_NEARME = 2;
private ListAdapter mEventsAdapter;
private String mUsername; // store this separate so we have access to it
// before User obj is retrieved
LastFmServer mServer = AndroidLastFmServerFactory.getServer();
ViewFlipper mNestedViewFlipper;
private Stack<Integer> mViewHistory;
View previousSelectedView = null;
// Animations
Animation mPushRightIn;
Animation mPushRightOut;
Animation mPushLeftIn;
Animation mPushLeftOut;
ListView[] mEventsLists = new ListView[3];
private EventActivityResult mOnEventActivityResult;
Location mLocation = null;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.events);
mUsername = getIntent().getStringExtra("user");
mViewHistory = new Stack<Integer>();
mNestedViewFlipper = (ViewFlipper) findViewById(R.id.NestedViewFlipper);
mNestedViewFlipper.setAnimateFirstView(false);
mNestedViewFlipper.setAnimationCacheEnabled(false);
getListView().requestFocus();
String[] mStrings = new String[] { getString(R.string.profile_myevents),
getString(R.string.profile_events_recommended),
getString(R.string.profile_events_nearby)}; // this
// order
// must
// match
// the
// ProfileActions
// enum
mEventsAdapter = new ListAdapter(Profile_EventsTab.this, mStrings);
getListView().setAdapter(mEventsAdapter);
// TODO should be functions and not member variables, caching is evil
mEventsLists[EVENTS_MYEVENTS] = (ListView) findViewById(R.id.myevents_list_view);
mEventsLists[EVENTS_MYEVENTS].setOnItemClickListener(mEventItemClickListener);
mEventsLists[EVENTS_RECOMMENDED] = (ListView) findViewById(R.id.recommended_list_view);
mEventsLists[EVENTS_RECOMMENDED].setOnItemClickListener(mEventItemClickListener);
mEventsLists[EVENTS_NEARME] = (ListView) findViewById(R.id.nearme_list_view);
mEventsLists[EVENTS_NEARME].setOnItemClickListener(mEventItemClickListener);
// Loading animations
mPushLeftIn = AnimationUtils.loadAnimation(this, R.anim.push_left_in);
mPushLeftOut = AnimationUtils.loadAnimation(this, R.anim.push_left_out);
mPushRightIn = AnimationUtils.loadAnimation(this, R.anim.push_right_in);
mPushRightOut = AnimationUtils.loadAnimation(this, R.anim.push_right_out);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 0 && resultCode == RESULT_OK) {
int status = data.getExtras().getInt("status", -1);
if (mOnEventActivityResult != null && status != -1) {
mOnEventActivityResult.onEventStatus(status);
}
}
}
@Override
protected void onPause() {
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
super.onPause();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (!mViewHistory.isEmpty()) {
setPreviousAnimation();
mEventsAdapter.disableLoadBar();
mNestedViewFlipper.setDisplayedChild(mViewHistory.pop());
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
return true;
}
if (event.getRepeatCount() == 0) {
finish();
return true;
}
}
return false;
}
private void setNextAnimation() {
mNestedViewFlipper.setInAnimation(mPushLeftIn);
mNestedViewFlipper.setOutAnimation(mPushLeftOut);
}
private void setPreviousAnimation() {
mNestedViewFlipper.setInAnimation(mPushRightIn);
mNestedViewFlipper.setOutAnimation(mPushRightOut);
}
public void onListItemClick(ListView l, View v, int position, long id) {
setNextAnimation();
mEventsAdapter.enableLoadBar(position);
switch (position) {
case EVENTS_MYEVENTS:
try {
LastFMApplication.getInstance().tracker.trackPageView("/Profile/Events");
} catch (Exception e) {
//Google Analytics doesn't appear to be thread safe
}
new LoadMyEventsTask().execute((Void) null);
break;
case EVENTS_RECOMMENDED:
try {
LastFMApplication.getInstance().tracker.trackPageView("/Profile/Events/Recommended");
} catch (Exception e) {
//Google Analytics doesn't appear to be thread safe
}
new LoadRecommendedEventsTask().execute((Void) null);
break;
case EVENTS_NEARME:
try {
LastFMApplication.getInstance().tracker.trackPageView("/Profile/Events/Nearby");
} catch (Exception e) {
//Google Analytics doesn't appear to be thread safe
}
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setSpeedRequired(false);
criteria.setCostAllowed(false);
String provider = lm.getBestProvider(criteria, true);
if(provider != null) {
mLocation = lm.getLastKnownLocation(provider);
lm.requestLocationUpdates(provider, 30000L, 1000.0f, this);
}
new LoadNearbyEventsTask().execute((Void) null);
break;
default:
break;
}
}
private OnItemClickListener mEventItemClickListener = new OnItemClickListener() {
public void onItemClick(final AdapterView<?> parent, final View v, final int position, long id) {
try {
final Event event = (Event) parent.getAdapter().getItem(position);
mOnEventActivityResult = new EventActivityResult() {
public void onEventStatus(int status) {
event.setStatus(String.valueOf(status));
mOnEventActivityResult = null;
}
};
startActivityForResult(fm.last.android.activity.Event.intentFromEvent(Profile_EventsTab.this, event), 0);
} catch (ClassCastException e) {
// when the list item is not an event
}
}
};
private class LoadMyEventsTask extends AsyncTaskEx<Void, Void, EventListAdapter> {
@Override
public EventListAdapter doInBackground(Void... params) {
try {
fm.last.api.Event[] events = mServer.getUserEvents(mUsername);
if (events.length > 0) {
EventListAdapter result = new EventListAdapter(Profile_EventsTab.this);
result.setEventsSource(events);
return result;
}
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(EventListAdapter result) {
if (result != null) {
mEventsLists[EVENTS_MYEVENTS].setAdapter(result);
} else {
String[] strings = new String[] { getString(R.string.profile_noevents) };
ListAdapter adapter = new ListAdapter(Profile_EventsTab.this, strings);
adapter.disableDisclosureIcons();
adapter.setDisabled();
mEventsLists[EVENTS_MYEVENTS].setAdapter(adapter);
}
mViewHistory.push(mNestedViewFlipper.getDisplayedChild()); // Save
// the
// current
// view
mNestedViewFlipper.setDisplayedChild(EVENTS_MYEVENTS + 1);
}
}
private class LoadRecommendedEventsTask extends AsyncTaskEx<Void, Void, EventListAdapter> {
@Override
public EventListAdapter doInBackground(Void... params) {
try {
fm.last.api.Event[] events = mServer.getUserRecommendedEvents(mUsername, LastFMApplication.getInstance().session.getKey());
if (events.length > 0) {
EventListAdapter result = new EventListAdapter(Profile_EventsTab.this);
result.setEventsSource(events);
return result;
}
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(EventListAdapter result) {
if (result != null) {
mEventsLists[EVENTS_RECOMMENDED].setAdapter(result);
} else {
String[] strings = new String[] { getString(R.string.profile_noevents) };
ListAdapter adapter = new ListAdapter(Profile_EventsTab.this, strings);
adapter.disableDisclosureIcons();
adapter.setDisabled();
mEventsLists[EVENTS_RECOMMENDED].setAdapter(adapter);
}
mViewHistory.push(mNestedViewFlipper.getDisplayedChild()); // Save
// the
// current
// view
mNestedViewFlipper.setDisplayedChild(EVENTS_RECOMMENDED + 1);
}
}
private class LoadNearbyEventsTask extends AsyncTaskEx<Void, Void, EventListAdapter> {
@Override
public EventListAdapter doInBackground(Void... params) {
try {
if(mLocation != null) {
String latitude = String.valueOf(mLocation.getLatitude());
String longitude = String.valueOf(mLocation.getLongitude());
fm.last.api.Event[] events = mServer.getNearbyEvents(latitude, longitude);
if (events.length > 0) {
EventListAdapter result = new EventListAdapter(Profile_EventsTab.this);
result.setEventsSource(events);
return result;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (WSError e) {
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(EventListAdapter result) {
if (result != null) {
mEventsLists[EVENTS_NEARME].setAdapter(result);
} else {
String[] strings = new String[] { getString(R.string.profile_noevents) };
ListAdapter adapter = new ListAdapter(Profile_EventsTab.this, strings);
adapter.disableDisclosureIcons();
adapter.setDisabled();
mEventsLists[EVENTS_NEARME].setAdapter(adapter);
}
if(mViewHistory.empty()) {
mViewHistory.push(mNestedViewFlipper.getDisplayedChild()); // Save
// the
// current
// view
mNestedViewFlipper.setDisplayedChild(EVENTS_NEARME + 1);
}
}
}
public void onLocationChanged(Location location) {
if(location != null) {
mLocation = location;
new LoadNearbyEventsTask().execute((Void) null);
}
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}