private void fetchRecentStations() {
    LastFmServer server = AndroidLastFmServerFactory.getServer();

    Session session = LastFMApplication.getInstance().session;
    // Is it worth it?
    if (session != null) {
      try {
        // Let me work it
        Station stations[] = server.getUserRecentStations(session.getName(), session.getKey());
        if (stations != null && stations.length > 0) {
          // I put my thing down, flip it, and reverse it
          List<Station> list = Arrays.asList(stations);
          Collections.reverse(list);
          stations = (Station[]) list.toArray();
          RecentStationsDao.getInstance().clearTable();
          for (Station station : stations) {
            RecentStationsDao.getInstance()
                .appendRecentStation(station.getUrl(), station.getName());
          }
        }
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
    @Override
    public Boolean doInBackground(Void... params) {
      boolean success = false;
      Session session = LastFMApplication.getInstance().session;

      // Check our subscriber status
      LastFmServer server = AndroidLastFmServerFactory.getServer();
      try {
        fetchRecentStations();
        User user = server.getUserInfo(null, session.getKey());
        if (user != null) {
          String subscriber = user.getSubscriber();
          SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
          SharedPreferences.Editor editor = settings.edit();
          editor.putString("lastfm_subscriber", subscriber);
          editor.commit();
          session = new Session(session.getName(), session.getKey(), subscriber);
          LastFMApplication.getInstance().session = session;
        }
      } catch (WSError e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      try {
        if (mUsername == null) {
          mUser = mServer.getUserInfo(null, session.getKey());
        } else {
          mUser = mServer.getUserInfo(mUsername, null);
          tasteometer = mServer.tasteometerCompare(mUsername, session.getName(), 8);
        }
        success = true;
      } catch (Exception e) {
        e.printStackTrace();
      }
      return success;
    }
  @Override
  protected void onListItemClick(ListView l, View v, int position, long id) {
    Intent intent = null;
    Integer i = (Integer) getListAdapter().getItem(position);

    switch (i) {
      case R.drawable.info_dark:
        intent = new Intent(this, Metadata.class);
        intent.putExtra("artist", mArtistName);
        intent.putExtra("track", mTrackName);
        startActivity(intent);
        break;
      case R.drawable.list_radio_icon_rest:
        ((ListAdapter) getListAdapter()).enableLoadBar(position);
        LastFMApplication.getInstance()
            .playRadioStation(
                this, "lastfm://artist/" + Uri.encode(mArtistName) + "/similarartists", true);
        return;
      case R.drawable.share_dark:
        intent = new Intent(this, ShareResolverActivity.class);
        intent.putExtra("lastfm.artist", mArtistName);
        if (mTrackName != null) intent.putExtra("lastfm.track", mTrackName);
        if (mAlbumName != null) intent.putExtra("lastfm.album", mAlbumName);
        startActivity(intent);
        break;
      case R.drawable.tag_dark:
        intent = new Intent(this, Tag.class);
        intent.putExtra("lastfm.artist", mArtistName);
        intent.putExtra("lastfm.track", mTrackName);
        startActivity(intent);
        break;
      case R.drawable.love:
        try {
          LastFmServer server = AndroidLastFmServerFactory.getServer();
          server.loveTrack(
              mArtistName, mTrackName, LastFMApplication.getInstance().session.getKey());
          Toast.makeText(
                  LastFMApplication.getInstance(),
                  getString(R.string.scrobbler_trackloved),
                  Toast.LENGTH_SHORT)
              .show();
        } catch (Exception e) {
        }
        break;
      case R.drawable.ban:
        try {
          LastFmServer server = AndroidLastFmServerFactory.getServer();
          server.banTrack(
              mArtistName, mTrackName, LastFMApplication.getInstance().session.getKey());
          Toast.makeText(
                  LastFMApplication.getInstance(),
                  getString(R.string.scrobbler_trackbanned),
                  Toast.LENGTH_SHORT)
              .show();
        } catch (Exception e) {
        }
        break;
      case R.drawable.shopping_cart_dark:
        if (getIntent().getBooleanExtra("lastfm.nowplaying", false)) {
          try {
            LastFMApplication.getInstance()
                .tracker
                .trackEvent(
                    "Clicks", // Category
                    "widget-buy", // Action
                    "", // Label
                    0); // Value
          } catch (Exception e) {
            // Google Analytics doesn't appear to be thread safe
          }
        } else {
          try {
            LastFMApplication.getInstance()
                .tracker
                .trackEvent(
                    "Clicks", // Category
                    "charts-buy", // Action
                    "", // Label
                    0); // Value
          } catch (Exception e) {
            // Google Analytics doesn't appear to be thread safe
          }
        }
        if (mTrackName != null) Amazon.searchForTrack(this, mArtistName, mTrackName);

        if (mAlbumName != null) Amazon.searchForAlbum(this, mArtistName, mAlbumName);
        break;
      default:
        break;
    }
    finish();
  }
  private static void performSync(
      Context context,
      Account account,
      Bundle extras,
      String authority,
      ContentProviderClient provider,
      SyncResult syncResult)
      throws OperationCanceledException {
    HashMap<Long, SyncEntry> localEvents = new HashMap<Long, SyncEntry>();
    ArrayList<Long> lastfmEvents = new ArrayList<Long>();
    mContentResolver = context.getContentResolver();

    // If our app has requested a full sync, we're going to delete all our local contacts and start
    // over
    boolean is_full_sync =
        PreferenceManager.getDefaultSharedPreferences(LastFMApplication.getInstance())
            .getBoolean("do_full_sync", false);

    // If our schema is out-of-date, do a fresh sync
    if (PreferenceManager.getDefaultSharedPreferences(LastFMApplication.getInstance())
            .getInt("sync_schema", 0)
        < syncSchema) is_full_sync = true;

    long calendar_id = getCalendar(account);
    if (calendar_id == -1) {
      Log.e("CalendarSyncAdapter", "Unable to create Last.fm event calendar");
      return;
    }

    Log.i("CalendarSyncAdapter", "Last.fm events calendar: " + calendar_id);

    // Load the local Last.fm events
    Uri eventsUri =
        Events.CONTENT_URI
            .buildUpon()
            .appendQueryParameter(Events.CALENDAR_ID, String.valueOf(calendar_id))
            .build();
    Cursor c1 =
        mContentResolver.query(
            eventsUri, new String[] {Events._ID, Events._SYNC_ID}, null, null, null);
    while (c1 != null && c1.moveToNext()) {
      if (is_full_sync) {
        deleteEvent(context, account, c1.getLong(0));
      } else {
        SyncEntry entry = new SyncEntry();
        entry.raw_id = c1.getLong(0);
        localEvents.put(c1.getLong(1), entry);
      }
    }
    c1.close();

    Editor editor =
        PreferenceManager.getDefaultSharedPreferences(LastFMApplication.getInstance()).edit();
    editor.remove("do_full_sync");
    editor.putInt("sync_schema", syncSchema);
    editor.commit();

    LastFmServer server = AndroidLastFmServerFactory.getServer();
    try {
      Event[] events = server.getUserEvents(account.name);
      ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
      for (Event event : events) {
        lastfmEvents.add(Long.valueOf(event.getId()));

        if (localEvents.containsKey(Long.valueOf(event.getId()))) {
          SyncEntry entry = localEvents.get(Long.valueOf(event.getId()));
          operationList.add(updateEvent(calendar_id, account, event, entry.raw_id));
        } else {
          operationList.add(updateEvent(calendar_id, account, event, -1));
        }

        if (operationList.size() >= 50) {
          try {
            mContentResolver.applyBatch(CalendarContract.AUTHORITY, operationList);
          } catch (Exception e) {
            e.printStackTrace();
          }
          operationList.clear();
        }
      }

      events = server.getPastUserEvents(account.name);
      for (Event event : events) {
        lastfmEvents.add(Long.valueOf(event.getId()));

        if (localEvents.containsKey(Long.valueOf(event.getId()))) {
          SyncEntry entry = localEvents.get(Long.valueOf(event.getId()));
          operationList.add(updateEvent(calendar_id, account, event, entry.raw_id));
        } else {
          operationList.add(updateEvent(calendar_id, account, event, -1));
        }

        if (operationList.size() >= 50) {
          try {
            mContentResolver.applyBatch(CalendarContract.AUTHORITY, operationList);
          } catch (Exception e) {
            e.printStackTrace();
          }
          operationList.clear();
        }
      }

      if (operationList.size() > 0) {
        try {
          mContentResolver.applyBatch(CalendarContract.AUTHORITY, operationList);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    } catch (IOException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    } catch (WSError e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }

    Iterator<Long> i = localEvents.keySet().iterator();
    while (i.hasNext()) {
      Long event = i.next();
      if (!lastfmEvents.contains(event))
        deleteEvent(context, account, localEvents.get(event).raw_id);
    }
  }
public class Profile_RadioTab extends ListActivity {

  private SeparatedListAdapter mMainAdapter;
  private LastFMStreamAdapter mMyStationsAdapter;
  private LastFMStreamAdapter mMyRecentAdapter;
  private User mUser;
  private String mUsername; // store this separate so we have access to it
  // before User obj is retrieved
  private boolean isAuthenticatedUser;
  LastFmServer mServer = AndroidLastFmServerFactory.getServer();

  private IntentFilter mIntentFilter;

  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    mUsername = getIntent().getStringExtra("user");
    isAuthenticatedUser = getIntent().getBooleanExtra("authenticated", false);

    getListView().setDivider(new ColorDrawable(0xffd9d7d7));
    getListView().setSelector(new ColorDrawable(0x00000000));
    getListView().requestFocus();

    mMyRecentAdapter = new LastFMStreamAdapter(this);

    new LoadUserTask().execute((Void) null);
    SetupMyStations();

    mIntentFilter = new IntentFilter();
    mIntentFilter.addAction(RadioPlayerService.PLAYBACK_ERROR);
    mIntentFilter.addAction(RadioPlayerService.STATION_CHANGED);
    mIntentFilter.addAction("fm.last.android.ERROR");
  }

  private void fetchRecentStations() {
    LastFmServer server = AndroidLastFmServerFactory.getServer();

    Session session = LastFMApplication.getInstance().session;
    // Is it worth it?
    if (session != null) {
      try {
        // Let me work it
        Station stations[] = server.getUserRecentStations(session.getName(), session.getKey());
        if (stations != null && stations.length > 0) {
          // I put my thing down, flip it, and reverse it
          List<Station> list = Arrays.asList(stations);
          Collections.reverse(list);
          stations = (Station[]) list.toArray();
          RecentStationsDao.getInstance().clearTable();
          for (Station station : stations) {
            RecentStationsDao.getInstance()
                .appendRecentStation(station.getUrl(), station.getName());
          }
        }
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }

  private class LoadUserTask extends AsyncTaskEx<Void, Void, Boolean> {
    Tasteometer tasteometer;

    @Override
    public Boolean doInBackground(Void... params) {
      boolean success = false;
      Session session = LastFMApplication.getInstance().session;

      // Check our subscriber status
      LastFmServer server = AndroidLastFmServerFactory.getServer();
      try {
        fetchRecentStations();
        User user = server.getUserInfo(null, session.getKey());
        if (user != null) {
          String subscriber = user.getSubscriber();
          SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
          SharedPreferences.Editor editor = settings.edit();
          editor.putString("lastfm_subscriber", subscriber);
          editor.commit();
          session = new Session(session.getName(), session.getKey(), subscriber);
          LastFMApplication.getInstance().session = session;
        }
      } catch (WSError e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      try {
        if (mUsername == null) {
          mUser = mServer.getUserInfo(null, session.getKey());
        } else {
          mUser = mServer.getUserInfo(mUsername, null);
          tasteometer = mServer.tasteometerCompare(mUsername, session.getName(), 8);
        }
        success = true;
      } catch (Exception e) {
        e.printStackTrace();
      }
      return success;
    }

    @Override
    public void onPostExecute(Boolean result) {
      Session session = LastFMApplication.getInstance().session;
      if (session != null) {
        SetupRecentStations();

        if (!isAuthenticatedUser && Profile_RadioTab.this.mUser != null) {
          SetupCommonArtists(tasteometer);
        }
        mMainAdapter.notifyDataSetChanged();
      }
    }
  }

  void SetupCommonArtists(Tasteometer ts) {
    mMyRecentAdapter.resetList();

    if (ts != null) {
      for (String name : ts.getResults()) {
        String url = "lastfm://artist/" + Uri.encode(name) + "/similarartists";
        mMyRecentAdapter.putStation(name, url);
      }
    }

    mMyRecentAdapter.updateModel();
  }

  private void RebuildMainMenu() {
    SetupMyStations();

    mMainAdapter = new SeparatedListAdapter(this);
    mMyStationsAdapter.container = mMainAdapter;
    mMyRecentAdapter.container = mMainAdapter;
    if (isAuthenticatedUser) {
      mMainAdapter.addSection(getString(R.string.profile_mystations), mMyStationsAdapter);
      if (mMyRecentAdapter.getCount() > 0) {
        mMainAdapter.addSection(getString(R.string.profile_recentstations), mMyRecentAdapter);
      }
    } else {
      mMainAdapter.addSection(
          getString(R.string.profile_userstations, mUsername), mMyStationsAdapter);
      mMainAdapter.addSection(getString(R.string.profile_commonartists), mMyRecentAdapter);
    }
    if (mMyStationsAdapter != null && mMyStationsAdapter.getCount() > 0)
      mMyStationsAdapter.updateNowPlaying();
    if (mMyRecentAdapter != null && mMyRecentAdapter.getCount() > 0)
      mMyRecentAdapter.updateNowPlaying();
    setListAdapter(mMainAdapter);
    mMainAdapter.notifyDataSetChanged();
  }

  @Override
  public void onResume() {
    registerReceiver(mStatusListener, mIntentFilter);

    SetupRecentStations();
    RebuildMainMenu();
    mMainAdapter.disableLoadBar();
    getListView().setEnabled(true);
    mMainAdapter.notifyDataSetChanged();

    super.onResume();
  }

  @Override
  protected void onPause() {
    unregisterReceiver(mStatusListener);
    super.onPause();
  }

  private BroadcastReceiver mStatusListener =
      new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

          String action = intent.getAction();
          if (action.equals(RadioPlayerService.PLAYBACK_ERROR)
              || action.equals("fm.last.android.ERROR")) {
            // see also repeated code one page above in OnResume
            RebuildMainMenu();
            mMainAdapter.disableLoadBar();
          } else if (action.equals(RadioPlayerService.STATION_CHANGED)) {
            // Update now playing buttons after the service is re-bound
            SetupRecentStations();
            RebuildMainMenu();
          }
        }
      };

  private void SetupRecentStations() {
    if (!isAuthenticatedUser) return;
    SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);
    mMyRecentAdapter.resetList();
    List<Station> stations = RecentStationsDao.getInstance().getRecentStations();
    if (stations != null) {
      for (Station station : stations) {
        String name = station.getName();
        String url = station.getUrl();

        if (url.startsWith("lastfm://playlist/") && settings.getBoolean("remove_playlists", false))
          continue;
        if (url.startsWith("lastfm://usertags/") && settings.getBoolean("remove_tags", false))
          continue;
        if (url.endsWith("/loved") && settings.getBoolean("remove_loved", false)) continue;
        mMyRecentAdapter.putStation(name, url);
      }
    }
    mMyRecentAdapter.updateModel();
  }

  private void SetupMyStations() {
    SharedPreferences settings = getSharedPreferences(LastFm.PREFS, 0);

    Session session = LastFMApplication.getInstance().session;
    mMyStationsAdapter = new LastFMStreamAdapter(this);
    if (isAuthenticatedUser) {
      mMyStationsAdapter.putStation(
          getString(R.string.profile_mylibrary),
          "lastfm://user/" + Uri.encode(mUsername) + "/personal");
      if (!settings.getBoolean("remove_loved", false) && session.getSubscriber().equals("1"))
        mMyStationsAdapter.putStation(
            getString(R.string.profile_myloved),
            "lastfm://user/" + Uri.encode(mUsername) + "/loved");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_myrecs),
          "lastfm://user/" + Uri.encode(mUsername) + "/recommended");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_mymix), "lastfm://user/" + Uri.encode(mUsername) + "/mix");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_myneighborhood),
          "lastfm://user/" + Uri.encode(mUsername) + "/neighbours");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_myfriends),
          "lastfm://user/" + Uri.encode(mUsername) + "/friends");
    } else {
      mMyStationsAdapter.putStation(
          getString(R.string.profile_userlibrary, mUsername),
          "lastfm://user/" + Uri.encode(mUsername) + "/personal");
      if (!settings.getBoolean("remove_loved", false) && session.getSubscriber().equals("1"))
        mMyStationsAdapter.putStation(
            getString(R.string.profile_userloved, mUsername),
            "lastfm://user/" + Uri.encode(mUsername) + "/loved");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_myrecs),
          "lastfm://user/" + Uri.encode(mUsername) + "/recommended");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_usermix, mUsername),
          "lastfm://user/" + Uri.encode(mUsername) + "/mix");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_userneighborhood, mUsername),
          "lastfm://user/" + Uri.encode(mUsername) + "/neighbours");
      mMyStationsAdapter.putStation(
          getString(R.string.profile_userfriends, mUsername),
          "lastfm://user/" + Uri.encode(mUsername) + "/friends");
    }

    mMyStationsAdapter.updateModel();
  }

  @Override
  public void onListItemClick(ListView l, View v, int p, long id) {
    final int position = p;

    if (!mMainAdapter.isEnabled(position)) return;

    LastFMApplication.getInstance()
        .bindService(
            new Intent(
                LastFMApplication.getInstance(), fm.last.android.player.RadioPlayerService.class),
            new ServiceConnection() {
              public void onServiceConnected(ComponentName comp, IBinder binder) {
                IRadioPlayer player = IRadioPlayer.Stub.asInterface(binder);
                try {
                  String adapter_station = mMainAdapter.getStation(position);
                  String current_station = player.getStationUrl();
                  if ((player.isPlaying() || player.getState() == RadioPlayerService.STATE_PAUSED)
                      && adapter_station.equals(current_station)) {
                    if (player.getState() == RadioPlayerService.STATE_PAUSED)
                      LastFMApplication.getInstance()
                          .playRadioStation(Profile_RadioTab.this, player.getStationUrl(), false);
                    Intent intent = new Intent(Profile_RadioTab.this, Player.class);
                    startActivity(intent);
                  } else {
                    mMainAdapter.enableLoadBar(position);
                    LastFMApplication.getInstance()
                        .playRadioStation(Profile_RadioTab.this, adapter_station, true);
                  }
                } catch (Exception e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
                }
                LastFMApplication.getInstance().unbindService(this);
              }

              public void onServiceDisconnected(ComponentName comp) {}
            },
            Context.BIND_AUTO_CREATE);
  }
}