package net.rdrei.android.scdl2.ui;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.StandardExceptionParser;
import com.google.android.gms.analytics.Tracker;
import com.google.inject.Inject;
import net.rdrei.android.scdl2.R;
import net.rdrei.android.scdl2.api.MediaDownloadType;
import net.rdrei.android.scdl2.api.MediaState;
import net.rdrei.android.scdl2.api.PendingDownload;
import roboguice.activity.RoboFragmentActivity;
import roboguice.inject.InjectView;
import roboguice.util.Ln;
/**
* Dispatches a download request to either the single download or playlist download fragment.
*/
public class DownloadActivity extends RoboFragmentActivity implements DownloadMediaContract {
public static final String ANALYTICS_TAG = "DOWNLOAD_TRACK";
public static final String MEDIA_STATE_TAG = "scdl:MEDIA_STATE_TAG";
public static final String MAIN_LAYOUT_FRAGMENT = "MAIN_LAYOUT_FRAGMENT";
private MediaState mMediaState = MediaState.UNKNOWN;
private boolean mIsPostSaveInstanceState = false;
@InjectView(R.id.outer_layout)
private ViewGroup mOuterLayout;
@Inject
private AdViewManager mAdViewManager;
@Inject
private Tracker mTracker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
if (savedInstanceState != null) {
mMediaState = savedInstanceState.getParcelable(MEDIA_STATE_TAG);
} else {
CommonMenuFragment.injectMenu(this);
}
if (mMediaState == MediaState.UNKNOWN) {
Ln.d("No previous state. Starting media resolver.");
final AbstractPendingDownloadResolver task = new PendingDownloadResolver(this);
task.execute();
}
mAdViewManager.addToViewIfRequired(mOuterLayout);
}
@Override
protected void onResumeFragments() {
super.onResumeFragments();
mIsPostSaveInstanceState = false;
loadMediaFragments();
}
@Override
protected void onPause() {
super.onPause();
// Apparently, it's safer to do this here.
mIsPostSaveInstanceState = true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(MEDIA_STATE_TAG, mMediaState);
}
/**
* Load the correct fragment based on what MediaState we currently have.
*/
protected void loadMediaFragments() {
final Fragment newFragment;
if (mIsPostSaveInstanceState) {
Ln.i("Skipping fragment loading since Activity has already been saved.");
return;
}
if (mMediaState.getType() == MediaDownloadType.TRACK) {
newFragment = DownloadTrackFragment.newInstance(mMediaState);
mTracker.send(new HitBuilders.EventBuilder().setCategory(ANALYTICS_TAG)
.setAction("LOADED")
.build()
);
} else {
newFragment = SimpleLoadingFragment.newInstance();
}
newFragment.setRetainInstance(true);
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_layout, newFragment, MAIN_LAYOUT_FRAGMENT)
.disallowAddToBackStack()
.commit();
}
/**
* Show error activity with the given error code and exit the current activity.
*/
public void startErrorActivity(final TrackErrorActivity.ErrorCode errorCode) {
final Intent intent = new Intent(this, TrackErrorActivity.class);
intent.putExtra(TrackErrorActivity.EXTRA_ERROR_CODE, errorCode);
mTracker.send(new HitBuilders.ExceptionBuilder().setFatal(false)
.setDescription(String.format("trackLoadError: %s", errorCode))
.build()
);
startActivity(intent);
finish();
}
@Override
public void handleFatalError(final TrackErrorActivity.ErrorCode errorCode) {
startErrorActivity(errorCode);
}
private class PendingDownloadResolver extends AbstractPendingDownloadResolver {
public PendingDownloadResolver(Context context) {
super(context);
}
@Override
protected void onErrorCode(TrackErrorActivity.ErrorCode errorCode) {
startErrorActivity(errorCode);
}
@Override
protected void onSuccess(PendingDownload download) throws Exception {
final AbstractMediaStateLoaderTask task = new MediaStateLoaderTask(getContext(),
download);
task.execute();
}
}
/**
* Takes a pending download and resolves it into a MediaState
*/
private class MediaStateLoaderTask extends AbstractMediaStateLoaderTask {
protected MediaStateLoaderTask(final Context context, final PendingDownload download) {
super(context, download);
assert download.getType() == MediaDownloadType.TRACK;
}
@Override
protected void onException(final Exception e) throws RuntimeException {
super.onException(e);
Ln.e("Error while resolving track: %s", e.toString());
final StandardExceptionParser exceptionParser = new StandardExceptionParser(
DownloadActivity.this, null);
mTracker.send(new HitBuilders.ExceptionBuilder()
.setFatal(false)
.setDescription("MediaStateLoaderTask: "
+ exceptionParser.getDescription(Thread.currentThread().getName(), e))
.build()
);
Toast.makeText(getContext(), "ERROR: " + e.toString(), Toast.LENGTH_LONG).show();
}
@Override
protected void onSuccess(final MediaState state) throws Exception {
super.onSuccess(state);
mMediaState = state;
loadMediaFragments();
}
}
}