package org.commcare.android.framework;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.Fragment;
import android.util.Log;

import org.commcare.android.tasks.templates.CommCareTask;

/**
 * Hold a reference to the parent Activity so we can report the
 * task's current progress and results. The Android framework
 * will pass us a reference to the newly created Activity after
 * each configuration change.
 *
 * @author ctsims
 */
public class StateFragment<R> extends Fragment {
    private CommCareTask<?, ?, ?, R> currentTask;

    private WakeLock wakelock;

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

        setRetainInstance(true);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (context instanceof CommCareActivity) {
            if (isCurrentTaskRunning()) {
                this.currentTask.connect((CommCareActivity)context);
            }
        }
    }

    private boolean isCurrentTaskRunning() {
        return this.currentTask != null &&
                this.currentTask.getStatus() == AsyncTask.Status.RUNNING;
    }

    @Override
    public void onDetach() {
        super.onDetach();

        if (currentTask != null) {
            Log.i("CommCareUI", "Detaching activity from current task: " + this.currentTask);
            currentTask.disconnect();
            releaseWakeLock();
        }
    }

    public void cancelTask() {
        if (currentTask != null) {
            currentTask.cancel(false);
        }
    }

    private synchronized void acquireWakeLock(CommCareActivity activity) {
        int lockLevel = activity.getWakeLockLevel();
        if (lockLevel != CommCareTask.DONT_WAKELOCK) {
            releaseWakeLock();

            PowerManager pm = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
            wakelock = pm.newWakeLock(lockLevel, "CommCareLock");
            wakelock.acquire();
        }
    }

    public synchronized void releaseWakeLock() {
        if (wakelock != null && wakelock.isHeld()) {
            wakelock.release();
        }
        wakelock = null;
    }

    public void connectTask(CommCareTask<?, ?, ?, R> task, CommCareActivity activity) {
        acquireWakeLock(activity);
        this.currentTask = task;
    }
}

@@ -1096,58 +1096,317 @@
     
-this.currentTask.connect((CommCareActivity)context
+CommCareActivity activity = (CommCareActivity)context;%0D%0A                // connecting to a task requires the activity's state holder to%0D%0A                // be set; which we're in the middle of, so take a shortcut%0D%0A                activity.stateHolder = this;%0D%0A                this.currentTask.connect(activity
 );%0D%0A

set stateholder when trying to connect to task