package org.dodgybits.shuffle.android.synchronisation.tracks;
import static org.dodgybits.shuffle.android.core.util.Constants.cFlurryTracksSyncCompletedEvent;
import static org.dodgybits.shuffle.android.core.util.Constants.cFlurryTracksSyncError;
import static org.dodgybits.shuffle.android.core.util.Constants.cFlurryTracksSyncStartedEvent;
import java.util.LinkedList;
import org.dodgybits.android.shuffle.R;
import org.dodgybits.shuffle.android.core.activity.flurry.Analytics;
import org.dodgybits.shuffle.android.core.model.Project;
import org.dodgybits.shuffle.android.core.model.Task;
import org.dodgybits.shuffle.android.core.model.persistence.ContextPersister;
import org.dodgybits.shuffle.android.core.model.persistence.EntityPersister;
import org.dodgybits.shuffle.android.core.model.persistence.ProjectPersister;
import org.dodgybits.shuffle.android.core.model.persistence.TaskPersister;
import org.dodgybits.shuffle.android.preference.model.Preferences;
import org.dodgybits.shuffle.android.preference.view.Progress;
import roboguice.inject.ContentResolverProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
/**
* This task synchronizes shuffle with a tracks service.
*
* @author Morten Nielsen
*/
public class TracksSynchronizer extends AsyncTask<String, Progress, Void> {
private static final String cTag = "TracksSynchronizer";
private static TracksSynchronizer synchronizer;
private static LinkedList<SyncProgressListener> progressListeners = new LinkedList<SyncProgressListener>();
private final Context mContext;
private final LinkedList<Integer> mMessages;
private final ContextSynchronizer mContextSynchronizer;
private final ProjectSynchronizer mProjectSynchronizer;
private final TaskSynchronizer mTaskSynchronizer;
private Analytics mAnalytics;
// TODO inject sync classes (BIG job)
public static TracksSynchronizer getActiveSynchronizer(
ContextWrapper context, Analytics analytics) throws ApiException {
TracksSynchronizer synchronizer = getSingletonSynchronizer(context, analytics);
while (synchronizer.getStatus() == Status.FINISHED) {
synchronizer = getSingletonSynchronizer(context, analytics);
}
return synchronizer;
}
private static TracksSynchronizer getSingletonSynchronizer(Context context, Analytics analytics) throws ApiException {
if (synchronizer == null || synchronizer.getStatus() == Status.FINISHED) {
synchronizer = new TracksSynchronizer(
context, analytics,
new WebClient(context, Preferences.getTracksUser(context),
Preferences.getTracksPassword(context)),
Preferences.getTracksUrl(context)
);
}
return synchronizer;
}
private TracksSynchronizer(
Context context,
Analytics analytics,
WebClient client,
String tracksUrl) {
mContext = context;
//TODO inject this
ContentResolverProvider provider = new ContentResolverProvider() {
@Override
public ContentResolver get() {
return mContext.getContentResolver();
}
};
mAnalytics = analytics;
EntityPersister<Task> taskPersister = new TaskPersister(provider, analytics);
EntityPersister<org.dodgybits.shuffle.android.core.model.Context> contextPersister = new ContextPersister(provider, analytics);
EntityPersister<Project> projectPersister = new ProjectPersister(provider, analytics);
mContextSynchronizer = new ContextSynchronizer(contextPersister, this, client, context, mAnalytics, 0, tracksUrl);
mProjectSynchronizer = new ProjectSynchronizer(projectPersister, this, client, context, mAnalytics, 33, tracksUrl);
mTaskSynchronizer = new TaskSynchronizer(taskPersister, this, client, context, mAnalytics, 66, tracksUrl);
mMessages = new LinkedList<Integer>();
}
@Override
protected void onProgressUpdate(Progress... progresses) {
for (SyncProgressListener listener : progressListeners) {
listener.progressUpdate(progresses[0]);
}
}
public void registerListener(SyncProgressListener listener) {
if (!progressListeners.contains(listener))
progressListeners.add(listener);
}
public void unRegisterListener(SyncProgressListener
listener) {
progressListeners.remove(listener);
}
@Override
protected Void doInBackground(String... strings) {
try {
mAnalytics.onEvent(cFlurryTracksSyncStartedEvent);
mContextSynchronizer.synchronize();
mProjectSynchronizer.synchronize();
mTaskSynchronizer.synchronize();
publishProgress(Progress.createProgress(100, "Synchronization Complete"));
mAnalytics.onEvent(cFlurryTracksSyncCompletedEvent);
} catch (ApiException e) {
Log.w(cTag, "Tracks call failed", e);
publishProgress(Progress.createErrorProgress(mContext.getString(R.string.web_error_message)));
mAnalytics.onError(cFlurryTracksSyncError, e.getMessage(), getClass().getName());
} catch (Exception e) {
Log.w(cTag, "Synch failed", e);
publishProgress(Progress.createErrorProgress(mContext.getString(R.string.error_message)));
mAnalytics.onError(cFlurryTracksSyncError, e.getMessage(), getClass().getName());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
if (mMessages.size() > 0) {
for (Integer textId : mMessages) {
Toast toast = Toast.makeText(mContext.getApplicationContext(), textId
, Toast.LENGTH_SHORT);
toast.show();
}
}
try {
synchronizer = getSingletonSynchronizer(mContext, mAnalytics);
} catch (ApiException ignored) {
}
}
public void reportProgress(Progress progress) {
publishProgress(progress);
}
public void postSyncMessage(int toastMessage) {
mMessages.add(toastMessage);
}
}