package info.izumin.android.bletia;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import info.izumin.android.bletia.action.Action;
import info.izumin.android.bletia.wrapper.BluetoothGattWrapper;

/**
 * Created by izumin on 9/14/15.
 */
public class BleActionStore {
    private EnumMap<Action.Type, Map<UUID, Action>> mWaitingActionMap;
    private EnumMap<Action.Type, Map<UUID, Action>> mRunningActionMap;
    private EnumMap<Action.Type, List<Action>> mWaitingActionList;
    private EnumMap<Action.Type, List<Action>> mRunningActionList;

    public BleActionStore() {
        mWaitingActionMap = new EnumMap<>(Action.Type.class);
        mRunningActionMap = new EnumMap<>(Action.Type.class);
        mWaitingActionList = new EnumMap<>(Action.Type.class);
        mRunningActionList = new EnumMap<>(Action.Type.class);
    }

    public void add(Action action) {
        Action.Type type = action.getType();
        if (action.getUuid() == null) {
            if (!mWaitingActionList.containsKey(type)) {
                mWaitingActionList.put(type, new ArrayList<Action>());
            }
            mWaitingActionList.get(type).add(action);
        } else {
            if (!mWaitingActionMap.containsKey(type)) {
                mWaitingActionMap.put(type, new HashMap<UUID, Action>());
            }
            mWaitingActionMap.get(type).put(action.getUuid(), action);
        }
    }

    public void execute(Action.Type type, BluetoothGattWrapper gattWrapper) {
        Action action = mWaitingActionList.get(type).remove(0);
        if (!mRunningActionList.containsKey(type)) {
            mRunningActionList.put(type, new ArrayList<Action>());
        }
        mRunningActionList.get(type).add(action);
        action.execute(gattWrapper);
    }

    public void execute(Action.Type type, UUID uuid, BluetoothGattWrapper gattWrapper) {
        if (uuid == null) {
            execute(type, gattWrapper);
            return;
        }

        Action action = mWaitingActionMap.get(type).remove(uuid);
        if (!mRunningActionMap.containsKey(type)) {
            mRunningActionMap.put(type, new HashMap<UUID, Action>());
        }
        mRunningActionMap.get(type).put(uuid, action);
        action.execute(gattWrapper);
    }

    public Action close(Action.Type type) {
        return mRunningActionList.get(type).remove(0);
    }

    public Action close(Action.Type type, UUID uuid) {
        return (uuid == null) ? close(type) : mRunningActionMap.get(type).remove(uuid);
    }

    public boolean isRunning(Action.Type type) {
        return mRunningActionList.containsKey(type) && (mRunningActionList.get(type).size() > 0);
    }

    public boolean isRunning(Action.Type type, UUID uuid) {
        if (uuid == null) { return isRunning(type); }
        return mRunningActionMap.containsKey(type) && mRunningActionMap.get(type).containsKey(uuid);
    }
}

@@ -105,83 +105,12 @@
 til.
-HashMap;%0Aimport java.util.List;%0Aimport java.util.Map;%0Aimport java.util.UUID
+List
 ;%0A%0Ai
@@ -322,34 +322,29 @@
 ction.Type, 
-Map%3CUUID, 
+List%3C
 Action%3E%3E mWa
@@ -358,149 +358,13 @@
 tion
-Map;%0A    private EnumMap%3CAction.Type, Map%3CUUID, Action%3E%3E mRunningActionMap;%0A    private EnumMap%3CAction.Type, List%3CAction%3E%3E mWaitingActionList
+Queue
 ;%0A  
@@ -422,20 +422,21 @@
 ngAction
-List
+Queue
 ;%0A%0A    p
@@ -474,35 +474,37 @@
   mWaitingAction
-Map
+Queue
  = new EnumMap%3C%3E
@@ -550,137 +550,13 @@
 tion
-Map = new EnumMap%3C%3E(Action.Type.class);%0A        mWaitingActionList = new EnumMap%3C%3E(Action.Type.class);%0A        mRunningActionList
+Queue
  = n
@@ -611,19 +611,23 @@
 ic void 
-add
+enqueue
 (Action 
@@ -685,52 +685,8 @@
 ();%0A
-        if (action.getUuid() == null) %7B%0A    
     
@@ -700,36 +700,37 @@
 (!mWaitingAction
-List
+Queue
 .containsKey(typ
@@ -727,36 +727,32 @@
 insKey(type)) %7B%0A
-    
             mWai
@@ -753,36 +753,37 @@
   mWaitingAction
-List
+Queue
 .put(type, new A
@@ -807,34 +807,26 @@
 ));%0A        
-    %7D%0A    
+%7D%0A
         mWai
@@ -839,277 +839,36 @@
 tion
-List.get(type).add(action);%0A        %7D else %7B%0A            if (!mWaitingActionMap.containsKey(type)) %7B%0A                mWaitingActionMap.put(type, new HashMap%3CUUID, Action%3E());%0A            %7D%0A            mWaitingActionMap.get(type).put(action.getUuid(), action);%0A        %7D
+Queue.get(type).add(action);
 %0A   
@@ -979,36 +979,37 @@
 = mWaitingAction
-List
+Queue
 .get(type).remov
@@ -1033,36 +1033,37 @@
 (!mRunningAction
-List
+Queue
 .containsKey(typ
@@ -1094,20 +1094,21 @@
 ngAction
-List
+Queue
 .put(typ
@@ -1160,36 +1160,37 @@
   mRunningAction
-List
+Queue
 .get(type).add(a
@@ -1256,706 +1256,77 @@
 lic 
-void execute(Action.Type type, UUID uuid, BluetoothGattWrapper gattWrapper) %7B%0A        if (uuid == null) %7B%0A            execute(type, gattWrapper);%0A            return;%0A        %7D%0A%0A        Action action = mWaitingActionMap.get(type).remove(uuid);%0A        if (!mRunningActionMap.containsKey(type)) %7B%0A            mRunningActionMap.put(type, new HashMap%3CUUID, Action%3E());%0A        %7D%0A        mRunningActionMap.get(type).put(uuid, action);%0A        action.execute(gattWrapper);%0A    %7D%0A%0A    public Action close(Action.Type type) %7B%0A        return mRunningActionList.get(type).remove(0);%0A    %7D%0A%0A    public Action close(Action.Type type, UUID uuid) %7B%0A        return (uuid == null) ? close(type) : mRunningActionMap
+Action dequeue(Action.Type type) %7B%0A        return mRunningActionQueue
 .get
@@ -1339,20 +1339,17 @@
 .remove(
-uuid
+0
 );%0A    %7D
@@ -1428,20 +1428,21 @@
 ngAction
-List
+Queue
 .contain
@@ -1470,20 +1470,21 @@
 ngAction
-List
+Queue
 .get(typ
@@ -1508,229 +1508,7 @@
    %7D
-%0A%0A    public boolean isRunning(Action.Type type, UUID uuid) %7B%0A        if (uuid == null) %7B return isRunning(type); %7D%0A        return mRunningActionMap.containsKey(type) && mRunningActionMap.get(type).containsKey(uuid);%0A    %7D
 %0A%7D%0A

Simplify action store