package com.hdasync;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.lang.ref.WeakReference;


/**
 * Created by scott on 15/3/26.
 */
public class HdAsync {

    public static final String TAG = "HdAsync";

    private HdAsyncArgs args;
    private HdAsyncActionGroup actionGroup;

    private boolean isCanceled = false;
    private boolean isDone = false;

    public static HdAsync with(Object host) {
        return new HdAsync(host);
    }

    private HdAsync(Object host) {
        actionGroup = new HdAsyncActionGroup();
        args = new HdAsyncArgs();
        args.setHdAsync(this);
        args.setHost(host);
    }


    public HdAsync call() {
        isCanceled = false;
        executeAction(args, true);
        return this;
    }

    public HdAsync call(HdAsyncArgs args) {
        isCanceled = false;
        this.args = args;
        executeAction(args, true);
        return this;
    }

    public HdAsync resume() {
        call();
        return this;
    }

    public HdAsync resume(HdAsyncArgs args) {
        call(args);
        return this;
    }

    public void cancel() {
        isCanceled = true;
        isDone = true;
    }

    public boolean isDone() {
        return isDone;
    }

    public void destroy() {
        cancel();
        if (actionGroup != null) {
            actionGroup.clear();
        }
        actionGroup = null;
        args = null;
    }

    public HdAsync then(final HdAsyncAction action) {
        actionGroup.then(action);
        return this;
    }

    public HdAsync delay(final HdAsyncAction action, long delay) {
        actionGroup.delay(action, delay);
        return this;
    }

    public HdAsync both(HdAsyncAction... actions) {
        actionGroup.both(actions);
        return this;
    }

    public HdAsync append(HdAsync other) {
        if (other != null) {
            actionGroup.append(other.actionGroup);
        }
        return this;
    }


    static class Data {
        HdAsyncAction action;
        HdAsyncArgs args;
    }

    private void executeAction(HdAsyncArgs args, boolean needNext) {
        if (actionGroup != null && !actionGroup.allActionFinish()) {

            if (!needNext) {
                return;
            }

            HdAsyncAction[] actions = actionGroup.poll();

            for (HdAsyncAction action : actions) {
                if (action.looper == null) {
                    Log.d(TAG, "action.looper  = null");
                }

                Handler handler = new Handler(action.looper, new HandlerCallback());
                Message msg = Message.obtain();
                Data data = new Data();
                data.action = action;
                data.args = args;
                msg.obj = data;
                if (action.delay == 0) {
                    handler.sendMessage(msg);
                } else {
                    handler.sendMessageDelayed(msg, action.delay);
                }

            }

        } else {
            isDone = true;
            Log.d(TAG, "isDone");
        }
    }


    class HandlerCallback implements Handler.Callback {

        @Override
        public boolean handleMessage(Message message) {
            if (!(message.obj instanceof Data)) {
                return false;
            }

            Data data = (Data) message.obj;


            HdAsyncAction action = data.action;
            HdAsyncArgs args = data.args;


            if (isCanceled) {
                return false;
            }

            HdAsyncResult result = action.call(args);

            actionGroup.finishOneAction();

            if (result != null) {
                executeAction(result.args, result.needNext);
            }

            return false;
        }

    }

}

@@ -1175,37 +1175,14 @@
 ue;%0A
-        isDone = true;%0A
     %7D%0A
+
 %0A   
@@ -1270,26 +1270,8 @@
 ) %7B%0A
-        cancel();%0A
     
@@ -2173,32 +2173,46 @@
    if (!needNext
+ %7C%7C isCanceled
 ) %7B%0A            
@@ -2340,32 +2340,33 @@
 on : actions) %7B%0A
+%0A
                 
@@ -2418,43 +2418,16 @@
     
-Log.d(TAG, %22action.looper  = null%22)
+continue
 ;%0A  
@@ -2909,33 +2909,32 @@
               %7D%0A
-%0A
             %7D%0A%0A 
@@ -2972,24 +2972,47 @@
 one = true;%0A
+            destroy();%0A
             
@@ -3322,17 +3322,16 @@
 e.obj;%0A%0A
-%0A
         
@@ -3362,32 +3362,32 @@
  = data.action;%0A
+
             HdAs
@@ -3417,84 +3417,8 @@
 s;%0A%0A
-%0A            if (isCanceled) %7B%0A                return false;%0A            %7D%0A%0A
     

modify hdasync