package io.dwak.tracker;

import java.util.ArrayList;

/**
 * Created by vrajeevan on 12/16/14.
 */
public class Tracker {
    private boolean mActive = false;
    private TrackerComputation mCurrentComputation = null;
    private int nextId = 1;
    private ArrayList<TrackerComputation> mPendingComputations;
    private boolean mWillFlush = false;
    private boolean mInFlush = false;
    private boolean mInCompute = false;
    private boolean mThrowFirstError = false;
    private ArrayList<TrackerFlushCallbacks> mTrackerFlushCallbackses;

    public Tracker() {
    }

    public void setCurrentComputation(TrackerComputation currentComputation) {
        mCurrentComputation = currentComputation;
        mActive = currentComputation != null;
    }

    public void requireFlush(){
        if(!mWillFlush){
            // TODO
//            setTimeout(Tracker.flush, 0);
            mWillFlush = true;
        }
    }

    public class TrackerComputation {
        private final TrackerComputation sInstance;
        private final boolean mStopped;
        private final boolean mInvalidated;
        private final int mId;
        private final ArrayList<TrackerInvalidateCallbacks> mInvalidateCallbacks;
        private final TrackerComputation mParent;
        private final TrackerComputationFunction mFunction;
        private final boolean mRecomputing;
        private boolean mFirstRun;
        private boolean mErrored;
        private boolean mConstructingComputation = false;

        TrackerComputation(TrackerComputationFunction function, TrackerComputation parent) {
            sInstance = this;
            mStopped = false;
            mInvalidated = false;
            mId = nextId++;
            mInvalidateCallbacks = new ArrayList<TrackerInvalidateCallbacks>();
            mFirstRun = true;
            mParent = parent;
            mFunction = function;
            mRecomputing = false;

            try {
                function.onCompute();
                mErrored = false;
            } finally {
                mFirstRun = false;
                if (mErrored) {
                    stop();
                }

            }
        }

        private void stop() {

        }

        private void onInvalidate() {

        }

        private void invalidate() {

        }

        private void compute() {

        }

        private void reCompute() {

        }
    }

    private class TrackerInvalidateCallbacks {
    }
}

@@ -46,16 +46,42 @@
 rayList;
+%0Aimport java.util.HashMap;
 %0A%0A/**%0A *
@@ -142,31 +142,30 @@
 acker %7B%0A    
-private
+static
  boolean mAc
@@ -170,32 +170,105 @@
 Active = false;%0A
+    private static Tracker sInstance;%0A    private static int nextId = 1;%0A
     private Trac
@@ -314,36 +314,8 @@
 ll;%0A
-    private int nextId = 1;%0A
     
@@ -641,184 +641,103 @@
     
-%7D%0A%0A    public void setCurrentCompu
+    sInstance = this;%0A    %7D%0A%0A    public s
 tati
-on(
+c 
 Tracker
-Computation currentComputation) %7B%0A        mCurrentComputation = currentComputation;%0A        mActive = currentComputation != null
+ getInstance() %7B%0A        return sInstance
 ;%0A  
@@ -917,24 +917,391 @@
 %0A    public 
+TrackerComputation getCurrentComputation() %7B%0A        return mCurrentComputation;%0A    %7D%0A%0A    public void setCurrentComputation(TrackerComputation currentComputation) %7B%0A        mCurrentComputation = currentComputation;%0A        mActive = currentComputation != null;%0A    %7D%0A%0A    interface TrackerInvalidateCallbacks %7B%0A        void onInvalidate();%0A    %7D%0A%0A    public static 
 class Tracke
@@ -2655,32 +2655,118 @@
 ) %7B%0A%0A        %7D%0A%0A
+        private void onInvalidate(TrackerInvalidateCallbacks callbacks) %7B%0A%0A        %7D%0A%0A
         private 
@@ -2844,61 +2844,1456 @@
   %7D%0A
-    %7D%0A%0A    private class TrackerInvalidateCallbacks %7B
+%0A        public int getId() %7B%0A            return mId;%0A        %7D%0A    %7D%0A%0A    public static class TrackerDependency %7B%0A        private HashMap%3CInteger, TrackerComputation%3E mDependentsById;%0A        private TrackerComputation mComputation;%0A%0A        public TrackerDependency() %7B%0A            mDependentsById = new HashMap%3CInteger, TrackerComputation%3E();%0A        %7D%0A%0A        public boolean depend(TrackerComputation computation) %7B%0A            if (computation == null) %7B%0A                if (!mActive)%0A                    return false;%0A%0A                mComputation = Tracker.getInstance().getCurrentComputation();%0A            %7D%0A%0A            final int id = computation.getId();%0A            if (!mDependentsById.containsKey(id)) %7B%0A                mDependentsById.put(id, computation);%0A                computation.onInvalidate(new TrackerInvalidateCallbacks() %7B%0A                    @Override%0A                    public void onInvalidate() %7B%0A                        mDependentsById.remove(id);%0A                    %7D%0A                %7D);%0A%0A                return true;%0A            %7D%0A            return false;%0A        %7D%0A%0A        public void changed() %7B%0A            for (Integer id : mDependentsById.keySet()) %7B%0A                mDependentsById.get(id).invalidate();%0A            %7D%0A        %7D%0A%0A        public boolean hasDependants() %7B%0A            for (Integer id : mDependentsById.keySet()) %7B%0A                return true;%0A            %7D%0A            return false;%0A        %7D
 %0A   

add dependecy subclass